Eu tenho um formato de data vindo da API como este:
"start_time": "2015-10-1 3:00 PM GMT+1:00"
Qual é o carimbo de data / hora AAAA-DD-MM HH: MM am / pm GMT. Estou mapeando esse valor para uma variável Date no POJO. Obviamente, está mostrando erro de conversão.
Eu gostaria de saber 2 coisas:
- Qual é a formatação que preciso usar para realizar a conversão com Jackson? Data é um bom tipo de campo para isso?
- Em geral, existe uma maneira de processar as variáveis antes que elas sejam mapeadas para membros do objeto por Jackson? Algo como, alterar o formato, cálculos, etc.
Date
classe. O java.time, a moderna API de data e hora do Java, a substituiu há quase 5 anos. Use-o e o FasterXML / jackson-modules-java8 .Respostas:
Date
é um tipo de campo fino para isso. Você pode tornar o JSON analisável com bastante facilidade usandoObjectMapper.setDateFormat
:Sim. Você tem algumas opções, incluindo a implementação de um costume
JsonDeserializer
, por exemplo, extensãoJsonDeserializer<Date>
. Este é um bom começo.fonte
LocalDateTime
ou emZonedDateTime
vez deDate
? ComoDate
está basicamente obsoleto (ou pelo menos muitos de seus métodos), eu gostaria de usar essas alternativas.java.util.Date
explicitamente, quero salientar que isso não funciona.java.sql.Date.
Veja também minha resposta abaixo.Desde o Jackson v2.0, você pode usar a anotação @JsonFormat diretamente nos membros do Object;
fonte
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
Obviamente, existe uma maneira automatizada chamada serialização e desserialização e você pode defini-la com anotações específicas ( @JsonSerialize , @JsonDeserialize ), conforme mencionado pelo pb2q.
Você pode usar java.util.Date e java.util.Calendar ... e provavelmente o JodaTime também.
As anotações @JsonFormat não funcionaram para mim como eu queria ( ajustou o fuso horário para um valor diferente) durante a desserialização (a serialização funcionou perfeitamente):
Você precisa usar o serializador personalizado e o desserializador personalizado em vez da anotação @JsonFormat, se desejar um resultado previsto. Encontrei um bom tutorial e solução aqui http://www.baeldung.com/jackson-serialize-dates
Existem exemplos para os campos Data , mas eu precisava para os campos Calendário , então aqui está minha implementação :
A classe do serializador :
A classe desserializador :
e o uso das classes acima:
Usando essa implementação, a execução do processo de serialização e desserialização resulta consecutivamente no valor de origem.
Somente usando a anotação @JsonFormat, a desserialização dá um resultado diferente , acho que, devido à configuração padrão do fuso horário interno da biblioteca, o que você não pode alterar com os parâmetros de anotação (essa também foi minha experiência com as versões 2.5.3 e 2.6.3 da biblioteca Jackson).
fonte
Apenas um exemplo completo para o aplicativo de inicialização com
RFC3339
formato de data e horafonte
Para adicionar caracteres como T e Z na sua data
resultado
fonte
Trabalhando para mim. SpringBoot.
resultado:
fonte
Com base na resposta muito útil de @ miklov-kriven, espero que esses dois pontos adicionais de consideração sejam úteis para alguém:
(1) Acho uma boa ideia incluir serializador e desserializador como classes internas estáticas na mesma classe. NB, usando ThreadLocal para segurança de thread de SimpleDateFormat.
(2) Como alternativa ao uso das anotações @JsonSerialize e @JsonDeserialize em cada membro da classe, você também pode substituir a serialização padrão de Jackson aplicando a serialização personalizada no nível do aplicativo, ou seja, todos os membros da classe do tipo Date serão serializados por Jackson usando essa serialização customizada sem anotação explícita em cada campo. Se você estiver usando o Spring Boot, por exemplo, uma maneira de fazer isso seria da seguinte maneira:
fonte
Se alguém tiver problemas com o uso de um formato de data personalizado para java.sql.Date, esta é a solução mais simples:
(Essa resposta SO me poupou muitos problemas: https://stackoverflow.com/a/35212795/3149048 )
Jackson usa o SqlDateSerializer por padrão para java.sql.Date, mas atualmente, esse serializador não leva em conta o formato da data, consulte este problema: https://github.com/FasterXML/jackson-databind/issues/1407 . A solução alternativa é registrar um serializador diferente para java.sql.Date, conforme mostrado no exemplo de código.
fonte
Quero salientar que definir um exemplo
SimpleDateFormat
descrito na outra resposta só funciona para ojava.util.Date
que eu suponho que se refira à pergunta. Mas parajava.sql.Date
o formatador não funciona. No meu caso, não era muito óbvio por que o formatador não funcionou, porque no modelo que deveria ser serializado o campo era de fato um,java.utl.Date
mas o objeto real acabou sendo umjava.sql.Date
. Isso é possível porqueEntão isso é realmente válido
Portanto, se você está se perguntando por que o campo Data não está formatado corretamente, verifique se o objeto é realmente um
java.util.Date
.Aqui também é mencionado por que o manuseio
java.sql.Date
não será adicionado.fonte
Date
classes diferentes . Hoje em dia, não se deve nem um delesSimpleDateFormat
. O java.time, a moderna API de data e hora do Java, os substituiu há quase 5 anos. Use-o e o FasterXML / jackson-modules-java8 .