有没有办法配置 LocalDate 格式以在整个 spring 应用程序中进行序列化和反序列化?

Is there a way to configure LocalDate format for serializing and deserializing in the whole spring application?

我有以下问题希望有人能帮帮我:

上下文:3 个 Rest 端点

  1. 创建(register
  2. 查找 (findKid)
  3. 举报(listDashboardInfo

要求:在整个应用程序中对 LocalDates 使用相同的日期格式yyyyMMdd

问题:使用 @DateTimeFormat(pattern = DateUtils.SHORT_DATE_PATTERN) 适用于 registerlistDashboardInfo 但不适用于 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;
}

我做的测试:

从 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 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.propertiesapplication.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