Джексон Маппер расширяет 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);
- Зависимость от импорта: jackson-datatype-jsr310
- Напишите класс расширения: 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);
}
}
- Тестовый код
@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);
}