详细分析@InitBinder注解的使用和原理

本文详细介绍了SpringMVC中@InitBinder注解的使用,包括如何通过它进行WebDataBinder初始化以实现类型转换,如字符串到Date。此外,还探讨了自定义Editor的实现,通过继承PropertyEditorSupport处理日期转换问题。同时,文章深入解析了WebDataBinder的初始化原理,以及@InitBinder修饰的方法加载过程。通过对@ControllerAdvice和@Controller类中@InitBinder方法的理解,阐述了它们的生效范围和作用。
摘要由CSDN通过智能技术生成

前言

由@InitBinder注解修饰的方法用于初始化WebDataBinder对象,能够实现:从request获取到handler方法中由@RequestParam注解或@PathVariable注解修饰的参数后,假如获取到的参数类型与handler方法上的参数类型不匹配,此时可以使用初始化好的WebDataBinder对获取到的参数进行类型处理。

一个经典的例子就是handler方法上的参数类型为Date,而从request中获取到的参数类型是字符串,SpringMVC在默认情况下无法实现字符串转Date,此时可以在由@InitBinder注解修饰的方法中为WebDataBinder对象注册CustomDateEditor,从而使得WebDataBinder能将从request中获取到的字符串再转换为Date对象。

通常,如果在@ControllerAdvice注解修饰的类中使用@InitBinder注解,此时@InitBinder注解修饰的方法所做的事情全局生效(前提是@ControllerAdvice注解没有设置basePackages字段);如果在@Controller注解修饰的类中使用@InitBinder注解,此时@InitBinder注解修饰的方法所做的事情仅对当前Controller生效。本篇文章将结合简单例子,对@InitBinder注解的使用,原理进行学习。

SpringBoot版本:2.4.1

正文

一. @InitBinder注解使用说明

以前言中提到的字符串转Date为例,对@InitBinder的使用进行说明。

@RestController
public class DateController {

    private static final String SUCCESS = "success";
    private static final String FAILED = "failed";

    private final List<Date> dates = new ArrayList<>();

    @RequestMapping(value = "/api/v1/date/add", method = RequestMethod.GET)
    public ResponseEntity<String> addDate(@RequestParam("date") Date date) {
        ResponseEntity<String> response;
        try {
            dates.add(date);
            response = new ResponseEntity<>(SUCCESS, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            response = new ResponseEntity<>(FAILED, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return response;
    }

}
复制代码

上面写好了一个简单的Controller,用于获取Date并存储。然后在单元测试中使用TestRestTemplate模拟客户端向服务端发起请求,程序如下。

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DateControllerTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void 测试Date字符串转换为Date对象() {
        ResponseEntity<String> response = restTemplate
                .getForEntity("/api/v1/date/add?date=20200620", String.class);

        assertThat(response.getStatusCodeValue(), is(HttpStatus.OK.value()));
    }

}
复制代码

由于此时并没有使用@InitBinder注解修饰的方法向WebDataBinder注册CustomDateEditor对象,运行测试程序时断言会无法通过,报错会包含如下信息。

Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'

由于无法将字符串转换为Date,导致了参数类型不匹配的异常。

下面使用@ControllerAdvice注解和@InitBinder注解为WebDataBinder添加CustomDateEditor对象,使SpringMVC框架为我们实现字符串转Date

@ControllerAdvice
public class GlobalControllerAdvice {

    @InitBinder
    public void setDateEditor(WebDataBinder binder) {
        
`@InitBinder` 是 Spring MVC 中的一个注解,它可以用来定制数据绑定过程。在 Spring MVC 中,当客户端提交请求时,Spring MVC 会自动将请求中的参数绑定到控制器方法的参数上,这个过程就是数据绑定。`@InitBinder` 可以用来注册自定义的数据编辑器或属性编辑器,从而控制数据绑定的过程。 具体来说,`@InitBinder` 注解可以用在控制器类中的方法上,它的作用是用来初始化 WebDataBinder 对象,这个对象负责将表单提交的数据绑定到控制器的方法参数上。在 `@InitBinder` 注解标记的方法中,可以使用 WebDataBinder 对象的一些方法来定制数据绑定过程,例如注册自定义的属性编辑器。 举个例子,如果你有一个控制器方法接收一个类型为 `java.util.Date` 的参数,你可以使用 `@InitBinder` 注解来注册一个 `CustomDateEditor` 对象,这个对象可以将字符串类型的日期转换成 `java.util.Date` 类型。具体代码如下: ```java @Controller public class MyController { @InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); } @RequestMapping("/test") public String test(Date date) { // do something with date return "success"; } } ``` 在上面的例子中,`initBinder` 方法使用 `SimpleDateFormat` 创建了一个日期格式化对象,并将它注册到 `WebDataBinder` 对象中,然后将 `WebDataBinder` 对象作为参数传递给 `initBinder` 方法。控制器方法 `test` 的参数是一个 `Date` 类型的对象,当客户端提交请求时,Spring MVC 会自动调用 `initBinder` 方法初始化 `WebDataBinder` 对象,然后使用这个对象将字符串类型的日期转换成 `java.util.Date` 类型,最后将 `Date` 对象绑定到 `test` 方法的参数上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值