前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMvc 注解 @InitBinder 表单多对象精准绑定接收

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

作者头像
微风-- 轻许--
发布2019-07-02 13:45:48
1.5K0
发布2019-07-02 13:45:48
举报
文章被收录于专栏:java 微风java 微风java 微风

@InitBinder用于在@Controller中标注于方法,表示为当前控制器注册一个属性编辑器或者其他,只对当前的Controller有效。

在使用SpringMVC的时候,经常会遇到表单中的日期字符串和JavaBean的Date类型的转换,而SpringMVC默认不支持这个格式的转换,需要手动配置自定义数据的绑定才能解决这个问题。

在需要日期转换的Controller中使用SpringMVC的注解@initbinder和Spring自带的WebDateBinder类来操作。

WebDataBinder是用来绑定请求参数到指定的属性编辑器. 由前台传到controller里的值是String类型的,当往Model里Set这个值的时候,如果set的这个属性是个对象,Spring就会去找到对应的editor进行转换,然后再SET进去。

-----------------------------------我是分隔线-----------------------------------

一. 问题描述: 一张表单中提交多个对象,并在后台Controller 中精准的绑定。可对象中的参数名有的相同,后台接收入参时无法像struts那样jsp表单中使用Object.Param形式对表单进行精准绑定入参(struts2默认就是这种方案),因为struts2采用了OGNL,并通过栈(根对象)进行操作,栈中默认有action实例,所以无此问题。但 Struts用这种方式绑定入参牺牲了性能。

现在以前台表单提交两个对象为例。

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>

此时 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不适合,可以使用这个。

完整例子:

两个对象

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>

Controller

@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;
    }

--------------------- 转自:

https://blog.csdn.net/qq_24505127/article/details/54236583

https://blog.51cto.com/simplelife/1919597

另关于类型转换见另一文章: SpringMVC注解 @initbinder 解决类型转换问题

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年06月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档