SpringMVC之@InitBinder注解(日期转换)

  1. Spring MVC之@InitBinder注解(日期转换)
    1. @InitBinder 注解作用
    2. @InitBinder 注解源码
    3. @ControllerAdvice 全局注册
    4. 使用其他格式转化器

Spring MVC之@InitBinder注解(日期转换)

作者:YD_1989、来源:SpringMVC之@InitBinder注解(日期转换):https://blog.csdn.net/m0_58680865/article/details/125006308

@InitBinder 注解作用

SpringMVC 并不是能对所有类型的参数进行绑定的,如果对日期 Date 类型参数进行绑定,就会报错 IllegalStateException 错误。所以需要注册一些类型绑定器用于对参数进行绑定。InitBinder注解就有这个作用。

代码示例:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;

@RestController
public class InitBinderController {

    @RequestMapping(value = "/testInitBinder", method = RequestMethod.GET)
    public String testInitBinder(Date date) {
        System.out.println("date = " + date);
        return "testInitBinder";
    }
}

测试 Controller API:

curl -X GET localhost:8080/testInitBinder?date=2019-05-15
{"timestamp":"2024-08-26T03:47:59.076+00:00","status":400,"error":"Bad Request","path":"/testInitBinder"}

控制台报错:

2024-08-26 11:47:59.068  WARN 36167 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2019-05-15'; nested exception is java.lang.IllegalArgumentException]

报错提示不能把 String 类型转换为 Date 类型报错。此时就需要一个日期类型转换器。

import org.springframework.format.datetime.DateFormatter;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;

@RestController
public class InitBinderController {

    @RequestMapping(value = "/testInitBinder", method = RequestMethod.GET)
    private String testInitBinder(Date date) {
        System.out.println("date = " + date);
        return "testInitBinder";
    }

    @InitBinder
    public void dateTypeBinder(WebDataBinder webDataBinder) {
        // 往数据绑定器中添加一个DateFormatter日期转化器。
        webDataBinder.addCustomFormatter(new DateFormatter("yyyy-mm-dd"));
    }
}

测试 Controller API:

curl -X GET localhost:8080/testInitBinder?date=2019-05-15
testInitBinder

控制台输出:

date = Tue Jan 15 00:05:00 CST 2019

@InitBinder 注解源码

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InitBinder {
    // 指定参数名,这个不知控制器方法上形参的参数名,而是请求参数名,
    // 可以指定多个。指定后只有这些参数需要用到该转换器。如果不指定,默认所有。
    String[] value() default {};
}

注意:并且使用InitBinder 注册的绑定器只有在当前 Controller 中才有效,不会作用于其他 Controller。

@ControllerAdvice 全局注册

此时,就需要用到 @ControllerAdvice 注解定义全局绑定器。使不同 Controller 的方法都能作用到。

import org.springframework.format.datetime.DateFormatter;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

@ControllerAdvice
public class InitConfig {

    @InitBinder
    public void dateTypeBinder(WebDataBinder webDataBinder) {
        // 往数据绑定器中添加一个DateFormatter日期转化器。
        webDataBinder.addCustomFormatter(new DateFormatter("yyyy-mm-dd"));
    }
}

使用其他格式转化器

我们可以自定义格式转化器,实现 Formatter 接口就可。还可以添加验证器等等。

public class StringFormatter implements Formatter<String> {
    private static final String PREFIX = "convertString == ";

    @Override
    public String parse(String text, Locale locale) throws ParseException {
        return rPREFIX + text;
    }

    @Override
    public String print(String object, Locale locale) {
        return object;
    }
}

添加

import org.springframework.format.datetime.DateFormatter;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

@ControllerAdvice
public class InitConfig {

    @InitBinder
    public void dateTypeBinder(WebDataBinder webDataBinder) {
        // 往数据绑定器中添加一个DateFormatter日期转化器。
        webDataBinder.addCustomFormatter(new DateFormatter("yyyy-mm-dd"));

        // 添加一个string类型的数据绑定器,作用是加个前缀
        webDataBinder.addCustomFormatter(new StringFormatter());
    }
}

测试 Controller API:

curl -X GET localhost:8080/testInitBinder?date=2019-05-15
testInitBinder

打印结果:

name = convertString == 刘亦菲

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 8629303@qq.com

×

喜欢就点赞,疼爱就打赏

GitHub