如何在从JSON反序列化过程中忽略空值属性

7

我正在尝试将一个JSON字符串反序列化为ConcurrentHashMap对象,但是由于我的JSON包含空值属性,所以我遇到了错误,而ConcurrentHashMap不接受空值。这是代码片段:

ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(jsonString, ConcurrentHashMap.class);

在反序列化期间是否有忽略具有空值的属性的方法?我知道我们可以在序列化期间忽略这些属性:

mapper.setSerializationInclusion(JsonInclude.NON_NULL);

那么反序列化过程呢?


不幸的是,这篇文章只涉及在序列化期间抑制属性,但我对相反的过程很感兴趣:在反序列化期间抑制属性。 - Radu Dumbrăveanu
我认为最好的方法是在创建json的过程中排除NULL值。通过这种方式,您将完全不必关心它。 - Anastasios Vlasopoulos
2个回答

3
可能有更好的方法,但是一个解决方法是:

可能有更好的方法,但是一个解决方法是:

Map<String, Object> map = mapper.readValue(jsonString, HashMap.class);
map.values().removeIf(o -> o == null);
return new ConcurrentHashMap<> (map);

我必须使用ConcurrentHashMap,因为Sonar的缘故。答案是完美的,但我不能使用Map,只能使用ConcurrentMap。 - Radu Dumbrăveanu
@RaduDumbrăveanu 从功能上讲没有区别 - 直到你返回之前,你的映射对外部代码是不可访问的,因此在反序列化时它是否并发是无关紧要的...除非你找到更好的方法,否则我会使用那个解决方案,并告诉Sonar忽略这个问题。 - assylias

1
以下技巧对我很有用:

ObjectMapper mapper = new ObjectMapper();

String jsonString = "{\"key1\": 1, \"key2\": null, \"key3\": 3}";

ConcurrentHashMap<String, Object> map = mapper.readValue(jsonString, new ConcurrentHashMap<String, Object>() {
    @Override
    public Object put(String key, Object value) {
        return value != null ? super.put(key, value) : null;
    }
}.getClass());

System.out.println(map); // {key1=1, key3=3}

这个想法很简单,就是重写ConcurrentHashMap.put()方法,使它忽略要添加到映射中的null值。
你可以创建一个扩展自ConcurrentHashMap的类,而不是使用匿名内部类:
public class NullValuesIgnorerConcurrentHashMap<K, V>
    extends ConcurrentHashMap<K, V> {

    @Override
    public V put(K key, V value) {
        return value != null ? super.put(key, value) : null;
    }
}

然后您将使用该类将其反序列化为 ConcurrentHashMap

ConcurrentHashMap<String, Object> map = 
    mapper.readValue(jsonString, NullValuesIgnorerConcurrentHashMap.class);

System.out.println(map); // {key1=1, key3=3}

采用这种方法,当给定一个null值时,在put()中返回的映射永远不会抛出NullPointerException

我尝试了你的解决方案,但对我没有用。我需要使用mapper.readValue(jsonString, new TypeReference<Map<String, Object>>() { });从JSON数据创建一个映射。 - theShadow89
@theShadow89 也许你可以使用 mapper.readValue(jsonString, new TypeReference<NullValuesIgnorerConcurrentHashMap<String, Object>>() { },因为 NullValuesIgnorerConcurrentHashMap 类型是泛型的。 - fps

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接