Come serializzare Joda DateTime con l’elaboratore Jackson JSON?

Come posso ottenere da Jackson la serializzazione del mio object Joda DateTime secondo un modello semplice (come “dd-MM-yyyy”)?

Ho provato:

@JsonSerialize(using=DateTimeSerializer.class) private final DateTime date; 

Ho anche provato:

 ObjectMapper mapper = new ObjectMapper() .getSerializationConfig() .setDateFormat(df); 

Grazie!

Questo è diventato molto facile con Jackson 2.0 e il modulo Joda.

 ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule()); 

Dipendenza da Maven:

  com.fasterxml.jackson.datatype jackson-datatype-joda 2.1.1  

Codice e documentazione: https://github.com/FasterXML/jackson-datatype-joda

Binari: http://repo1.maven.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-joda/

Nell’object che stai mappando:

 @JsonSerialize(using = CustomDateSerializer.class) public DateTime getDate() { ... } 

In CustomDateSerializer:

 public class CustomDateSerializer extends JsonSerializer { private static DateTimeFormatter formatter = DateTimeFormat.forPattern("dd-MM-yyyy"); @Override public void serialize(DateTime value, JsonGenerator gen, SerializerProvider arg2) throws IOException, JsonProcessingException { gen.writeString(formatter.print(value)); } } 

Come ha detto @Kimble, con Jackson 2, l’utilizzo della formattazione predefinita è molto semplice; semplicemente registra JodaModule sul tuo ObjectMapper .

 ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule()); 

Per la serializzazione / de-serializzazione personalizzata di DateTime , è necessario implementare il proprio StdScalarSerializer e StdScalarDeserializer ; è piuttosto contorto, ma comunque.

Ad esempio, ecco un serializzatore DateTime che utilizza ISODateFormat con il fuso orario UTC:

 public class DateTimeSerializer extends StdScalarSerializer { public DateTimeSerializer() { super(DateTime.class); } @Override public void serialize(DateTime dateTime, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException, JsonGenerationException { String dateTimeAsString = ISODateTimeFormat.withZoneUTC().print(dateTime); jsonGenerator.writeString(dateTimeAsString); } } 

E il deserializzatore corrispondente:

 public class DateTimeDesrializer extends StdScalarDeserializer { public DateTimeDesrializer() { super(DateTime.class); } @Override public DateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { try { JsonToken currentToken = jsonParser.getCurrentToken(); if (currentToken == JsonToken.VALUE_STRING) { String dateTimeAsString = jsonParser.getText().trim(); return ISODateTimeFormat.withZoneUTC().parseDateTime(dateTimeAsString); } } finally { throw deserializationContext.mappingException(getValueClass()); } } 

Quindi legali insieme a un modulo:

 public class DateTimeModule extends SimpleModule { public DateTimeModule() { super(); addSerializer(DateTime.class, new DateTimeSerializer()); addDeserializer(DateTime.class, new DateTimeDeserializer()); } } 

Quindi registra il modulo sul tuo ObjectMapper :

 ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new DateTimeModule()); 

https://stackoverflow.com/a/10835114/1113510

Sebbene sia ansible inserire un’annotazione per ogni campo data, è preferibile eseguire una configurazione globale per il proprio strumento di mapping degli oggetti. Se usi jackson puoi configurare la tua molla come segue:

    

Per CustomObjectMapper:

 public class CustomObjectMapper extends ObjectMapper { public CustomObjectMapper() { super(); configure(Feature.WRITE_DATES_AS_TIMESTAMPS, false); setDateFormat(new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'ZZZ (z)")); } } 

Ovviamente, SimpleDateFormat può utilizzare qualsiasi formato necessario.

la soluzione facile

Ho riscontrato problemi simili e la mia soluzione è molto chiara rispetto a quella sopra riportata.

Ho semplicemente usato il pattern nell’annotazione @JSonFormat

Fondamentalmente la mia class ha un campo DateTime , quindi metto un’annotazione attorno al getter:

 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") public DateTime getDate() { return date; } 

Serializzo la class con ObjectMapper

  ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule()); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); ObjectWriter ow = mapper.writer(); try { String logStr = ow.writeValueAsString(log); outLogger.info(logStr); } catch (IOException e) { logger.warn("JSON maping exception", e); } 

Usiamo Jackson 2.5.4

Nel frattempo, Jackson registra automaticamente il modulo Joda quando JodaModule è in classpath. Ho appena aggiunto Jackson-datatype-joda a Maven e ha funzionato all’istante.

  com.fasterxml.jackson.datatype jackson-datatype-joda 2.8.7  

Uscita JSON:

 {"created" : "2017-03-28T05:59:27.258Z"} 

Sembra che per Jackson 1.9.12 non ci sia alcuna possibilità di default, a causa di:

 public final static class DateTimeSerializer extends JodaSerializer { public DateTimeSerializer() { super(DateTime.class); } @Override public void serialize(DateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { if (provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)) { jgen.writeNumber(value.getMillis()); } else { jgen.writeString(value.toString()); } } @Override public JsonNode getSchema(SerializerProvider provider, java.lang.reflect.Type typeHint) { return createSchemaNode(provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS) ? "number" : "string", true); } } 

Questa class serializza i dati utilizzando il metodo toString () di Joda DateTime.

L’approccio proposto da Rusty Kuntz funziona perfettamente per il mio caso.

Per quelli con Spring Boot devi aggiungere il modulo al tuo contesto e verrà aggiunto alla tua configurazione in questo modo.

 @Bean public Module jodaTimeModule() { return new JodaModule(); } 

E se vuoi usare il nuovo modulo temporale java8 jsr-310.

 @Bean public Module jodaTimeModule() { return new JavaTimeModule(); } 

Sto usando Java 8 e questo ha funzionato per me:

aggiungi la dipendenza su pom.xml
com.fasterxml.jackson.datatype jackson-datatype-jsr310 2.4.0

e aggiungi JodaModule sul tuo ObjectMapper
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule());