SpringmvcバインドSetのソリューション


詳細
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