有没有办法配置 LocalDate 格式以在整个 spring 应用程序中进行序列化和反序列化?
Is there a way to configure LocalDate format for serializing and deserializing in the whole spring application?
我有以下问题希望有人能帮帮我:
上下文:3 个 Rest 端点
- 创建(
register
)
- 查找 (
findKid
)
- 举报(
listDashboardInfo
)
要求:在整个应用程序中对 LocalDates 使用相同的日期格式yyyyMMdd
问题:使用 @DateTimeFormat(pattern = DateUtils.SHORT_DATE_PATTERN)
适用于 register
和 listDashboardInfo
但不适用于 findKid
这些是代码的相关部分:
BODY
{
"sailDate": "20191201"
}
@PostMapping(KID_PATH)
@ResponseStatus(HttpStatus.CREATED)
public KidDTO register(@RequestBody @Valid KidDTO kid) {
return kidService.saveKid(kid);
}
GET /kid/0001::20190901
RESPONSE
{
"sailDate": "2019-09-01"
}
@GetMapping(KID_FIND_PATH)
public CompletableFuture<KidDTO> findKid(@PathVariable String id) {
return kidService.findKid(id);
}
GET /kid?shipCode=AL&sailDate=20190901
@GetMapping(KID_LIST_PATH)
public CompletableFuture<Slice<DashboardDTO>> listDashboardInfo(@Valid DashboardFilter filter, Pageable pageable) {
return kidService.listKidsWithStatistics(filter, pageable);
}
@Getter
@Setter
public class DashboardFilter {
@NotNull
@DateTimeFormat(pattern = DateUtils.SHORT_DATE_PATTERN)
private LocalDate sailDate;
}
@Data
public class KidDTO {
@NotNull
@DateTimeFormat(pattern = DateUtils.SHORT_DATE_PATTERN)
private LocalDate sailDate;
}
我做的测试:
- spring.jackson.date-application.properties 中的格式:来自 https://blog.codecentric.de/en/2017/08/parsing-of-localdate-query-parameters-in-spring-boot/ 这仅适用于 Date 而不是 LocalDate。
- 使用
@JsonFormat(pattern = DateUtils.SHORT_DATE_PATTERN)
listDashboardInfo
无法识别格式并产生错误
从 Whosebug 我还发现 Spring 不使用 Jackson 反序列化查询参数,所以:
- 我用 @InitBinder
创建了一个 @ControllerAdvice
但方法 setAsText
从未被调用过:
@ControllerAdvice
public class GlobalDateBinder {
@InitBinder
public void binder(WebDataBinder binder) {
binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
LocalDate.parse(text, DateUtils.SHORT_DATE_FORMATTER);
}
});
}
}
- 我也试过
@Bean public Formatter<LocalDate> localDateFormatter()
但没有任何变化:
@Bean
public FormattingConversionService conversionService() {
DefaultFormattingConversionService conversionService =
new DefaultFormattingConversionService(false);
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setDateFormatter(DateUtils.SHORT_DATE_FORMATTER);
registrar.registerFormatters(conversionService);
return conversionService;
}
@Bean
public Formatter<LocalDate> localDateFormatter() {
return new Formatter<LocalDate>() {
@Override
public LocalDate parse(String text, Locale locale) {
return LocalDate.parse(text, DateUtils.SHORT_DATE_FORMATTER);
}
@Override
public String print(LocalDate object, Locale locale) {
return DateUtils.SHORT_DATE_FORMATTER.format(object);
}
};
}
有人知道发生了什么事吗?
如何格式化findKid
的响应?
如何配置具有相同日期格式的整个应用程序以在序列化和 parsing/deserializing 进程中工作?
更新:
我在这里 发现我可以将 @JsonFormat 用于 rest 控制器(序列化和反序列化),将 @DateTimeFormat 用于 ModelView 控制器,但同时使用两者修复了我的错误,所以我不这样做如果我只有休息控制器,请理解为什么会出现这种行为。在我的案例中看起来像@DateTimeFormat 反序列化和@JsonFormat 序列化,这是预期的行为吗?有没有配置错误?
您可以将此 bean 添加到您的配置中:
@Bean
public ObjectMapper objectMapper() {
DateTimeFormatter dateFormatter; // create your date formatter
DateTimeFormatter dateTimeFormatter; // create your date and time formatter
ObjectMapper mapper = new ObjectMapper();
SimpleModule localDateModule = new SimpleModule();
localDateModule.addDeserializer(LocalDate.class,
new LocalDateDeserializer(formatter));
localDateModule.addSerializer(LocalDate.class,
new LocalDateSerializer(formatter));
localDateModule.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(dateTimeFormatter));
localDateModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(dateTimeFormatter));
mapper.registerModules(localDateModule);
return mapper;
}
只需将 属性 spring.jackson.date-format
设置为您想要的任何格式 application.properties
或 application.yml
.
示例application.properties
:
spring.jackson.date-format=yyyyMMdd
示例application.yml
:
spring:
jackson:
date-format: yyyyMMdd
来源和其他可用属性:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
我有以下问题希望有人能帮帮我:
上下文:3 个 Rest 端点
- 创建(
register
) - 查找 (
findKid
) - 举报(
listDashboardInfo
)
要求:在整个应用程序中对 LocalDates 使用相同的日期格式yyyyMMdd
问题:使用 @DateTimeFormat(pattern = DateUtils.SHORT_DATE_PATTERN)
适用于 register
和 listDashboardInfo
但不适用于 findKid
这些是代码的相关部分:
BODY
{
"sailDate": "20191201"
}
@PostMapping(KID_PATH)
@ResponseStatus(HttpStatus.CREATED)
public KidDTO register(@RequestBody @Valid KidDTO kid) {
return kidService.saveKid(kid);
}
GET /kid/0001::20190901
RESPONSE
{
"sailDate": "2019-09-01"
}
@GetMapping(KID_FIND_PATH)
public CompletableFuture<KidDTO> findKid(@PathVariable String id) {
return kidService.findKid(id);
}
GET /kid?shipCode=AL&sailDate=20190901
@GetMapping(KID_LIST_PATH)
public CompletableFuture<Slice<DashboardDTO>> listDashboardInfo(@Valid DashboardFilter filter, Pageable pageable) {
return kidService.listKidsWithStatistics(filter, pageable);
}
@Getter
@Setter
public class DashboardFilter {
@NotNull
@DateTimeFormat(pattern = DateUtils.SHORT_DATE_PATTERN)
private LocalDate sailDate;
}
@Data
public class KidDTO {
@NotNull
@DateTimeFormat(pattern = DateUtils.SHORT_DATE_PATTERN)
private LocalDate sailDate;
}
我做的测试:
- spring.jackson.date-application.properties 中的格式:来自 https://blog.codecentric.de/en/2017/08/parsing-of-localdate-query-parameters-in-spring-boot/ 这仅适用于 Date 而不是 LocalDate。
- 使用
@JsonFormat(pattern = DateUtils.SHORT_DATE_PATTERN)
listDashboardInfo
无法识别格式并产生错误
从 Whosebug 我还发现 Spring 不使用 Jackson 反序列化查询参数,所以:
- 我用 @InitBinder
创建了一个 @ControllerAdvice
但方法 setAsText
从未被调用过:
@ControllerAdvice
public class GlobalDateBinder {
@InitBinder
public void binder(WebDataBinder binder) {
binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
LocalDate.parse(text, DateUtils.SHORT_DATE_FORMATTER);
}
});
}
}
- 我也试过
@Bean public Formatter<LocalDate> localDateFormatter()
但没有任何变化:
@Bean
public FormattingConversionService conversionService() {
DefaultFormattingConversionService conversionService =
new DefaultFormattingConversionService(false);
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setDateFormatter(DateUtils.SHORT_DATE_FORMATTER);
registrar.registerFormatters(conversionService);
return conversionService;
}
@Bean
public Formatter<LocalDate> localDateFormatter() {
return new Formatter<LocalDate>() {
@Override
public LocalDate parse(String text, Locale locale) {
return LocalDate.parse(text, DateUtils.SHORT_DATE_FORMATTER);
}
@Override
public String print(LocalDate object, Locale locale) {
return DateUtils.SHORT_DATE_FORMATTER.format(object);
}
};
}
有人知道发生了什么事吗?
如何格式化findKid
的响应?
如何配置具有相同日期格式的整个应用程序以在序列化和 parsing/deserializing 进程中工作?
更新:
我在这里
您可以将此 bean 添加到您的配置中:
@Bean
public ObjectMapper objectMapper() {
DateTimeFormatter dateFormatter; // create your date formatter
DateTimeFormatter dateTimeFormatter; // create your date and time formatter
ObjectMapper mapper = new ObjectMapper();
SimpleModule localDateModule = new SimpleModule();
localDateModule.addDeserializer(LocalDate.class,
new LocalDateDeserializer(formatter));
localDateModule.addSerializer(LocalDate.class,
new LocalDateSerializer(formatter));
localDateModule.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(dateTimeFormatter));
localDateModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(dateTimeFormatter));
mapper.registerModules(localDateModule);
return mapper;
}
只需将 属性 spring.jackson.date-format
设置为您想要的任何格式 application.properties
或 application.yml
.
示例application.properties
:
spring.jackson.date-format=yyyyMMdd
示例application.yml
:
spring:
jackson:
date-format: yyyyMMdd
来源和其他可用属性:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html