使用HATEOAS时ZonedDateTime的Jackson反序列化问题

问题描述

我使用的DTO有

   private zoneddatetime created;

如果我不使用HATEOAS,我得到的输出

   "created": "2020-08-21T13:11:39+01:00[Europe/dublin]"

实施HATEOAS时

   resourceAssembler.toResource(studentService.getStudentById())

我得到的是

"created": {
"offset": {
    "totalSeconds": 3600,"id": "+01:00","rules": {
        "transitions": [],"transitionRules": [],"fixedOffset": true
    }
},"zone": {
    "id": "Europe/London","rules": {
        "transitions": [
            {
                "offsetBefore": {
                    "totalSeconds": -1500,"id": "-00:25","rules": {
                        "transitions": [],"fixedOffset": true
                    }
                },"offsetAfter": {
                    "totalSeconds": -1521,"id": "-00:25:21","dateTimeAfter": {
                    "nano": 0,"hour": 23,"minute": 59,"second": 39,"year": 1880,

我为Jackson添加的依赖项

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-jaxb-annotations</artifactId>
    </dependency>

Jackson配置

@Bean
public ObjectMapper objectMapper() {       
    ObjectMapper mapper = new ObjectMapper();
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    mapper.disable(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS);
    mapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.registerModule(new JavaTimeModule());
    return mapper;
}

我使用的SpringBoot版本是1.5.14

解决方法

Spring HATEOAS构造了自己的对象映射器,因此解决我的问题的解决方法是

@Configuration
public class ObjectMapperCustomizer {

  private static final String SPRING_HATEOAS_OBJECT_MAPPER = "_halObjectMapper";

  @Autowired
  @Qualifier(SPRING_HATEOAS_OBJECT_MAPPER)
  private ObjectMapper springHateoasObjectMapper;

  @Bean(name = "objectMapper")
  ObjectMapper objectMapper() {
    springHateoasObjectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
    springHateoasObjectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    springHateoasObjectMapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,false);
    springHateoasObjectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,false);
    springHateoasObjectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
    springHateoasObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
    springHateoasObjectMapper.registerModules(new JavaTimeModule());
    return springHateoasObjectMapper;
  }

}