Джексон Маппер расширяет LocalDate

У нас есть DTO, определенный с LocalDate:

@JsonProperty("dob")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate dob;

У нас есть код с ObjectMapper, определенный следующим образом:

private static final ObjectMapper makeMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new ParameterNamesModule());
    mapper.registerModule(new Jdk8Module());
    mapper.registerModule(new JavaTimeModule());
    return mapper;
}

У нас есть все ядро ​​jackson-datababindm, jsr310, в нашем файле pom.xml:

    <!-- Jackson JSON Mapping -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.8.8</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.8.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.8.8</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-parameter-names</artifactId>
        <version>2.8.8</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jdk8</artifactId>
        <version>2.8.8</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>2.8.8</version>
    </dependency>

Итак, когда я конвертирую свой объект в строку JSON:

    String json = makeMapper().writeValueAsString(myobject);

Dob записывает в строку JSON как:

"dob": {"year": 1964, "month": "FEBRUARY", "chronology": {"calendarType": "iso8601", "id": "ISO"}, "monthValue": 2, "dayOfMonth": 13, "dayOfWeek": "ЧЕТВЕРГ", "era": "CE", "dayOfYear": 44, "leapYear": true}

вместо: "dob":"1964-02-13", что правильно.

Итак, я не уверен, как я это сделал?
Я хотел бы убедиться, что дата записана правильно, чтобы я мог повторно проанализировать обратно в LocalDate. Или есть способ, которым я могу взять существующий JSON (расширенный) и проанализировать его обратно в LocalDate?

Спасибо!

3 ответа

Решение

Оказывается, это была проблема ClassLoader. В наименьшем случае код работает, и LocalDate соответственно превращается в JSON. Когда вы переводите один проект в другой в другой, то получается, что ObjectMapper был определен в другом месте без JavaTimeModule.

Я взял код:

private static final ObjectMapper makeMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new ParameterNamesModule());
    mapper.registerModule(new Jdk8Module());
    mapper.registerModule(new JavaTimeModule());
    return mapper;
}

и принес это прямо в мой класс, где я нуждался в этом, и это сработало. Мне не помогло обращение к утилите из другого проекта.

Надеюсь, это поможет кому-то еще.

В com.fasterxml.jackson.core:jackson-databind:2.9.7 может достичь LocalDate обходной путь с помощью следующего кода:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.registerModule(new JavaTimeModule());
String expectedJson = objectMapper.writeValueAsString(dataVersions);
  1. Зависимость от импорта: jackson-datatype-jsr310
  2. Напишите класс расширения: JsonJacksonCodecExt
      package org.wjw.redisson;

import org.redisson.codec.JsonJacksonCodec;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

/** 对 {@link org.redisson.codec.JsonJacksonCodec} 的扩展,是的其能支持LocalDate
 * The Class JsonJacksonCodecExt.
 */
public class JsonJacksonCodecExt extends JsonJacksonCodec{
  @Override
  protected void init(ObjectMapper objectMapper) {
    objectMapper.registerModule(new JavaTimeModule());
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    
    super.init(objectMapper);    
  }
  
}
  1. Тестовый код
        @Test
  void testRMap_PutGet_JsonStringCodec() {
    RMap<String, User> map = redisson.getMap("jsonMap",new JsonJacksonCodecExt());
    map.put("1", new User("wjw1", 18, LocalDate.now()));
    map.put("2", new User("wjw2", 19, LocalDate.now()));
    map.put("3", new User("wjw3", 20, LocalDate.now()));

    User v = map.get("2");

    System.out.println(v);
  }
Другие вопросы по тегам