简体   繁体   English

Spring 引导无法为 REST API 输入设置全局日期格式

[英]Spring Boot unable to set global date format for REST API input

I am trying to set a global format for date-time, so that I don't have to annotate each and every method or on DTO fields.我正在尝试为日期时间设置全局格式,这样我就不必注释每个方法或 DTO 字段。

I have tried to configure it globally, the only impact it had was on API response , it is formatting the date in specific pattern.我尝试全局配置它,它的唯一影响是对API 响应,它以特定模式格式化日期。

But it does not accept it as an input format.但它不接受它作为输入格式。

@Configuration
public class DateFormatConfig {

    public DateFormatConfig() {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
        return builder -> {
            builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
            builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        };
    }
}

Exception message异常消息

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 [@org.springframework.web.bind.annotation.RequestParam 
    java.util.Date] for value '2022-01-03 19:32:22'; nested exception is java.lang.IllegalArgumentException
....
Caused by: java.lang.IllegalArgumentException: null
    at java.base/java.util.Date.parse(Date.java:616) ~[na:na]
    at java.base/java.util.Date.<init>(Date.java:274) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) ~[na:na]

A REST controller method where the call lands is as follow一个 REST controller 方法,其中调用落地如下

public Response update(@PathVariable("id") 
                            Long id,
                       @RequestParam(value = "someTime", required = false) 
                            Date someTime)

My expectaion from above configuration is, it should work for both input and output of the API我对上述配置的期望是,它应该适用于 API 的输入和 output

  1. It must accept the format I specificy for input它必须接受我指定的输入格式
  2. It must accept null as value它必须接受 null 作为值

Everything works fine if I use @DateTimeFormat annotation , which means for each field I have to make such changes如果我使用@DateTimeFormat注释,一切正常,这意味着我必须对每个字段进行此类更改

@RequestParam(value = "someTime", required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date someTime

Can you try with below code.It should work.您可以尝试使用以下代码吗。它应该可以工作。

@PostConstruct
    public void init() {
        // Setting Spring Boot SetTimeZone
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    }

you should use你应该使用

@Bean
public Converter<String, Date> stringDateConverter() {
    return new Converter<String, Date>() {
        final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        @Override
        public Date convert(@NonNull String source) {
            return Date.from(formatter.parse(source, LocalDateTime::from).toInstant(ZoneOffset.UTC));
        }
    };
}

AbstractNamedValueMethodArgumentResolver#resolveArgument use WebDataBinder , WebDataBinder use ConversionService registered in WebMvcAutoConfiguration.EnableWebMvcConfiguration#mvcConversionService , and this converter will be registered in org.springframework.boot.convert.ApplicationConversionService#addBeans AbstractNamedValueMethodArgumentResolver#resolveArgument使用WebDataBinderWebDataBinder使用在WebMvcAutoConfiguration.EnableWebMvcConfiguration#mvcConversionService中注册的ConversionService ,这个转换器会在org.springframework.boot.convert.ApplicationConversionService#addBeans中注册

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM