serialize pattern jsonformat example java json jodatime jackson

java - pattern - ¿Cómo serializar Joda DateTime con el procesador Jackson JSON?



send date json java (9)

¿Cómo hago para que Jackson serialice mi objeto Joda DateTime según un patrón simple (como "dd-MM-aaaa")?

He intentado:

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

También lo intenté:

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

¡Gracias!


la solución fácil

He encontrado un problema similar y mi solución es mucho más clara que la anterior.

Simplemente utilicé el patrón en la anotación @JSonFormat

Básicamente, mi clase tiene un campo DateTime , así que puse una anotación alrededor del getter:

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

Serializo la clase 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); }

Usamos Jackson 2.5.4


Como dijo @Kimble, con Jackson 2, usar el formato predeterminado es muy fácil; simplemente registre JodaModule en su ObjectMapper .

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

Para la serialización / StdScalarSerializer personalizada de DateTime , debe implementar su propio StdScalarSerializer y StdScalarDeserializer ; es bastante intrincado, pero de todos modos.

Por ejemplo, aquí hay un serializador DateTime que usa el ISODateFormat con la zona horaria UTC:

public class DateTimeSerializer extends StdScalarSerializer<DateTime> { 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); } }

Y el deserializador correspondiente:

public class DateTimeDesrializer extends StdScalarDeserializer<DateTime> { 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()); } }

Luego une esto con un módulo:

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

Luego registre el módulo en su ObjectMapper :

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


En el objeto que está mapeando:

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

En CustomDateSerializer:

public class CustomDateSerializer extends JsonSerializer<DateTime> { 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)); } }



Estoy usando Java 8 y esto funcionó para mí:

agregue la dependencia en pom.xml
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.4.0</version> </dependency>

y agrega JodaModule en tu ObjectMapper
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule());


Mientras tanto, Jackson registra el módulo Joda automáticamente cuando el JodaModule está en classpath. Acabo de agregar jackson-datatype-joda a Maven y funcionó al instante.

<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> <version>2.8.7</version> </dependency>

Salida JSON:

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


Para aquellos con Spring Boot, tienes que agregar el módulo a tu contexto y se agregará a tu configuración de esta manera.

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

Y si quiere usar el nuevo módulo de tiempo java8 jsr-310.

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


Parece que para Jackson 1.9.12 no existe tal posibilidad por defecto, debido a:

public final static class DateTimeSerializer extends JodaSerializer<DateTime> { 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); } }

Esta clase serializa datos usando el método toString () de Joda DateTime.

El enfoque propuesto por Rusty Kuntz funciona perfecto para mi caso.


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

Aunque puede poner una anotación para cada campo de fecha, es mejor hacer una configuración global para su asignador de objetos. Si usa jackson, puede configurar su muelle de la siguiente manera:

<bean id="jacksonObjectMapper" class="com.company.CustomObjectMapper" /> <bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig" factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" > </bean>

Para 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)")); } }

Por supuesto, SimpleDateFormat puede usar cualquier formato que necesite.