如何将Joda DateTime与Jackson JSON处理器序列化?
我如何让jackson根据一个简单的模式(如“dd-MM-yyyy”)序列化我的Joda DateTime对象?
我试过了:
@JsonSerialize(using=DateTimeSerializer.class) private final DateTime date;
我也试过:
ObjectMapper mapper = new ObjectMapper() .getSerializationConfig() .setDateFormat(df);
谢谢!
Jackson 2.0和Joda模块已经变得非常容易。
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule());
Maven依赖:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> <version>2.1.1</version> </dependency>
代码和文档: https : //github.com/FasterXML/jackson-datatype-joda
二进制文件: http : //repo1.maven.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-joda/
在你映射的对象中:
@JsonSerialize(using = CustomDateSerializer.class) public DateTime getDate() { ... }
在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)); } }
正如@Kimble所说的,用Jackson 2,使用默认格式是很容易的; 只需在你的ObjectMapper
上注册JodaModule
即可。
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule());
对于DateTime
自定义序列化/反序列化,您需要实现自己的StdScalarSerializer
和StdScalarDeserializer
; 这是相当复杂的,但无论如何。
例如,下面是一个使用ISODateFormat
和UTC时区的DateTime
序列化程序:
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); } }
和相应的反序列化器:
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()); } }
然后用模块把它们连在一起:
public class DateTimeModule extends SimpleModule { public DateTimeModule() { super(); addSerializer(DateTime.class, new DateTimeSerializer()); addDeserializer(DateTime.class, new DateTimeDeserializer()); } }
然后在你的ObjectMapper
上注册模块:
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new DateTimeModule());
https://stackoverflow.com/a/10835114/1113510
尽pipe可以为每个date字段添加注释,但最好为对象映射器进行全局configuration。 如果你使用jackson,你可以configuration你的弹簧如下:
<bean id="jacksonObjectMapper" class="com.company.CustomObjectMapper" /> <bean id="jacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig" factory-bean="jacksonObjectMapper" factory-method="getSerializationConfig" > </bean>
对于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)")); } }
当然,SimpleDateFormat可以使用任何你需要的格式。
简单的解决scheme
我遇到了类似的问题,我的解决scheme比上面的要清楚得多。
我只是使用 @JSonFormat
注释中 的模式
基本上我的类有一个DateTime
字段,所以我在getter周围添加了一个注释:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") public DateTime getDate() { return date; }
我用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); }
我们使用jackson2.5.4
同时,当JodaModule处于classpath中时,Jackson会自动注册Joda模块。 我只是将jackson数据types乔达添加到Maven,它立即工作。
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> <version>2.8.7</version> </dependency>
JSON输出:
{"created" : "2017-03-28T05:59:27.258Z"}
jackson1.9.12似乎没有这样的可能性,因为:
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); } }
这个类使用Joda DateTime的toString()方法序列化数据。
Rusty Kuntz提出的方法适用于我的案例。
对于那些使用Spring Boot的人来说,你必须将模块添加到你的上下文中,并将它添加到你的configuration中。
@Bean public Module jodaTimeModule() { return new JodaModule(); }
如果你想使用新的java8时间模块jsr-310。
@Bean public Module jodaTimeModule() { return new JavaTimeModule(); }
我正在使用Java 8,这对我工作:
添加对pom.xml的依赖关系
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.4.0</version> </dependency>
并在你的ObjectMapper上添加JodaModule
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule());