SpringMVC用InitBinder注解实现表单多对象精准绑定接收。
要在一张表单中提交多个对象,并且还要在后台Controller中精准的绑定接收,可是,这些对象中可能有相同的参数名,如何做到精准绑定?后台接收入参时无法像Struts那样JSP表单中使用Object.Param形式对表单进行精准绑定入参,我们都知道Struts2默认就是这种方案,这是因为struts2采用了OGNL,并通过栈(根对象)进行操作的,而且栈中默认有Action实例,所以很自然的没有这种问题。另一方面说,Struts用这种方式绑定入参,却牺牲了性能。虽然SpringMVC不能像Struts那样方便的很直接的入参绑定,当然,Spring对多对象绑定入参也提供了方法。
下面直接上完整的代码示例。
运行工程,打开浏览器在地址栏内输入 http://localhost:8080/testbinder/test?user.name=Tom&addr.name=NewyokStreet112 回车,查看输出结果正常,说明参数精准绑定啦。
新User类代码:
其他代码不需要修改,运行工程,在浏览器地址栏上输入:
http://localhost:8080/testbinder/test?user.name=Tom&user.car.color=Blue&addr.name=NewyokStreet112
或
http://localhost:8080/testbinder/test?user.name=Tom&car.color=Blue&addr.name=NewyokStreet112
再加个控制器test2,与test不同的是只把参数类型Addr换为Addr2,其他不变。
同样打开浏览器测试,在地址栏输入参数和数据,回车,后端看到正确接收到来自前端的数据,说明对 addr 的绑定是公用的。
要在一张表单中提交多个对象,并且还要在后台Controller中精准的绑定接收,可是,这些对象中可能有相同的参数名,如何做到精准绑定?后台接收入参时无法像Struts那样JSP表单中使用Object.Param形式对表单进行精准绑定入参,我们都知道Struts2默认就是这种方案,这是因为struts2采用了OGNL,并通过栈(根对象)进行操作的,而且栈中默认有Action实例,所以很自然的没有这种问题。另一方面说,Struts用这种方式绑定入参,却牺牲了性能。虽然SpringMVC不能像Struts那样方便的很直接的入参绑定,当然,Spring对多对象绑定入参也提供了方法。
下面直接上完整的代码示例。
两个类:
public class User{
String id;
String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Addr{
String id;
String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
前端代码:
<form action="/test/test" method="post">
<input type="text" name="user.id" value="huo_user_id">
<input type="text" name="user.name" value="huo_user_name">
<input type="text" name="addr.id" value="huo_addr_id">
<input type="text" name="addr.name" value="huo_addr_name">
<input type="submit" value="提交">
</form>
控制器代码:
@Controller
@RequestMapping("testbinder")
public class TestController {
@InitBinder("user")
public void initBinderUser(WebDataBinder binder) {
binder.setFieldDefaultPrefix("user.");
}
@InitBinder("addr")
public void initBinderAddr(WebDataBinder binder) {
binder.setFieldDefaultPrefix("addr.");
}
@RequestMapping(value = "test", method = RequestMethod.GET)
@ResponseBody
public Map<String,Object> test(HttpServletRequest request,@ModelAttribute("user") User user, @ModelAttribute("addr") Addr addr){
Map<String,Object> map=new HashMap<String,Object>();
map.put("user", user);
map.put("addr", addr);
return map;
}
}
运行工程,打开浏览器在地址栏内输入 http://localhost:8080/testbinder/test?user.name=Tom&addr.name=NewyokStreet112 回车,查看输出结果正常,说明参数精准绑定啦。
对于嵌套类的情况,也同样有效。比如再创建一个Car类,在User类加上一个Car类的属性,如下。
Car类代码:
public class Car {
String color;
Integer weight;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
}
新User类代码:
public class User{
String id;
String name;
Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
其他代码不需要修改,运行工程,在浏览器地址栏上输入:
http://localhost:8080/testbinder/test?user.name=Tom&user.car.color=Blue&addr.name=NewyokStreet112
或
http://localhost:8080/testbinder/test?user.name=Tom&car.color=Blue&addr.name=NewyokStreet112
回车,查看输出结果正常,说明嵌套类参数精准绑定。
一次绑定后,可以在多个控制器中使用,下面举例说明。
再创建个Addr2类,与Addr类相同,也有id和name属性,还多一个remark属性。
public class Addr2{
String id;
String name;
String remark;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
再加个控制器test2,与test不同的是只把参数类型Addr换为Addr2,其他不变。
@RequestMapping(value = "test2", method = RequestMethod.GET)
@ResponseBody
public Map<String,Object> test(HttpServletRequest request,@ModelAttribute("user") User user, @ModelAttribute("addr") Addr2 addr){
Map<String,Object> map=new HashMap<String,Object>();
map.put("user", user);
map.put("addr", addr);
return map;
}
同样打开浏览器测试,在地址栏输入参数和数据,回车,后端看到正确接收到来自前端的数据,说明对 addr 的绑定是公用的。
参考:http://blog.youkuaiyun.com/qq_24505127/article/details/54236583