SpringMvc @InitBinder 表单多对象精准绑定接收

3 篇文章 0 订阅
3 篇文章 0 订阅

问题出现

要在一张表单中提交多个对象,并且还要在后台Controller 中精准的绑定接收。可是,这些对象中的参数名可能相同,后台接收入参时无法像struts那样jsp表单中使用Object.Param形式对表单进行精准绑定入参,我们都知道struts2默认就是这种方案,这是因为struts2采用了OGNL,并通过栈(根对象)进行操作的,而且栈中默认有action实例,所以很自然的没有这种问题。另一方面说,Struts用这种方式绑定入参,却牺牲了性能。虽然springmvc不能像struts那样方便的很直接的入参绑定,当然,Spring多对象绑定入参也提供了方法。

今天就以前台表单提交两个对象做实例。为了扩大影响,我让这两个对象的属性相同。

User.java 和Addr.java


public class User implements Serializable{
    String id;
    String name;
    //get..set....
}

public class Addr implements Serializable{
    String id;
    String name;//set..get...
}

前台JSP


<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>

看到这种情况,很容易想到struts进行绑定非常方便,可是,谁让我们要使用SpringMVC呢。。。这种情况springMVC直接进行入参,是不能接收到参数的。

问题思路

使用 @InitBinder 注解进行绑定参数。前台表单中name属性仍然使用Object.Param形式传入。(另一种解决思路:扩展spring的HandlerMethodArgumentResolver以支持自定义的数据绑定方式。)

@InitBinder("user")
public void initBinderUser(WebDataBinder binder) {
	binder.setFieldDefaultPrefix("user.");
}

此处使用@InitBinder() 中间的value,用于指定命令/表单属性或请求参数的名字,符合该名字的将使用此处的DataBinder,如我们的@ModelAttribute("user1") User user1 将使用@InitBinder("user1")指定的DataBinder绑定;如果不指定value值,那么所有的都将使用。

DataBinder.setFieldDefaultPrefix 意思是设置参数的前缀,如我们的是"user1.",此处不能少了".",

这种方式的缺点:

1、不支持Path variable的绑定,如/test1/{user1.id}这种情况的绑定;

2、不支持如集合/数组的绑定;

问题解决


@Controller
@RequestMapping("/test")
public class TestController {

    // 绑定变量名字和属性,参数封装进类
	@InitBinder("user")
	public void initBinderUser(WebDataBinder binder) {
		binder.setFieldDefaultPrefix("user.");
	}
	
    // 绑定变量名字和属性,参数封装进类
	@InitBinder("addr")
	public void initBinderAddr(WebDataBinder binder) {
		binder.setFieldDefaultPrefix("addr.");
	}
	
	
	@RequestMapping("/test")
	@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;
	}

就一个@InitBinder 就可以解决了。


另外可以通过DataBinder完成如下几件事情:

1、binder.setAllowedFields("id")  : 设置允许的字段,比如我只想设置id,那么可以调用这个方法,那么其他属性会忽略;

2、binder.setDisallowedFields("id") : 设置不允许的自动,比如我不想设置id,那么可以调用此方法,这个属性将不设置;

3、binder.setRequiredFields() : 表示哪些字段是必填的;

4、binder.setValidator() :设置自定义的验证器,如果如JSR-303不适合,可以使用这个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值