I'm trying to serialize the Java object with hashmap into json string using jackson object mapper.
Below is the class definition of 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;
}
}
}
Below is the the sample test case -
@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);
}
I used
mapper.setDefaultPropertyInclusion(
JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL));`
by using the answer provided in stack overflow question.
I'm expecting the result as {"expected":true} but somehow the key with null value is included in the result.
How can I fix this issue?
Note:
When you put @JsonInclude on a field, that means if the field (not the element of fields) is null then it will be ignored from conversion.
@JsonInclude on additionalProperties that means, if additionalProperties(itself) is null then it will be ignored from conversion.so
@JsonIncludeonly checksadditionalPropertiesitself for null value, not its elements.
Example: Assume that you have an Ext object with additionalProperties=null, when you want to serialize it, the additionalProperties is ignored because it is null.
additionalProperties map contain null and Jackson doesn't ignore them.Solution 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
And also you can get Ext object from the generated string. in this case, your object has a filtered additionalProperties (does not have any element with null key or null value)
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());
}
Solution 2
You can write a custom serializer.
This link might be useful for this purpose
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With