gpt4 book ai didi

java - Jackson - 在序列化 HashMap 对象时跳过具有空值的键

转载 作者:行者123 更新时间:2023-12-01 18:42:20 28 4
gpt4 key购买 nike

我正在尝试使用 Jackson 对象映射器将带有 hashmap 的 Java 对象序列化为 json 字符串。

下面是Ext的类定义 -

        import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({})
public class Ext implements Serializable {

@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap();
private static final long serialVersionUID = -4500317258794294335L;

public Ext() {
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

// ignore toString, equals and hascode

public static class ExtBuilder {
protected Ext instance;

public ExtBuilder() {
if (this.getClass().equals(Ext.ExtBuilder.class)) {
this.instance = new Ext();
}
}

public Ext build() {
Ext result = this.instance;
this.instance = null;
return result;
}

public Ext.ExtBuilder withAdditionalProperty(String name, Object value) {
this.instance.getAdditionalProperties().put(name, value);
return this;
}
}
}

下面是示例测试用例 -

    @Test
public void testNullObjectSerialization() throws Exception {

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
mapper.setDefaultPropertyInclusion(
JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL));

ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
mapper.writeValue(out, new Ext.ExtBuilder().withAdditionalProperty("unexpected", null).withAdditionalProperty("expected", true).build());
String result = new String(out.toByteArray());
Assert.assertEquals("{\"expected\":true}", result);
}

我用过

mapper.setDefaultPropertyInclusion(
JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL));`

通过使用堆栈溢出中提供的答案 question .

我期望结果为 {"expected":true} 但不知何故,具有 null 值的键包含在结果中。

如何解决这个问题?

注意:

  1. 代码位于 github here .
  2. 我使用的是 jacksersion 版本 2.9.8

最佳答案

当您将@JsonInclude放在字段上时,这意味着如果字段(不是字段的元素)null,那么它将在转换中被忽略。

  • 就您的情况而言,当您在 additionalProperties 上使用 @JsonInclude 时,这意味着,如果 additionalProperties(本身)为空,那么它将在转换中被忽略。

so @JsonInclude only checks additionalProperties itself for null value, not its elements.

<小时/>

示例:假设您有一个带有 additionalProperties=nullExt 对象,当您想要序列化它时,additionalProperties 会被忽略,因为它是

  • 但在您的场景中,additionalProperties 映射的元素包含null,并且 Jackson 不会忽略它们。
<小时/>

解决方案1

You can serialize additionalProperties map (itself) not the whole Ext object.

public static void main(String[] args) throws JsonProcessingException {

//Create Ext Object
Ext ext = new Ext.ExtBuilder().withAdditionalProperty("unexpected", null).withAdditionalProperty("expected", true).build();

//Config
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

//Conversion the additionalProperties map (ext.getAdditionalProperties())
String filterMap = mapper.writeValueAsString(ext.getAdditionalProperties());

//Result ({"expected":true})
System.out.println(filterMap);


}
}

Convert JSON to Ext Object

您还可以从生成的字符串中获取Ext对象。在这种情况下,您的对象有一个过滤的additionalProperties(没有任何带有空键或空值的元素)

public static void main(String[] args) throws JsonProcessingException {

//Create Ext Object
Ext ext = new Ext.ExtBuilder().withAdditionalProperty("unexpected", null).withAdditionalProperty("expected", true).build();

//Config
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

//Conversion the additionalProperties map (ext.getAdditionalProperties())
String filterMap = mapper.writeValueAsString(ext.getAdditionalProperties());

//Result ({"expected":true})
System.out.println(filterMap);

//Convert back JSON string to Ext object
Ext filterdExt = mapper.readValue(filterMap, Ext.class);

//Print AdditionalProperties of filterdExt ({"expected":true})
System.out.println(filterdExt.getAdditionalProperties());

}
<小时/>

解决方案2

您可以编写自定义序列化程序。

<强> This link 可能对此目的有用

关于java - Jackson - 在序列化 HashMap 对象时跳过具有空值的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59902926/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com