了解如何在使用 jackson解析json 时反序列化多种日期格式。
Jackson handles serialization and deserialization of dates 默认使用 GMT,格林威治标准时间(时区缩写),用于所有日期处理,除非另有配置。如果您公开多个客户端发布到的休息服务,您可能希望灵活地支持多种日期格式。让我们通过编写自定义日期反序列化器来了解如何处理各种日期格式。
我们使用 simple archetype quick start 和导入的依赖项 jackson 和 apache commons lang 创建了一个 maven 项目。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
回顾一下,序列化和反序列化是与 json 相互转换的过程。例如,您可能有想要使用jackson将其转换为数组列表的 json 数组。或者您可以使用 gson 执行相同的转换。当用户发布到服务或我们通过读取文件来使用 json 时,我们将获取 json 并将其转换为 java 对象。读取日期时,我们希望将其解析为日期而不是字符串。
为此,我们将通过扩展 UntypedObjectDeserializer
创建一个自定义jackson解析器,如果需要绑定未知类型的内容,则使用解析器实现。我们将首先检查令牌是否为字符串,以及是否使用 apache commons 解析以多种格式传递的日期。如果抛出异常,我们将只使用上下文进行解析。
class CustomDateDeseralizer extends UntypedObjectDeserializer {
private static final long serialVersionUID = -2275951539867772400L;
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
if (jp.getCurrentTokenId() == JsonTokenId.ID_STRING) {
try {
return DateUtils.parseDate(jp.getText(), new String[] {
"MM/dd/yyyy", "yyyy.MM.dd G 'at' HH:mm:ss z" });
} catch (Exception e) {
return super.deserialize(jp, ctxt);
}
} else {
return super.deserialize(jp, ctxt);
}
}
}
注册反序列化器后,我们必须指示 ObjectMapper
。在 Jackson 1.7 中,引入了模块来扩展 jackson 功能,因此我们可以创建 SimpleModule
并注册我们的 CustomDateDeseralizer
类。
private ObjectMapper configureObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(Object.class, new CustomDateDeseralizer());
objectMapper.registerModule(simpleModule);
return objectMapper;
}
如果您使用的是 spring boot,它会自动为您配置一个 ObjectMapper
。要覆盖默认配置,只需创建一个名为 objectMapper 的 bean 并提供您的配置。它可能看起来像这样:
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
// register your module
return objectMapper;
}
创建一个带有字符串和两个日期的示例 json,我们将希望通过 ObjectMapper
运行它并验证它是否创建了 java.util.date 对象。在调用 objectMapper.readValue
时,我们将指定将 json 键和值放到 HashMap 中。然后遍历key,将输出键、值和值类类型。
{
"name": "Justin Musgrove",
"shortDateFormat": "03/05/2015",
"longDateFormat": "2001.07.04 AD at 12:08:56 PDT"
}
String objectAsJson = "{\"name\": \"Justin Musgrove\", \"shortDateFormat\": \"03/05/2015\",\"longDateFormat\": \"2001.07.04 AD at 12:08:56 PDT\"}";
@Test
public void deserializeDates() throws JsonParseException,
JsonMappingException, IOException {
ObjectMapper objectMapper = configureObjectMapper();
@SuppressWarnings("unchecked")
Map<Object, Object> jsonAsMap = objectMapper.readValue(objectAsJson,
HashMap.class);
for (Entry<Object, Object> entry : jsonAsMap.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
System.out.println(entry.getValue().getClass());
System.out.println("----");
}
}
name
Justin Musgrove
class java.lang.String
----
shortDateFormat
Thu Mar 05 00:00:00 CST 2015
class java.util.Date
----
longDateFormat
Wed Jul 04 14:08:56 CDT 2001
class java.util.Date
----
感谢阅读,祝您幸福每一天!
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : http://www.leveluplunch.com/java/tutorials/033-custom-jackson-date-deserializer/
内容来源于网络,如有侵权,请联系作者删除!