该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-12-17
话说我都没配那个modelAttribute,form里就写了个POST 在Controller里就直接调用了.一直也奇怪这个问题,binder是怎么做的,难道他会根据form的属性自动匹配POJO吗
PS :modelAttribute 是怎么反射到POJO的 |
|
返回顶楼 | |
发表时间:2010-12-17
homg127 写道 话说我都没配那个modelAttribute,form里就写了个POST 在Controller里就直接调用了.一直也奇怪这个问题,binder是怎么做的,难道他会根据form的属性自动匹配POJO吗
PS :modelAttribute 是怎么反射到POJO的 咱俩的问题估计是一样的,我也不知道怎么可能通过modelAttribute里的CustomerCommand名找到com.command.CustomerCommand并实例化,所以不知道modelAttribute怎么bind到POJO。 |
|
返回顶楼 | |
发表时间:2010-12-17
unsid 写道 itstarting 写道 unsid 写道 这是我页面里东西,我觉得和/xrequirement/addcustomer.do提交到的controller没关系,因为这个页面刚一打开初始化就报错java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'customerComand' available as request attribute,那时候还没有提交呢。是不是要求command要和controller在同一个包下? 你把相关代码贴出来,这个问题不应该是个棘手问题,肯定是哪里犯了低级错误。 代码包括: 1. CustomerComand.java 2. 在controller的addcustomer方法 3. 加上这个jsp的form,就OK了 好的 CustomerComand.java public class CustomerCommand { private String firstname ; private String lastname ; public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } } 在controller的addcustomer方法 @Controller public class CustomerController { private CustomerRepository customerRepository; @RequestMapping(value="/addcustomer",method = RequestMethod.GET) public String addCustomer(CustomerCommand customerCommand) throws Exception { //do something } public void setCustomerRepository(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } } 加上这个jsp的form <form:form method="post" modelAttribute="customerCommand" action="/addcustomer.do"> FIRSTNAME: <form:input path="firstname"/><br> LASTNAME: <form:input path="lastname"/><br> <input type="submit" value="regist"/> </form:form> 非常感谢楼主细心解答! 老兄,你form里是post 但你mapping的地方是get(@RequestMapping(value="/addcustomer",method = RequestMethod.GET)) 其他我觉得不会有问题,你调整过来看看,直接去掉method的限制好了。 |
|
返回顶楼 | |
发表时间:2010-12-17
unsid 写道 homg127 写道 话说我都没配那个modelAttribute,form里就写了个POST 在Controller里就直接调用了.一直也奇怪这个问题,binder是怎么做的,难道他会根据form的属性自动匹配POJO吗
PS :modelAttribute 是怎么反射到POJO的 咱俩的问题估计是一样的,我也不知道怎么可能通过modelAttribute里的CustomerCommand名找到com.command.CustomerCommand并实例化,所以不知道modelAttribute怎么bind到POJO。 这里涉及Spring大量的conventions,我没细看这部分,我印象中大概的思路会是: 1.找到mapping的方法,然后逐个匹配方法的param 2.如果找到非“内置”的param(有一个列表,十几个这样),就试图去实例化并填充数据 此时,如果看到一个com.command.CustomerCommand,那就先实例化一个,然后从request取东西出来populate,取啥呢,取名字为“customerCommand”的modelAttribute,这就是convention。 binding部分大概也就是BeanUtils那样的思路,有深度研究的兄弟可以来给大家分享一下 |
|
返回顶楼 | |
发表时间:2010-12-17
itstarting 写道 unsid 写道 homg127 写道 话说我都没配那个modelAttribute,form里就写了个POST 在Controller里就直接调用了.一直也奇怪这个问题,binder是怎么做的,难道他会根据form的属性自动匹配POJO吗
PS :modelAttribute 是怎么反射到POJO的 咱俩的问题估计是一样的,我也不知道怎么可能通过modelAttribute里的CustomerCommand名找到com.command.CustomerCommand并实例化,所以不知道modelAttribute怎么bind到POJO。 这里涉及Spring大量的conventions,我没细看这部分,我印象中大概的思路会是: 1.找到mapping的方法,然后逐个匹配方法的param 2.如果找到非“内置”的param(有一个列表,十几个这样),就试图去实例化并填充数据 此时,如果看到一个com.command.CustomerCommand,那就先实例化一个,然后从request取东西出来populate,取啥呢,取名字为“customerCommand”的modelAttribute,这就是convention。 binding部分大概也就是BeanUtils那样的思路,有深度研究的兄弟可以来给大家分享一下 呵呵 谢谢你的解答 大概有些理解了 照你的说法 modelAttribute 只是一种写法习惯 用来在VIEW中分辨哪个实体 即使不写也没有关系 是这个意思吗? |
|
返回顶楼 | |
发表时间:2010-12-17
homg127 写道 呵呵 谢谢你的解答 大概有些理解了 照你的说法 modelAttribute 只是一种写法习惯 用来在VIEW中分辨哪个实体 即使不写也没有关系 是这个意思吗? no modelAttribute是form tag的属性,其实说白了就是用来构造类似于EL的path. 比如,modelAttribute="hotel",而<form:input path="name" .../>,这binding的时候就是 hotel.name 而如果需要多个bean在一个form里,就要modelAttribute="someWrapperBean",而 <form:input就要写: <form:input path="beanA.name".../> <form:input path="beanB.title".../> 此时: someWrapperBean.beanA.name,someWrapperBean.beanB.title,。。。 如此而已 |
|
返回顶楼 | |
发表时间:2010-12-17
itstarting 写道 unsid 写道 itstarting 写道 unsid 写道 这是我页面里东西,我觉得和/xrequirement/addcustomer.do提交到的controller没关系,因为这个页面刚一打开初始化就报错java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'customerComand' available as request attribute,那时候还没有提交呢。是不是要求command要和controller在同一个包下? 你把相关代码贴出来,这个问题不应该是个棘手问题,肯定是哪里犯了低级错误。 代码包括: 1. CustomerComand.java 2. 在controller的addcustomer方法 3. 加上这个jsp的form,就OK了 好的 CustomerComand.java public class CustomerCommand { private String firstname ; private String lastname ; public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } } 在controller的addcustomer方法 @Controller public class CustomerController { private CustomerRepository customerRepository; @RequestMapping(value="/addcustomer",method = RequestMethod.GET) public String addCustomer(CustomerCommand customerCommand) throws Exception { //do something } public void setCustomerRepository(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } } 加上这个jsp的form <form:form method="post" modelAttribute="customerCommand" action="/addcustomer.do"> FIRSTNAME: <form:input path="firstname"/><br> LASTNAME: <form:input path="lastname"/><br> <input type="submit" value="regist"/> </form:form> 非常感谢楼主细心解答! 老兄,你form里是post 但你mapping的地方是get(@RequestMapping(value="/addcustomer",method = RequestMethod.GET)) 其他我觉得不会有问题,你调整过来看看,直接去掉method的限制好了。 我改成一样的了,还是不行,报customerCommand没有绑定。 |
|
返回顶楼 | |
发表时间:2010-12-17
unsid 写道 我改成一样的了,还是不行,报customerCommand没有绑定。 服了: action="/addcustomer.do" but @RequestMapping(value="/addcustomer",method = RequestMethod.GET) 9成9是低级错误所致 |
|
返回顶楼 | |
发表时间:2010-12-20
itstarting 写道 unsid 写道 我改成一样的了,还是不行,报customerCommand没有绑定。 服了: action="/addcustomer.do" but @RequestMapping(value="/addcustomer",method = RequestMethod.GET) 9成9是低级错误所致 现在有了一点进展,事情是这样的,我一上来访问的helloController,并返回输入customer信息的页面hello.jsp。 @RequestMapping(value="/hello",method = RequestMethod.GET) public String hello(Model model) { model.addAttribute("hello","helloworld!"); return "hello"; } hello.jsp <form:form method="get" modelAttribute="customerCommand" action="/xrequirement/addcustomer"> ${hello}<br> FIRSTNAME: <form:input path="firstname"/><br> LASTNAME: <form:input path="lastname"/><br> <input type="submit" value="regist"/> </form:form> customerController @RequestMapping(value="/addcustomer",method = RequestMethod.GET) public String addCustomer(@ModelAttribute("customerCommand") CustomerCommand customerCommand) throws Exception { ....... } 此时会报customerCommand找不到绑定的异常,但是如果我把helloController改成这样 @RequestMapping(value="/hello",method = RequestMethod.GET) public String hello(@ModelAttribute("customerCommand") CustomerCommand customerCommand,Model model) { model.addAttribute("hello","helloworld!"); return "hello"; } 参数里增加了@ModelAttribute("customerCommand") CustomerCommand customerCommand 就正常显示了,我很纳闷我hello这个方法根本用不到CustomerCommand customerCommand难道必须要在这声明? |
|
返回顶楼 | |
发表时间:2010-12-20
unsid 写道 参数里增加了@ModelAttribute("customerCommand") CustomerCommand customerCommand 就正常显示了,我很纳闷我hello这个方法根本用不到CustomerCommand customerCommand难道必须要在这声明? 其实你的hello方法的执行终点是渲染hello.jsp,此时hello.jsp会试图在request获取modelAttribute,但如果你按原来的写法,显然没有名字为customerCommand的modelAttribute,所以会有绑定异常,而你加上就可以了。 另外,你也可以直接new一个然后put到request里去,也是OK的,此时方法上可以不要这个参数(@ModelAttribute("customerCommand") CustomerCommand customerCommand)了: model.addAttribute("customerCommand",new CustomerCommand ()); BTW:也许显式的写@ModelAttribute也是一种好习惯,但我一般懒得写,放在方法上即可,此时Spring能处理好,即使你没put到request去: @RequestMapping(value="/hello",method = RequestMethod.GET) public String hello(CustomerCommand customerCommand,Model model) { model.addAttribute("hello","helloworld!"); return "hello"; } |
|
返回顶楼 | |