json - 如何使用 JsonFormat 反序列化 Jackson Json NULL 字符串

标签 json string date null jackson

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

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

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

但是,如果 JSON 字符串值为空,我会收到以下异常。
你能告诉我如何解决这个问题吗?我尝试了一些选项,但它们都是用于序列化的。
ObjectMapper objectMapper = new ObjectMapper();   
objectMapper.setSerializationInclusion(Include.NON_NULL); 
objectMapper.setSerializationInclusion(Include.NON_EMPTY);

异常(exception) :

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)



谢谢
- 阿图尔

最佳答案

您的问题不是在 JSON 中传递了空值。问题在于 JSON 包含一个值为 "NULL" 的字符串。 .

因此,为了解决这个问题,有许多可用的方法。我认为以下两个将适用于这种情况。

备选方案 1:修复 JSON

第一个选择是修复 JSON,使其不包含字符串值 "NULL"而是包含值 null (未引用)或干脆跳过它。

想象一下以下 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值(value)观工作:
@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"无法解析为日期:
@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"

如果无法修复 JSON(如备选方案 1 中所述),您可以提供自己的转换器。

像这样设置你的 pojo:
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);
        }
    }
}

那么,你应该一切都准备好了。以下测试通过:
@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。

关于json - 如何使用 JsonFormat 反序列化 Jackson Json NULL 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28123887/

相关文章:

java - java中带有类型属性的JSON到XML

json - 在 Purescript 中的 AST 中输入信息

php - 如何用\"替换引号

java - Joda-Time DateTime 更改时区?

c# - 如何从 Windows 窗体 DateTimePicker 控件复制日期值?

c# - 反序列化客户端 AJAX JSON 日期

json - 当值为整数时,无法将小数部分显示为 .0

javascript - JSON Get请求使用JQuery(跨域)

c# 如何转义具有不同字母的目录路径?

java - 如何替换字符串中的最后一个单词