Como uso o mapeador Jackson JSON com o Java 8 LocalDateTime?
org.codehaus.jackson.map.JsonMappingException: Não é possível instanciar o valor do tipo [tipo simples, classe java.time.LocalDateTime] de JSON String; nenhum construtor de cadeia única / método de fábrica (através da cadeia de referência: MyDTO ["field1"] -> SubDTO ["date"])
Respostas:
Não há necessidade de usar serializadores / desserializadores personalizados aqui. Use o módulo datetime de jackson-modules-java8 :
Este módulo adiciona suporte para várias classes:
fonte
registerModule(new JSR310Module())
oufindAndRegisterModules()
. Veja github.com/FasterXML/jackson-datatype-jsr310 e aqui é como personalizar o seu mapeador de objeto se você usar o framework Spring: 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 na serialização quanto na desserialização.Atualização: Deixar esta resposta por razões históricas, mas não a recomendo. Por favor, veja a resposta aceita acima.
Diga a Jackson para mapear usando suas classes de [de] serialização personalizadas:
forneça classes personalizadas:
fato aleatório: se eu aninhar acima das classes e não as tornar estáticas, a mensagem de erro é estranha:
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
fonte
LocalDateTimeSerializer
eLocalDateTimeDeserializer
Se você estiver usando a classe ObjectMapper de quickxml, por padrão, o ObjectMapper não entenderá a classe LocalDateTime, portanto, será necessário adicionar outra dependência em seu gradle / maven:
Agora você precisa registrar o suporte ao tipo de dados oferecido por esta biblioteca no objeto objectmapper, isso pode ser feito da seguinte maneira:
Agora, em seu jsonString, você pode facilmente colocar seu campo java.LocalDateTime da seguinte maneira:
Ao fazer tudo isso, seu arquivo Json para conversão de objeto Java funcionará bem. Você pode ler o arquivo da seguinte maneira:
fonte
findAndRegisterModules()
foi uma peça fundamental que faltava para mim quando construção de umObjectMapper
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
Essa dependência inteligente resolverá o seu problema:
Uma coisa que lutei é que, para o fuso horário do ZonedDateTime, seja alterado para GMT durante a desserialização. Acabou que, por padrão, jackson o substitui por um do contexto. Para manter a zona, é necessário desativar esse 'recurso'
fonte
DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE
, também tive que desativarSerializationFeature.WRITE_DATES_AS_TIMESTAMPS
para que tudo começasse a funcionar como deveria.Eu tive um problema semelhante ao usar a inicialização do Spring . Com o Spring boot 1.5.1.RELEASE, tudo o que eu precisava fazer era adicionar dependência:
fonte
Se você estiver usando Jersey, precisará adicionar a dependência do Maven (jackson-datatype-jsr310) conforme as outras sugestões e registrar sua instância do mapeador de objetos da seguinte maneira:
Ao registrar Jackson em seus recursos, você precisa adicionar este mapeador da seguinte forma:
fonte
Se você não puder usar
jackson-modules-java8
por qualquer motivo, poderá (des) serializar o campo instantâneolong
usando@JsonIgnore
e@JsonGetter
&@JsonSetter
:Exemplo:
rendimentos
fonte
Eu uso este formato de hora:
"{birthDate": "2018-05-24T13:56:13Z}"
para desserializar de json para java.time.Instant (veja a captura de tela)fonte
Este é apenas um exemplo de como usá-lo em um teste de unidade que eu hackeei para depurar esse problema. Os principais ingredientes são
mapper.registerModule(new JavaTimeModule());
<artifactId>jackson-datatype-jsr310</artifactId>
Código:
fonte
Se você estiver usando a inicialização do Spring e tiver esse problema com o OffsetDateTime, precisará usar o registerModules como respondido acima por @greperror (respondida em 28 de maio de 16 às 13:04), mas observe que há uma diferença. A dependência mencionada não precisa ser adicionada, pois acho que a bota de mola já a possui. Eu estava tendo esse problema com a inicialização do Spring e funcionou para mim sem adicionar essa dependência.
fonte
Você pode definir isso no seu
application.yml
arquivo para resolver o Instant time, que é a API da data em java8:fonte
Para quem usa o Spring Boot 2.x
Não há necessidade de executar nenhuma das ações acima - o Java 8 LocalDateTime é serializado / desserializado imediatamente. Eu tive que fazer tudo o que precede no 1.x, mas com o Boot 2.x, ele funciona perfeitamente.
Consulte esta referência também no formato JSON Java 8 LocalDateTime no Spring Boot
fonte
Se alguém com problemas durante o uso
SpringBoot
aqui é como eu corrigi o problema sem adicionar nova dependência.Em
Spring 2.1.3
Jackson espera que a string de data2019-05-21T07:37:11.000
nesteyyyy-MM-dd HH:mm:ss.SSS
formato seja desserializada emLocalDateTime
. Verifique se a sequência de datas separa a data e a hora comT
nãospace
. segundos (ss
) e milissegundos (SSS
) podem ser omitidos.fonte
Se você considerar o uso do fastjson, poderá resolver seu problema, observe a versão
fonte
Se você está tendo esse problema devido ao GraphQL Java Tools e tentando organizar um Java
Instant
partir de uma sequência de datas, precisa configurar o SchemaParser para usar um ObjectMapper com determinadas configurações:Na sua classe GraphQLSchemaBuilder, injete o ObjectMapper e adicione estes módulos:
e adicione-o às opções:
Consulte https://github.com/graphql-java-kickstart/graphql-spring-boot/issues/32
fonte
Se você estiver usando o Jackson Serializer , aqui está uma maneira de usar os módulos de data:
fonte