如何使用JsonFormat将Jackson Json NULL字符串反序列化到日期 [英] How to deserialize Jackson Json NULL String to Date with JsonFormat

查看:3812
本文介绍了如何使用JsonFormat将Jackson Json NULL字符串反序列化到日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看了很多,但仍然无法得到答案,任何帮助是非常感谢!

I have looked a lot but still couldn't get the answer so far, any help is really appreciated!

我有一个简单的字符串日期字段映射,并尝试读取JSON字符串到Java对象。

I have a simple String to Date field mapping and try to read a JSON string to Java object.

@JsonInclude(value=Include.NON_EMPTY)
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd-MMM-yyyy", timezone="PST")
protected Date eolAnnounceDate;

但是如果JSON字符串值为空,我收到以下异常。你有人告诉我如何解决这个问题吗?我已经尝试了几个选项,但都是为了序列化。

However I am getting the following exception if the JSON string value is empty. Can you someone tell me how to get around this? I have tried a few options but they are all for serialization.

ObjectMapper objectMapper = new ObjectMapper();   
objectMapper.setSerializationInclusion(Include.NON_NULL); 
objectMapper.setSerializationInclusion(Include.NON_EMPTY);

异常:


java.lang.IllegalArgumentException:无法解析Date值'NULL'(格式:dd-MMM-yyyy):不可稀释日期:NULL
com.fasterxml.jackson.databind.deser.std.DateDeserializers $ DateBasedDeserializer._parseDate(DateDeserializers.java:180)
com.fasterxml.jackson.databind.deser.std.DateDeserializers $ DateDeserializer.deserialize( DateDeserializers.java:279)
com.fasterxml.jackson.databind.deser.std.DateDeserializers $ DateDeserializer.deserialize(DateDeserializers.java:260)
com.fasterxml.jackson.databind.deser.SettableBeanProperty。 deserialize(SettableBeanProperty.java:464)
com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98)
com.fasterxml.jackson.databind.deser.BeanDeserializer。 deserializeFromObject(BeanDeserializer.java:295)
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
com.fasterxml.jackson.databind.deser.std.CollectionDeserializer。 deserialize(CollectionDeserializer.java:230)
com.fasterxml.jackson.databind.deser.std.Col lectionDeserializer.deserialize(CollectionDeserializer.java:207)
com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
com.fasterxml.jackson.databind.deser。 SettableBeanProperty.deserialize(SettableBeanProperty.java:464)
com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98)
com.fasterxml.jackson.databind.deser。 BeanDeserializer.deserializeFromObject(BeanDeserializer.java:295)
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose( ObjectMapper.java:2888)
com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
com.cisco.cre.dao.impl.ElasticsearchDAOImpl.getListByIdsFilter(ElasticsearchDAOImpl.java: 94)

java.lang.IllegalArgumentException: Failed to parse Date value 'NULL' (format: "dd-MMM-yyyy"): Unparseable date: "NULL" com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateBasedDeserializer._parseDate(DateDeserializers.java:180) com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:279) com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:260) com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:464) com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98) com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:295) com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:230) com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:207) com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23) com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:464) com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98) com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:295) com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888) com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034) com.cisco.cre.dao.impl.ElasticsearchDAOImpl.getListByIdsFilter(ElasticsearchDAOImpl.java:94)

感谢
- Atul

Thanks - Atul

推荐答案

您的问题不是空值在JSON通过。问题是JSON包含一个值为$ code>NULL的字符串。

Your problem is not that a null value is passed in the JSON. The problem is that the JSON contains a string that has the value "NULL".

所以,为了解决这个问题有一些可用的方法。

So, in order to fix this there are a number of available approaches. I think that the following two will work for this case.

替代方案1:修复JSON

第一个替代方法是修复JSON,使其不包含字符串值NULL,而是包含值 null (不是引用),或者只是略过它。

The first alternative is to fix the JSON so that it does not contain the the string value "NULL" and instead contain the value null (not quoted) or simply skip it.

想像下面的POJO:

public class DatePojo {
    @JsonInclude(value= JsonInclude.Include.NON_EMPTY)
    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd-MMM-yyyy", timezone="PST")
    @JsonProperty("date")
    private Date date;
}

以下测试显示有效日期,空值和 null values work:

The following test shows that valid dates, empty values and null values work:

@Test
public void testJson() throws IOException {
    String jsonWithValidDate = "{\"date\":\"12-Jun-1982\"}";
    String jsonWithNoDate = "{}";
    String jsonWithNullDate = "{\"date\":null}";

    ObjectMapper mapper = new ObjectMapper();
    final DatePojo pojoWithValidDate = mapper.readValue(jsonWithValidDate, DatePojo.class);
    final DatePojo pojoWithNoDate = mapper.readValue(jsonWithNoDate, DatePojo.class);
    final DatePojo pojoWithNullDate = mapper.readValue(jsonWithNullDate, DatePojo.class);

    Assert.assertNotNull(pojoWithValidDate.date);
    Assert.assertNull(pojoWithNoDate.date);
    Assert.assertNull(pojoWithNullDate.date);
}

但是,如果传递值NULL 测试失败,因为NULL不能被解析为日期:

However, if you pass along the value "NULL" the test fails since "NULL" can not be parsed as a date:

@Test(expected = JsonMappingException.class)
public void testInvalidJson() throws IOException {
    String jsonWithNullString = "{\"date\":\"NULL\"}";

    ObjectMapper mapper = new ObjectMapper();
    mapper.readValue(jsonWithNullString, DatePojo.class); // Throws the exception
    Assert.fail();
}

替代方案2:提供自己的转换器来处理NULL

Alternative 2: provide your own converter that handles "NULL"

如果无法修复JSON(如替代1所述),您可以提供你自己的转换器。

If it is not possible to fix the JSON (as described in alternative 1) you can provide your own converter.

这样设置你的pojo:

Setup your pojo like this instead:

public class DatePojo {
    @JsonProperty("date")
    @JsonDeserialize(converter = MyDateConverter.class)
    private Date date;
}

并提供一个转换器:

public class MyDateConverter extends StdConverter<String, Date> {
    @Override
    public Date convert(final String value) {
        if (value == null || value.equals("NULL")) {
            return null;
        }
        try {
            return new SimpleDateFormat("dd-MMM-yyyy").parse(value);
        } catch (ParseException e) {
            throw new IllegalStateException("Unable to parse date", e);
        }
    }
}

然后,你应该是全部组。以下测试通过:

Then, you should be all set. The following test passes:

@Test
public void testJson() throws IOException {
    String jsonWithValidDate = "{\"date\":\"12-Jun-1982\"}";
    String jsonWithNoDate = "{}";
    String jsonWithNullDate = "{\"date\":null}";
    String jsonWithNullString = "{\"date\":\"NULL\"}"; // "NULL"

    ObjectMapper mapper = new ObjectMapper();
    final DatePojo pojoWithValidDate = mapper.readValue(jsonWithValidDate, DatePojo.class);
    final DatePojo pojoWithNoDate = mapper.readValue(jsonWithNoDate, DatePojo.class);
    final DatePojo pojoWithNullDate = mapper.readValue(jsonWithNullDate, DatePojo.class);
    final DatePojo pojoWithNullStr = mapper.readValue(jsonWithNullString, DatePojo.class); // Works

    Assert.assertNotNull(pojoWithValidDate.date);
    Assert.assertNull(pojoWithNoDate.date);
    Assert.assertNull(pojoWithNullDate.date);
    Assert.assertNull(pojoWithNullStr.date); // Works
}

IMO,最好的方法是使用替代1,更改JSON。

IMO, the best approach is to use alternative 1 where you simply change the JSON.

这篇关于如何使用JsonFormat将Jackson Json NULL字符串反序列化到日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆