Jackson's serialization and deserialization [@JsonValue and @JsonCreator annotations]

Jackson serialization

@JsonValueannotation

@JsonValueIt can be used on the get method or attribute field. Only one can be used for a class. When annotated with @JsonValue, only the value of this field will be returned during serialization, not the attribute key-value pair of this class.

Teacher.class

package org.zpli.springdemo.bean;

import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
import lombok.Setter;

/**
 * created at 2021/6/3 3:38 下午
 *
 * @author somnuszpli
 */
@Setter
@Getter
public class Teacher {
    
    

    // @JsonValue
    String name;

    int age;
    
    String address;

}

Test Methods:

@Test
public void test2() throws JsonProcessingException {
    
    
    ObjectMapper mapper = new ObjectMapper();

    Teacher teacher = new Teacher();
    teacher.setName("somnuszpli");
    teacher.setAge(24);
    teacher.setAddress("China");

    String teacherStr = mapper.writeValueAsString(teacher);
    System.out.println(teacherStr);
}

Output result:

{
    
    "name":"somnuszpli","age":24,"address":"China"}

@JsonValueAdd annotations to the name attribute of the Teacher class

package org.zpli.springdemo.bean;

import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
import lombok.Setter;

/**
 * created at 2021/6/3 3:38 下午
 *
 * @author somnuszpli
 */
@Setter
@Getter
public class Teacher {
    
    

    @JsonValue
    String name;

    int age;
    
    String address;

}

Run the test method, the output is:

"somnuszpli"

Jackson deserialization

1. What does the Jackson deserialization process do?

For Jackson's JSON data format, the deserialization process is to deserialize the JSON string into a java object .

ObjectMapper mapper = new ObjectMapper();

//将JSON字符串反序列化为java对象
String jsonInString = "{\"name\":\"乔丹\",\"age\":45,\"hobbies\":[\"高尔夫球\",\"棒球\"]}";
PlayerStar jordan = mapper.readValue(jsonInString, PlayerStar.class);

System.out.println(jordan);

By default, what functions does Jackson call during the deserialization process, let me introduce to you

  • First call the no-argument constructor of the deserialized target class PlayerStar to construct a java object
  • Then call the set method of the member variables of the class to assign values ​​to each member variable of the object.

So by default, if a Java class uses Jackson for deserialization, it must have a public no-argument constructor (if it is not written in java, it will exist by default), and it must have a set method for member variables.

2. @JsonCreatorNotes

By default, Jackson's deserialization process is as described above. By default, the no-argument constructor of the class is selected to create a class object and use the setter method to assign values ​​to the properties. When there is no no-argument constructor, an error will be reported. In addition, we can also use @JsonCreatorannotations to customize the deserialization process. In our custom deserialization function, we have more flexibility and can complete more non-prescribed actions . @JsonProperty needs to be added in front of the parameters using @JsonCreatorannotations, otherwise an error will be reported. There are two custom deserialization channels:

  • @JsonCreatorAnnotations are added to the constructor
  • @JsonCreatorAnnotations are added to factory static methods

After the annotation is used @JsonCreator, the method marked with the annotation will be used to construct the deserialized object, and the default deserialization process using the no-argument constructor and set method will be invalid.

2.1. @JsonCreatorAnnotations are added to the construction method

The JSON string corresponding to the PlayerStar is jsonInString in the first section. In the constructor function below, which attribute values ​​do you want to assign to the member variables of the java object, you can use it @JsonProperty("salary")to define it.

package org.zpli.springdemo.bean;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * created at 2021/6/3 3:14 下午
 *
 * @author somnuszpli
 */
public class PlayerStar {
    
    

    private String name;
    private Integer age;
    private String[] hobbies;               // 业余爱好,数组
    private List<String> friends;           // 朋友
    private Map<String, BigDecimal> salary; // 年收入 Map

    //这段是我们的核心代码,使用JsonCreator注解说明该方法是反序列化构造方法。
    @JsonCreator
    public PlayerStar(@JsonProperty("name") String name,
            @JsonProperty("age") Integer age,
            @JsonProperty("hobbies") String[] hobbies,
            @JsonProperty("friends") List<String> friends,
            @JsonProperty("salary") Map<String, BigDecimal> salary) {
    
    
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
        this.friends = friends;
        this.salary = salary;
    }

    @Override
    public String toString() {
    
    
        return "PlayerStar{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", hobbies=" + Arrays.toString(hobbies) +
                ", friends=" + friends +
                ", salary=" + salary +
                '}';
    }
}

We use the deserialization code in the first section to deserialize jsonInString to construct the PlayerStar object, and the console output is as follows (the object's toString() method output):

PlayerStar{
    
    name='乔丹', age=45, hobbies=[高尔夫球, 棒球], friends=null, salary=null}

Setting a breakpoint in @JsonCreatorthe marked construction method also proves that this method is used during the deserialization construction of the java object.

2.2. @JsonCreatorAnnotations are added to factory static methods

In addition to adding @JsonCreatorto the construction method, you can also use the static factory function to deserialize and construct java objects. The method of use is as follows:

package org.zpli.springdemo.bean;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * created at 2021/6/3 3:14 下午
 *
 * @author somnuszpli
 */
public class PlayerStar {
    
    

    private String name;
    private Integer age;
    private String[] hobbies;               // 业余爱好,数组
    private List<String> friends;           // 朋友
    private Map<String, BigDecimal> salary; // 年收入 Map

    @JsonCreator
    public static PlayerStar createPlayer(@JsonProperty("name") String name,
            @JsonProperty("age") Integer age,
            @JsonProperty("hobbies") String[] hobbies,
            @JsonProperty("friends") List<String> friends,
            @JsonProperty("salary") Map<String, BigDecimal> salary) {
    
    
        PlayerStar player = new PlayerStar();  //new 一个java对象
        player.name = name;    //赋值
        player.age = age;
        player.hobbies = hobbies;
        player.friends = friends;
        player.salary = salary;
        return player;
    }

    @Override
    public String toString() {
    
    
        return "PlayerStar{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", hobbies=" + Arrays.toString(hobbies) +
                ", friends=" + friends +
                ", salary=" + salary +
                '}';
    }
}

Adding @JsonCreatorannotations to factory static methods can achieve the same deserialization effect.

3. @ConstructorPropertiesNotes

@ConstructorPropertiesThe role of the annotation @JsonCreatoris the same as that of the annotation, but it can only be added to the construction method as a deserialization function. But its syntax is more concise, and it is more convenient to use, without @JsonPropertyannotations. It also provides flexibility, we can do more non-prescribed operations on the object during the deserialization process of the construction method.

package org.zpli.springdemo.bean;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.beans.ConstructorProperties;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * created at 2021/6/3 3:14 下午
 *
 * @author somnuszpli
 */
public class PlayerStar {
    
    

    private String name;
    private Integer age;
    private String[] hobbies;               // 业余爱好,数组
    private List<String> friends;           // 朋友
    private Map<String, BigDecimal> salary; // 年收入 Map

    @ConstructorProperties({
    
    "name", "age","hobbies", "friends","salary"})
    public PlayerStar(String name,
            Integer age,
            String[] hobbies,
            List<String> friends,
            Map<String, BigDecimal> salary) {
    
    
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
        this.friends = friends;
        this.salary = salary;
    }

    @Override
    public String toString() {
    
    
        return "PlayerStar{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", hobbies=" + Arrays.toString(hobbies) +
                ", friends=" + friends +
                ", salary=" + salary +
                '}';
    }
}

Adding @ConstructorPropertiesannotations to the construction method can achieve the same deserialization effect.

Guess you like

Origin blog.csdn.net/ToBeMaybe_/article/details/117525334