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

时间:2019-09-18 16:22:44

标签: spring spring-boot spring-mvc jackson spring-restcontroller

我有以下问题,希望有人可以帮忙

上下文:3个其余端点

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

要求:对整个应用程序中的LocalDate使用相同的日期格式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;
}

我做过的测试:

从stackoverflow中,我还发现Spring不使用Jackson来反序列化查询参数,因此: -我用@ControllerAdvice创建了一个@InitBinder,但是从未调用过方法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的响应?

如何配置具有相同日期格式的整个应用程序以在序列化和解析/反序列化过程中工作?

更新

我在这里https://stackoverflow.com/questions/30871255/spring-boot-localdate-field-serialization-and-deserialization发现我可以将@JsonFormat用于其余控制器(序列化和反序列化),并将@DateTimeFormat用于ModelView控制器,但同时使用这两种方法都可以解决我的错误,所以我不明白为什么如果我只有休息控制器,那就是这种行为。在我的情况下,看起来像@DateTimeFormat反序列化和@JsonFormat序列化,这是预期的行为吗?是否有任何配置错误?

2 个答案:

答案 0 :(得分:0)

您可以将此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;
    }

答案 1 :(得分:0)

只需将属性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