SpringmvcバインドSetのソリューション
3047 ワード
詳細
1、モデル
2、コントローラ
@FormModel注記「SpringMVCを拡張してより正確なデータバインド1をサポートする」を参照してください.
アドレスバーに次のように入力します.http://localhost:9080/es-web/vote?votes[0].voteItems[0].content=123の場合、次のように報告されます.
org.springframework.beans.InvalidPropertyException: Invalid property 'voteItems[0]' of bean class [com.sishuok.es.test.Vote]: Cannot get element with index 0 from Set of size 0, accessed using property path 'voteItems[0]'
3、原因:
理由は明らかであり,Setは無秩序リストであるため,順序付き注入を用いることは適切ではない,BeanWrapperImpl実装:
実装から,setに値があればバインドが実現できることがわかる.
4、解決方案:
springmvcがデータをバインドする前に、Setにデータを追加することを保証すればよい.
これにより、votesを以前の@FormModel(「votes」)に暴露することができ、これを使用してバインドされるので、データがあります.@ModelAttributeメソッドは、「フォーム参照オブジェクトをモデルデータとして露出」を参照してください.
しかし欠点も明らかで、フロントはバックグラウンドに教えなければならなくて、Setの中にいくつかのデータがあって、@ModelAttribute方法にそんなに多くのデータを用意してデータのバインドに使うようにして、比較的に面倒です.
より簡単な解決策は,リストのような秩序化された集合を用いることであり,これが最も簡単である.
上記のシナリオは、@ModelAttributeのバインドに一般的に適用されます.
最新の@FormModelの実装はFormModelMethodArgumentResolver.JAvaダウンロード.
関連記事:
SpringMVCを拡張し、より正確なデータバインド1をサポート
SpringMVC内蔵の精確なデータバインディング2
1、モデル
public class Vote {
private Integer id;
private String title;
private Set voteItems;
private VoteSubject voteSubject;
}
public class VoteItem {
private Integer id;
private String content;
private Vote vote;
}
2、コントローラ
@RequestMapping
public String vote(@FormModel("votes") Set votes) {
System.out.println(votes);
return "";
}
@FormModel注記「SpringMVCを拡張してより正確なデータバインド1をサポートする」を参照してください.
アドレスバーに次のように入力します.http://localhost:9080/es-web/vote?votes[0].voteItems[0].content=123の場合、次のように報告されます.
org.springframework.beans.InvalidPropertyException: Invalid property 'voteItems[0]' of bean class [com.sishuok.es.test.Vote]: Cannot get element with index 0 from Set of size 0, accessed using property path 'voteItems[0]'
3、原因:
理由は明らかであり,Setは無秩序リストであるため,順序付き注入を用いることは適切ではない,BeanWrapperImpl実装:
else if (value instanceof Set) {
// Apply index to Iterator in case of a Set.
Set set = (Set) value;
int index = Integer.parseInt(key);
if (index < 0 || index >= set.size()) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Cannot get element with index " + index + " from Set of size " +
set.size() + ", accessed using property path '" + propertyName + "'");
}
Iterator it = set.iterator();
for (int j = 0; it.hasNext(); j++) {
Object elem = it.next();
if (j == index) {
value = elem;
break;
}
}
}
実装から,setに値があればバインドが実現できることがわかる.
4、解決方案:
springmvcがデータをバインドする前に、Setにデータを追加することを保証すればよい.
@ModelAttribute("votes")
public Set initVotes() {
Set votes = new HashSet();
Vote vote = new Vote();
votes.add(vote);
vote.setVoteItems(new HashSet());
vote.getVoteItems().add(new VoteItem());
return votes;
}
これにより、votesを以前の@FormModel(「votes」)に暴露することができ、これを使用してバインドされるので、データがあります.@ModelAttributeメソッドは、「フォーム参照オブジェクトをモデルデータとして露出」を参照してください.
しかし欠点も明らかで、フロントはバックグラウンドに教えなければならなくて、Setの中にいくつかのデータがあって、@ModelAttribute方法にそんなに多くのデータを用意してデータのバインドに使うようにして、比較的に面倒です.
より簡単な解決策は,リストのような秩序化された集合を用いることであり,これが最も簡単である.
上記のシナリオは、@ModelAttributeのバインドに一般的に適用されます.
最新の@FormModelの実装はFormModelMethodArgumentResolver.JAvaダウンロード.
関連記事:
SpringMVCを拡張し、より正確なデータバインド1をサポート
SpringMVC内蔵の精確なデータバインディング2