Jackson ObjectMapper setSerializationInclusion() not working

13,142

Do not change ObjectMappers settings while using it. Once mapper has been in use not all settings take effect, because of caching of serializers and deserializers.

Configure an instance once and do not change settings after first use. It is done this way for thread-safety and performance.

http://wiki.fasterxml.com/JacksonFAQThreadSafety http://wiki.fasterxml.com/JacksonBestPracticesPerformance

Share:
13,142
Duncan
Author by

Duncan

Updated on June 08, 2022

Comments

  • Duncan
    Duncan almost 2 years

    I'm just getting familiar with Jackson binding. However, when I'm testing setSerializationInclusion(JsonInclude.Include.NON_NULL), I found that it's not working sometimes.

    Here is my code

    package com.blithe.main;
    
    import com.blithe.model.Student;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonInclude.Include;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    public class Jackson_2_NullValue {
        public static void main(String[] args) throws JsonProcessingException {
    
            ObjectMapper mapper = new ObjectMapper();
    
    
            Student s = new Student();
            String stundetString = mapper.writeValueAsString(s);
            System.out.println(stundetString);
    
    
            // exclude null fields
            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    
            s.setName("ss");
            stundetString = mapper.writeValueAsString(s);
            System.out.println(stundetString);
        }
    }
    

    and the POJO

    package com.blithe.model;
    
    import java.util.Date;
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonInclude.Include;
    
    // @JsonIgnoreProperties(ignoreUnknown = true)
    // exclude null fields for the whole class
    // @JsonInclude(Include.NON_NULL)
    public class Student {
    
        // exclude the field whe it's empty ("")
        // @JsonInclude(value=Include.NON_EMPTY)
        private String name;
    
        private Integer age;
    
        private Date birth;
    
        // Jackson ignores it
        @JsonIgnore
        private String nickName;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Date getBirth() {
            return birth;
        }
    
        public void setBirth(Date birth) {
            this.birth = birth;
        }
    
        public String getNickName() {
            return nickName;
        }
    
        public void setNickName(String nickName) {
            this.nickName = nickName;
        }
    }
    

    the output is

    {"name":null,"age":null,"birth":null}
    {"name":"ss","age":null,"birth":null}
    

    The later one should be null-value excluded, but it doesn't.

    However, when I put my code this way.

    package com.blithe.main;
    
    import com.blithe.model.Student;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonInclude.Include;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    public class Jackson_2_NullValue {
        public static void main(String[] args) throws JsonProcessingException {
    
            ObjectMapper mapper = new ObjectMapper();
            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    
            Student s = new Student();
            String stundetString = mapper.writeValueAsString(s);
            System.out.println(stundetString);
    
    
            // exclude null fields
            // mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    
            s.setName("ss");
            stundetString = mapper.writeValueAsString(s);
            System.out.println(stundetString);
        }
    }
    

    It works with the output below

    {}
    {"name":"ss"}
    

    Is this normal or just some kind of bug? Do I miss anything? The only maven dependency is jackson-databind 2.7.4. Any discussion is welcomed. Thanks!