¿Cómo uso el mapeador Jackson JSON con Java 8 LocalDateTime?
org.codehaus.jackson.map.JsonMappingException: no se puede crear una instancia del valor de tipo [tipo simple, clase java.time.LocalDateTime] de la cadena JSON; sin constructor de cadena única / método de fábrica (a través de la cadena de referencia: MyDTO ["field1"] -> SubDTO ["date"])
Respuestas:
No es necesario usar serializadores / deserializadores personalizados aquí. Utilice el módulo de fecha y hora de jackson-modules-java8 :
Este módulo agrega soporte para bastantes clases:
fuente
registerModule(new JSR310Module())
ofindAndRegisterModules()
. Consulte github.com/FasterXML/jackson-datatype-jsr310 y aquí le mostramos cómo personalizar su objeto de mapeador si usa Spring framework: stackoverflow.com/questions/7854030/…OffsetDateTime
@Test
public void testJacksonOffsetDateTimeDeserializer() throws IOException {
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
String json = "\"2015-10-20T11:00:00-8:30\"";
mapper.readValue(json, OffsetDateTime.class);
}
objectMapper.registerModule(new JavaTimeModule());
. Tanto en la serialización como en la deserialización.Actualización: Dejando esta respuesta por razones históricas, pero no la recomiendo. Por favor vea la respuesta aceptada arriba.
Dígale a Jackson que asigne utilizando sus clases de serialización [de] personalizadas:
proporcionar clases personalizadas:
hecho aleatorio: si anido las clases anteriores y no las hago estáticas, el mensaje de error es extraño:
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
fuente
LocalDateTimeSerializer
yLocalDateTimeDeserializer
Si está utilizando la clase ObjectMapper de rapidxml, por defecto ObjectMapper no entiende la clase LocalDateTime, por lo tanto, debe agregar otra dependencia en su gradle / maven:
Ahora debe registrar el soporte de tipo de datos que ofrece esta biblioteca en su objeto objectmapper, esto se puede hacer de la siguiente manera:
Ahora, en su jsonString, puede poner fácilmente su campo java.LocalDateTime de la siguiente manera:
Al hacer todo esto, su conversión de archivos Json a objetos Java funcionará bien, puede leer el archivo de la siguiente manera:
fuente
findAndRegisterModules()
fue una pieza crítica que me faltaba al construir unObjectMapper
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
Esta dependencia de Maven resolverá su problema:
Una cosa que me ha costado es que la zona horaria ZonedDateTime se cambie a GMT durante la deserialización. Resultó que, por defecto, Jackson lo reemplaza con uno del contexto. Para mantener la zona, uno debe deshabilitar esta 'característica'
fuente
DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE
, también tuve que deshabilitarSerializationFeature.WRITE_DATES_AS_TIMESTAMPS
para que todo comience a funcionar como debería.Tuve un problema similar al usar Spring boot . Con Spring boot 1.5.1.RELEASE todo lo que tuve que hacer es agregar dependencia:
fuente
Si está utilizando Jersey, entonces necesita agregar la dependencia de Maven (jackson-datatype-jsr310) como lo sugirieron los demás y registrar su instancia de mapeador de objetos de la siguiente manera:
Al registrar a Jackson en sus recursos, debe agregar este mapeador de la siguiente manera:
fuente
Si no se puede utilizar
jackson-modules-java8
por cualquier razón se puede (des) serializar el campo instantánea comolong
el uso@JsonIgnore
y@JsonGetter
Y@JsonSetter
:Ejemplo:
rendimientos
fuente
Utilizo este formato de hora:
"{birthDate": "2018-05-24T13:56:13Z}"
para deserializar de json a java.time.Instant (ver captura de pantalla)fuente
Este es solo un ejemplo de cómo usarlo en una prueba unitaria que pirateé para depurar este problema. Los ingredientes clave son
mapper.registerModule(new JavaTimeModule());
<artifactId>jackson-datatype-jsr310</artifactId>
Código:
fuente
Puede configurar esto en su
application.yml
archivo para resolver el tiempo instantáneo, que es la API de fecha en java8:fuente
Si está usando Spring Boot y tiene este problema con OffsetDateTime, entonces necesita usar el registerModules como respondió anteriormente @greperror (respondió el 28 de mayo de 16 a las 13:04) pero tenga en cuenta que hay una diferencia. La dependencia mencionada no necesita ser agregada, ya que supongo que Spring Boot ya la tiene. Estaba teniendo este problema con Spring boot y funcionó para mí sin agregar esta dependencia.
fuente
Para aquellos que usan Spring Boot 2.x
No es necesario hacer nada de lo anterior: Java 8 LocalDateTime está serializado / deserializado de fábrica. Tuve que hacer todo lo anterior en 1.x, pero con Boot 2.x, funciona a la perfección.
Consulte también esta referencia JSON Java 8 LocalDateTime format en Spring Boot
fuente
Si alguien que tiene problemas al usar
SpringBoot
aquí es cómo solucioné el problema sin agregar una nueva dependencia.En
Spring 2.1.3
Jackson espera que la cadena de fecha2019-05-21T07:37:11.000
en esteyyyy-MM-dd HH:mm:ss.SSS
formato se des-serialiceLocalDateTime
. Asegúrese de que la cadena de fecha separe la fecha y la hora conT
no conspace
. segundos (ss
) y milisegundos (SSS
) podrían omitirse.fuente
Si está utilizando Jackson Serializer , esta es una forma de usar los módulos de fecha:
fuente
Si considera usar fastjson, puede resolver su problema, tenga en cuenta la versión
fuente
Si tiene este problema debido a GraphQL Java Tools y está tratando de ordenar un Java a
Instant
partir de una cadena de fecha, debe configurar su SchemaParser para usar un ObjectMapper con ciertas configuraciones:En su clase GraphQLSchemaBuilder, inyecte ObjectMapper y agregue estos módulos:
y agregarlo a las opciones:
Ver https://github.com/graphql-java-kickstart/graphql-spring-boot/issues/32
fuente