Loading

Spring WebDataBinder

什么是WebDataBinder

WebDataBinder可以:

  1. 将请求参数(form或query data)绑定到一个模型对象上
  2. 将基于String的请求值(比如请求参数、路径变量、头、Cookies等)转换为Controller方法参数的目标类型
  3. 渲染HTML表单时将模型对象值格式化为String

在Web应用中,databinding可以将HTTP请求参数(form data或query parameter)绑定到一个模型对象或它的内嵌对象的属性中

只有符合JavaBean命名惯例规定的public属性才会被databinding绑定,比如一个firstName属性的public String getFirstName()public void setFirstName(String)方法。

尝试

尝试向Model Object中注入属性

下面在一个Controller方法中,我们定义了一个Person类型的参数,按照官方文档中@RequestMapping方法参数一节的描述,我们知道这个Person将被作为@ModelAttribute参数来处理,在没有其它代码的情况下,SpringMVC会调用它的无参构造器创建一个新的Person对象并加入到Model中:

@GetMapping("/testInjectToModelObjectProperties")
public String testInjectToModelObjectProperties(
        Person person,
        Model model
) {
    System.out.println("Person: " + person);
    System.out.println("Model: " + model);
    return "modelTestPage3";
}

根据上面的描述,databinding将HTTP请求的参数绑定到模型对象的属性中,那我们不妨试试,如下是我的请求URL:

http://${webapplicationrootpath}/databinding/testInjectToModelObjectProperties?name=Yudoge&age=12&weight=158.7&height=180&address=%E7%BF%BB%E6%96%97%E5%A4%A7%E8%A1%97%E7%BF%BB%E6%96%97%E8%8A%B1%E5%9B%AD3%E5%8F%B7%E6%A5%BC1001%E5%AE%A4&birthday=2001-04-10

我们将Person中的全部属性都通过URL参数进行了注入,得到的结果是:

img

尝试向Model Object内嵌的对象中注入属性

构造一个具有内嵌对象的Pojo:

@Data
@NoArgsConstructor
public class NestedPerson {
    String testField;
    Person person;
}

URL:

http://localhost:8080/databinding/testInjectNestedProperty?testField=hello&person.name=Yudoge

在注入内嵌属性的时候,需要带属性的完整路径,比如person.name,WebBinder会自动创建嵌套的Person对象。

配置WebDataBinder

@Controller@ControllerAdvice类都可以有一个@InitBinder注解标注的方法用来初始化它的WebDataBinder对象。

@InitBinder
public void initBinder(WebDataBinder binder) {
}

在这个方法中,你可以对本Controller的WebDataBinder做任何配置。比如你可以注册该Controller特定的PropertyEditorConverterFormatter组件。

@InitBinder方法也支持与@RequestMapping方法一样的参数,除了@ModelAttribute参数。

下面通过WebDateBinder注册了PropertyEditorFormatterConverterWebDataBinder好像没有直接用于注册Converter的API,但是它有一个用于获取ConversionService的API,一般的ConversionService都同样实现了ConverterRegistry,所以可以通过这个来注册Converter

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), false));
    binder.addCustomFormatter(new DateFormatter());

    FormattingConversionService service = (FormattingConversionService) binder.getConversionService();
    service.addConverter(xxx);
}
posted @ 2022-07-25 09:36  yudoge  阅读(474)  评论(0编辑  收藏  举报