Jackson learning five: JsonInclude annotation

Welcome to my GitHub

https://github.com/zq2599/blog_demos
content: classification summary of all original articles and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;

Series articles summary

Overview of this article

  1. This article is the fifth in the "Jackson Learning" series to familiarize yourself with a commonly used annotation JsonInclude . This annotation is only useful for serialization operations and is used to control whether methods, attributes, etc. should be serialized;
  2. The reason why a separate article is used to write JsonInclude annotations is because there are many kinds of annotation values, each of which has different effects. The best learning method is to actually code;
  3. First, make a brief introduction to all the values ​​of annotations:
ALWAYS // 默认策略,任何情况都执行序列化
NON_NULL // 非空
NON_ABSENT // null的不会序列化,但如果类型是AtomicReference,依然会被序列化
NON_EMPTY // null、集合数组等没有内容、空字符串等,都不会被序列化
NON_DEFAULT // 如果字段是默认值,就不会被序列化
CUSTOM // 此时要指定valueFilter属性,该属性对应一个类,用来自定义判断被JsonInclude修饰的字段是否序列化
USE_DEFAULTS // 当JsonInclude在类和属性上都有时,优先使用属性上的注解,此时如果在序列化的get方法上使用了JsonInclude,并设置为USE_DEFAULTS,就会使用类注解的设置  

Source download

  1. If you don't want to code, you can download all the source code on GitHub. The address and link information are shown in the following table (https://github.com/zq2599/blog_demos):
name link Remarks
Project homepage https://github.com/zq2599/blog_demos The project's homepage on GitHub
git warehouse address (https) https://github.com/zq2599/blog_demos.git The warehouse address of the project source code, https protocol
git warehouse address (ssh) [email protected]:zq2599/blog_demos.git The warehouse address of the source code of the project, ssh protocol
  1. There are multiple folders in this git project. The application of this chapter is under the jacksondemo folder, as shown in the red box below:
    Insert picture description here

  2. jacksondemo is a project with a parent-child structure. The code for this article is in the annotation sub-project, under the package jsoninclude , as shown below:
    Insert picture description here

  • Next, learn the effects of these attributes one by one;

ALWAYS

ALWAYS means all serialization, as shown below, both null and empty strings will be serialized:
Insert picture description here

NON_NULL

NON_NULL is easy to understand, that is, the value of null is not serialized:
Insert picture description here

NON_ABSENT

  1. NON_ABSENT is slightly more complicated. When the instantiated object has a member variable of type Optional or AtomicReference , if the instance referenced by Optional is empty, use NON_ABSENT to make the field not serialized;
  2. Optional is a feature of Java used to handle null pointers gracefully. This article will not explain too much. Please refer to the relevant documents yourself;
  3. In order for Jackson to support the Optional feature, two things must be done. The first is to add the following dependencies in pom.xml :
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
    <version>2.11.0</version>
</dependency>
  1. Followed by the following settings in the code:
mapper.registerModule(new Jdk8Module());
  1. Let's first take a look at Jackson's handling of Optional and AtomicReference when set to NON_NULL . In the following code, the references of Optional and AtomicReference are all empty, but they are still serialized:
    Insert picture description here

  2. The code remains unchanged, try changing NON_NULL to NON_ABSENT , as shown in the figure below, it can be seen that field2 and field3 are not serialized:
    Insert picture description here
    Summary of the effect of NON_ABSENT:
    a. Fields that are null by themselves will not be serialized;
    b. Optional type fields, If the reference value is null, the field will not be serialized;
    c. AtomicReference type field, if the reference value is null, the field will not be serialized;

NON_EMPTY

NON_EMPTY is easy to understand, the following situations will not be serialized:

  1. null
  2. Empty string
  3. Empty collection
  4. Empty array
  5. Optional type, the reference is empty
  6. AtomicReference type, the reference is empty
  7. The demo code and results are as shown in the figure below. It can be seen that all the above scenes are not serialized:
    Insert picture description here

NON_DEFAULT

  1. After setting to NON_DEFAULT, the fields that keep the default value will not be serialized, as shown below:
    Insert picture description here

CUSTOM

  1. Compared with other types, CUSTOM is slightly more complicated, and this value should be used with the valueFilter attribute;
  2. As shown below, when the value of JsonInclude is equal to CUSTOM , the equals method of CustomFilter will be executed during serialization. The input parameter of this method is the value of field0 . If the equals method returns true, field0 will not be serialized . If the equals method Field0 will be serialized when false is returned
@JsonInclude(value = JsonInclude.Include.CUSTOM, 
                valueFilter = CustomFilter.class)
        private String field0;
  1. Take a look at the code of the CustomFilter class. As shown below, only the equals method is visible: null, non-string, and length greater than 2 all return true, which means that they will not be serialized in these three cases :
static class CustomFilter {
    
    
        @Override
        public boolean equals(Object obj) {
    
    
            // null,或者不是字符串就返回true,意味着不被序列化
            if(null==obj || !(obj instanceof String)) {
    
    
                return true;
            }

            // 长度大于2就返回true,意味着不被序列化
            return ((String) obj).length() > 2;
        }
    }
  1. The complete code and results are posted below, and you can see it at a glance:
    Insert picture description here
  • Again: the equals method of valueFilter returns true, which means that the field will not be serialized! ! !

USE_DEFAULTS

The usage of USE_DEFAULTS is also a bit convoluted, let's learn by comparison;

  1. The code is shown below. There are JsonInclude annotations on the class and member variables. When serializing field0, which annotation is effective? :
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    static class Test {
    
    

        @JsonInclude(JsonInclude.Include.NON_NULL)
        private List<String> field0;

        public List<String> getField0() {
    
     return field0; }

        public void setField0(List<String> field0) {
    
     this.field0 = field0; }
    }
  1. Set field0 to an empty collection and run the code to try. If the annotation on the class is valid, then field0 will not be serialized (NON_EMPTY will filter out the empty collection), if the annotation on the member variable is valid, field0 will be serialized (NON_NULL only filters null, empty collection is not null), the execution result is as shown in the figure below, it can be seen that the annotation on the member variable is effective:
    Insert picture description here

  2. Next, keep the above code unchanged, only add the JsonInclude annotation to the getField0 method , the value is USE_DEFAULTS , so that in the serialization process, when the getField0 method is called, the value of JsonInclude is annotated with the class, that is, NON_EMPTY:

@JsonInclude(JsonInclude.Include.USE_DEFAULTS)
public List<String> getField0() {
    
     
	return field0; 
}
  1. Execute the modified code, as shown in the figure below, the annotation on the member variable field0 used at this time is not effective, but the class annotation is effective, resulting in the empty collection not being serialized:
    Insert picture description here
    Summary USE_DEFAULTS functions as follows:
    a. Class annotation When it exists at the same time as the member variable annotation, the member variable annotation shall prevail;
    b. If the corresponding get method also uses the JsonInclude annotation and the value is USE_DEFAULTS, the class annotation shall prevail;

At this point, the learning and actual combat of JsonInclude annotations are completed. I hope this article can provide you with reference to help you use annotations to specify more precise serialization filtering strategies;

Welcome to follow my public account: programmer Xin Chen

Insert picture description here

Guess you like

Origin blog.csdn.net/boling_cavalry/article/details/108412558