简体   繁体   中英

Jackson custom serializer with null values to be suppressed

I have a custom serializer to treat String with blank values as null and also to trim trailing blank spaces. Follwoing is the code for the same. -

public class StringSerializer extends JsonSerializer<String> {

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        String finalValue = null;
        if (value != null) {
            finalValue = value.trim();
            if (finalValue.isEmpty()) {
                finalValue = null;
            }
        }
        gen.writeObject(finalValue);

    }

}

In the main bean definition, the attribute definition is as follows -

public class SampleBean {
    private Long id;

    @JsonSerialize(using = StringSerializer.class)
    @JsonInclude(Include.NON_NULL)
    private String attribute1;

    @JsonSerialize(using = StringSerializer.class)
    @JsonInclude(Include.NON_NULL)
    private String attribute2;

    //Getters and setters
}

In the cases where the custom serializer kicks in, the not null values aren't ignored.

For example:

SampleBean bean = new SampleBean();
bean.setId(1L);
bean.setAttribtute1("abc");
bean.setAttribtute2(" ");
new ObjectMapper().writeValueAsString(bean);

The output of writeValueAsString: {"id": 1, "attribute1": "abc", "attribute2": null}

Expected output since i have @JsonInclude(Include.NON_NULL) in attribute 2, is as below. {"id": 1, "attribute1": "abc"}

Is there anyway to achieve this?

Try NON_EMPTY which should take care of empty and null string.

@JsonSerialize(using = 
StringSerializer.class)
@JsonInclude(Include.NON_EMPTY)

If this does not meet your requirement, look here to create a Custom filter and then use it in the valueFilter

https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html

I had exactly the same problem as you. It is true that JsonInclude.Include.NON_EMPTY and JsonInclude.Include.NON_NULL stops working with a custom Serializer.

I ended up creating a custom filter and used it together with the custom serializer.

Note that the example in the link https://www.logicbig.com/tutorials/misc/jackson/json-include-customized.html is wrong. In the equals() method, you should return true if you DON'T want to include the field, and return false if you want to include the field in the serialized output. This is the opposite of the example.

Some sample code:

/**
 * Custom Jackson Filter used for @JsonInclude. When the keywords string is empty don't include keywords in the
 * JSON serialization.
 */
public class KeywordsIncludeFilter {

    @Override
    public boolean equals(Object obj) {
        if(obj == null) return true;
        if(obj instanceof String && "".equals((String) obj)) return true;
        return false;
    }
}

Try adding the following to your StringSerializer :

@Override
public boolean isEmpty(SerializerProvider provider, String value) {
    if (value != null) {
        String finalValue = value.trim();
        if (finalValue.isEmpty()) {
            return true;
        }
    }

    return false;
}

Then add the "non empty" annotation to the field in question, eg:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String attribute2;

This sets the suppressible value to be "non empty" which you can then define via the isEmpty() override.

You are setting your value to a space instead of a null.

bean.setAttribtute2(" ");

Try it with a null.

bean.setAttribtute2(null);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM