`
jinnianshilongnian
  • 浏览: 21435073 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2405130
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2997788
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631528
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257583
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593212
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248982
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847622
Group-logo
跟我学Nginx+Lua开...
浏览量:698184
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780495
社区版块
存档分类
最新评论

springmvc绑定Set的解决方案

阅读更多

1、模型

public class Vote {
    private Integer id;
    private String title;
    private Set<VoteItem> voteItems;
    private VoteSubject voteSubject;
}

public class VoteItem {
    private Integer id;
    private String content;
    private Vote vote;
}

 

2、控制器

 

    @RequestMapping
    public String vote(@FormModel("votes") Set<Vote> 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<Vote> initVotes() {
        Set<Vote> votes = new HashSet<Vote>();
        Vote vote = new Vote();
        votes.add(vote);

        vote.setVoteItems(new HashSet<VoteItem>());
        vote.getVoteItems().add(new VoteItem());

        return votes;
    }

这样我们就可以把votes暴露给之前的@FormModel("votes") ,它会使用这个来绑定,所以就有数据了。@ModelAttribute方法请参考《暴露表单引用对象为模型数据》。

 

但是缺点也很明显,前台必须告诉后台,Set里有几个数据,好让@ModelAttribute方法准备好那么多数据用于数据绑定,比较麻烦。

 

更简单的解决方案就是使用有序集合,如List,这样最简单

 

如上方案通用适用于@ModelAttribute的绑定。

 

最新的@FormModel的实现请到FormModelMethodArgumentResolver.java下载。

 

 

相关文章:

扩展SpringMVC以支持更精准的数据绑定1

SpringMVC内置的精准数据绑定2 

1
2
分享到:
评论
3 楼 15882967370 2016-09-01  
  学习啦 大神
2 楼 jinnianshilongnian 2013-06-21  
asialee 写道
lz分析问题的精神值得佩服!

,对于自己熟悉的领域,就想把问题整明白,整不明白心里走放不下。估计这就是兴趣吧,哈哈。
1 楼 asialee 2013-06-21  
lz分析问题的精神值得佩服!

相关推荐

Global site tag (gtag.js) - Google Analytics