在SpringMVC中,是通过<form>中定义commandName去绑定bean,还有modelAttribute,但具体两者有没有区别还没有深究。但最近为了实现一项需求,明白了多一样这一过程的细节。
需求:页面里需要输入多辆汽车的信息,然后提交。
开始尝试,很自然的,在commandName中给一个汽车的List,对于输出汽车的信息,给一个List,没问题,用<forEach>就可以简单的输出了,但是返回到Controller的数据就有问题了。<input>的name属性该填什么呢?一般对应的是BeanName.setXXX,对应的XXX。但是对于List,好像给不出这个XXX,试了很久没试出来。(如果有人知道的话,希望指点一下)。
后来想到,一般绑定的是一个对象,那么用一个对象把List包起来吧。那么name就写ListName[i].XXX,XXX是对应的POJO的属性名。问题似乎解决了一点,不过跑的时候报错——越界。为什么?尝试了一翻后终于明白,commandName绑定的数据,跟原来Model的那个对象没有实际上的关系。后面的过程是,调用commandName对应的类的无参构造函数,形成一个模板,然后根据name的属性往这个模板上填数据。因为List默认构造就是一个空的List,所以它当模板放数据时当然会越界啦。后来就在对象里加了一个长度的属性,最开始先对这个属性放数据,而在这个属性设置的时候随便把List按这个长度初始化好,有了这个长度适合的模板放数据,就不会出现越界了。不过这里用了在set长度时的一个特殊处理,感觉好像不是太自然。
再后来,请教过其他人,说可以用Json处理这个数据传递的过程,可能会更直接。不过还没时间学习这个Json,所以这方法暂时无法介绍给大家。
与此相关的还想到一个问题,之前用struct1时,update一个数据,从利用Hibernate取出数据,然后用form传给页面,然后返回到action中处理更新,调用update的时候会报session中存在两个不同对象有同样的ID,也许问题跟数据绑定有关,因为刚才说过,绑定数据的时候是调用无参构造函数,所以就等于是重新new了一个对象,所以这时update这个new的对象是会报错的。当然调用merge是一个解决的方法。
关于Hibernate的修改,可以简单看看这个http://www.iteye.com/topic/355597
原来只要用@SessionAttribute就可以解决了!
使用SessionAttribute,form提交的时候直接就同步session里的对象了。