转:https://www.jianshu.com/p/59771cbf373d
1.问题情景
项目中前端后台的数据传递是必不可少的,比如说我们要在一张表单中提交对象,如果只是一个对象就就很好做,因为单独的对象中是很难存在相同的参数名的,但是如果我们想要提交多个对象,这些对象的参数名如果在项目的设计阶段可能会因为负责人沟通问题导致相同。
举个栗子:
再说主题之前我们先看看Struts2是如何解决这个问题的:
众所周知,Struts2采用了OGNL表达式,可以使用Object.Prarm形式对表单进行精准绑定入参,比如传student.id,后台就可以区分并接收到是student的id。Struts2我很不熟(因为没啥用),只知道这么一丢丢。
回到主题,我们主要是想看看在SpringMVC中我们怎么解决这个问题。
根据上面的情景,我们来搭建个问题,然后解决这个问题
先写Student和Course两个类,Student和Course里面都有id和note,参数名一样,但是意义很不同!!!
后台:
public class Student implements Serializable{ String id; String note; //get..set.... } public class Course implements Serializable{ String id; String note; //set..get... }
前端:
<form action="/test/test" method="get"> <input type="text" name="student.id" value="student_id"> <input type="text" name="student.name" value="student_name"> <input type="text" name="course.id" value="course_id"> <input type="text" name="course.name" value="course_name"> <input type="submit" value="提交"> </form>
2.解决问题
有请今天的主角——@InitBinder
有了它,我们就可以像Struts2一样,前端传Object.Prarm的形式了。当然在后台我们需要做些风骚操作!
@InitBinder("student") public void initBinderStudent(WebDataBinder binder){ binder.setFieldDefaultPrefix("student."); } @InitBinder("course") public void initBinderCourse(WebDataBinder binder){ binder.setFieldDefaultPrefix("course."); }
@InitBinder() 中间的value值,用于指定表单属性或请求参数的名字,符合该名字的将使用此处的DataBinder。比如:student.id和student.note。student就得是中间的value值,这样才能接收得到。而且student会填充进WebDataBinder,这里binder对象就是student了。
注意binder.setFieldDefaultPrefix("student."),这里的"."千万别忘记了!!!
大家一定觉得这个操作太风骚了。先别着急用,这里说一下这个方法的缺陷:
首先,这个方法不能自定义路径,比如我想写:”/TianShenSchool/4thClass/{student.id}“ ,这就无法完成!
其次,如果给的是集合或者是数组,也无法使用。
当然如果真的出现上面两种情况的话,建议大家还是乖乖改一改数据结构和系统设计吧ㄟ( ▔, ▔ )ㄏ
3.代码
Student对象和Course对象:
public class Student implements Serializable{ String id; String note; //get..set.... } public class Course implements Serializable{ String id; String note; //set..get... }
html页面:
<form action="/test/test" method="get"> <input type="text" name="student.id" value="student_id"> <input type="text" name="student.name" value="student_name"> <input type="text" name="course.id" value="course_id"> <input type="text" name="course.name" value="course_name"> <input type="submit" value="提交"> </form>
Controller:
@Controller @RequestMapping("/classtest") public class TestController { // 绑定变量名字和属性,参数封装进类 @InitBinder("student") public void initBinderUser(WebDataBinder binder) { binder.setFieldDefaultPrefix("student."); } // 绑定变量名字和属性,参数封装进类 @InitBinder("course") public void initBinderAddr(WebDataBinder binder) { binder.setFieldDefaultPrefix("course."); } @RequestMapping("/methodtest") @ResponseBody public Map<String,Object> test(@ModelAttribute("student") Student student,@ModelAttribute("course") Course course){ Map<String,Object> map=new HashMap<String,Object>(); map.put("student", student); map.put("course", course); return map; }