question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@JsonInclude(Include.NON_NULL) is not working while custom serializers are regiestered

See original GitHub issue

There is something wrong with way @JsonInclude annotations are handled. It seems like when custom serializers are attached to modules we register then @JsonInclude(Include.NON_NULL) or setSerializationIncludsion(Include.NON_EMPTY) means nothing.

My requirement is to not serialize keys for which values are null. I also want to trim string values to null (that’s why I created custom serializer which extends StdScalarSerializer).

Example input object of type let’s say MyClass:

- name: "nameOfObj1"
- producerName: "PROD CORP.     " 
- notes: "      " 

Expected output:

{
    "name" : "nameOfObj1",
    "producerName" : "PROD CORP."
}

I can’t get this working with Include.NON_NULL having my module with custom serializers added. Serializer itself works just fine and looks like this:

 public class MyCustomStringSerializer extends StdScalarSerializer<String> {


    protected MyCustomStringSerializer () {
        super(String.class);
    }

    @Override
    public void serialize(String value, JsonGenerator jgen,
            SerializerProvider provider) throws IOException,
            JsonGenerationException {
        String trimmedValue = StringUtils.trim(value);
        if(StringUtils.isEmpty(trimmedValue)) {
            jgen.writeNull();           
            }
        else {
            jgen.writeString(trimmedValue);
        }
    }
}

This is my object mapper where I register custom modules/serializers:

public class MyCustomObjectMapper extends ObjectMapper {

    private static final long serialVersionUID = 8125249677131844836L;

    public MyCustomObjectMapper() {
        registerModule(new MyModule());
        setSerializationInclusion(Include.NON_EMPTY);
    }

    class MyModule extends SimpleModule {

        private static final long serialVersionUID = 3012609212894483368L;

        public MyModule() {
            addSerializer(String.class, new MyCustomStringSerializer());
        }
    }
}

Using this approach I will get not exactly what I want:

{
    "name" : "nameOfObj1",
    "producerName" : "PROD CORP."
    "notes" : null
}

There is a workaround of course. I can use some kind of mapper which will take over the work MyCustomStringSerializer currently does. The output from this mapper would be an object having all String values trimmed to nulls. Then I don’t have to register any custom modules in ObjectMapper because all the work has been done. I can rely on @JsonInclude(Include.NON_NULL) annotation on serialized object class or I can set this setting globally with setSerializationIncludsion(Include.NON_EMPTY) in MyCustomOjbectMapper constructor. With such workaround I get what I want. How to achieve t with @JsonInclude annotation ?

I used NON_NULL and NOT_EMPTY interchangeably but I think for String values these annotations mean the same thing.

Jackson version: 2.5.1

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:16 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
cowtowncodercommented, Oct 2, 2020

@andrickd ok good. Just thought I’d mention. 😃

1reaction
cowtowncodercommented, Oct 1, 2020

@andrickd Ok sorry: for simple String it does not change the way value serializer works (except for @JsonFormat handling); this would be relevant mostly for structured type serializers (POJOs, Maps, Collections).

However: the whole inclusion filtering is handled by whatever calls these serializers. So if you delegate, yes, that serializer has to handle filtering out of values: delegate/child serializer must simply write out value when requested to do so. This is partly due to the common case of property value where in field name must be output by that “parent” serializer, so it has to decided for name/value pair, before delegating.

JsonGenerator.writeStringField() in particular simply outputs field name, name, and has no concept of anything going on at databind level. Maybe javadoc should be improved to make this clear.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JsonInclude(Include.NON_NULL) not working as expected
I tried @JsonSerialize(include = Inclusion.NON_NULL). intead of @JsonInclude(Include.NON_NULL). and it worked as expected.
Read more >
[Solved]-Do not include empty object to Jackson-Springboot
Without a custom serializer, jackson will include your object. Solution 1 : Replace new object with null person.setDetails(new PersonDetails());.
Read more >
Serialized Form (jackson-databind 2.7.0 API) - FasterXML
Property that contains value for which type information is included; null if value is a root value. Note that this value is not...
Read more >
Ignore Null Fields with Jackson - Baeldung
This quick tutorial is going to cover how to set up Jackson to ignore null fields when serializing a java class.
Read more >
Serialization and Deserialization Issues in Spring REST
Let's go over a few good practices for them. Configuring a Custom Jackson ObjectMapper. In Spring REST projects a custom implementation of ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found