Spring 启动无法为 REST API 输入设置全局日期格式
Spring Boot unable to set global date format for REST API input
我正在尝试为日期时间设置一个全局格式,这样我就不必对每个方法或 DTO 字段进行注释。
我试过全局配置它,它唯一的影响是 API 响应,它正在以特定模式格式化日期。
但它不接受它作为输入格式。
@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")));
};
}
}
异常消息
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]
调用登陆的REST控制器方法如下
public Response update(@PathVariable("id")
Long id,
@RequestParam(value = "someTime", required = false)
Date someTime)
我对上述配置的期望是,它应该适用于 API
的输入和输出
- 它必须接受我指定的输入格式
- 它必须接受 null 作为值
如果我使用 @DateTimeFormat
注释,一切正常,这意味着我必须对每个字段进行此类更改
@RequestParam(value = "someTime", required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date someTime
你能试试下面的 code.It 应该可以吗。
@PostConstruct
public void init() {
// Setting Spring Boot SetTimeZone
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
你应该使用
@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
使用WebDataBinder
,WebDataBinder
使用ConversionService
在WebMvcAutoConfiguration.EnableWebMvcConfiguration#mvcConversionService
中注册,此转换器将在org.springframework.boot.convert.ApplicationConversionService#addBeans
[=中注册17=]
我正在尝试为日期时间设置一个全局格式,这样我就不必对每个方法或 DTO 字段进行注释。
我试过全局配置它,它唯一的影响是 API 响应,它正在以特定模式格式化日期。
但它不接受它作为输入格式。
@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")));
};
}
}
异常消息
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]
调用登陆的REST控制器方法如下
public Response update(@PathVariable("id")
Long id,
@RequestParam(value = "someTime", required = false)
Date someTime)
我对上述配置的期望是,它应该适用于 API
的输入和输出- 它必须接受我指定的输入格式
- 它必须接受 null 作为值
如果我使用 @DateTimeFormat
注释,一切正常,这意味着我必须对每个字段进行此类更改
@RequestParam(value = "someTime", required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date someTime
你能试试下面的 code.It 应该可以吗。
@PostConstruct
public void init() {
// Setting Spring Boot SetTimeZone
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
你应该使用
@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
使用WebDataBinder
,WebDataBinder
使用ConversionService
在WebMvcAutoConfiguration.EnableWebMvcConfiguration#mvcConversionService
中注册,此转换器将在org.springframework.boot.convert.ApplicationConversionService#addBeans
[=中注册17=]