Jackson serialization
@JsonValue
annotation
@JsonValue
It 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"}
@JsonValue
Add 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. @JsonCreator
Notes
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 @JsonCreator
annotations 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 @JsonCreator
annotations, otherwise an error will be reported. There are two custom deserialization channels:
@JsonCreator
Annotations are added to the constructor@JsonCreator
Annotations 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. @JsonCreator
Annotations 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 @JsonCreator
the marked construction method also proves that this method is used during the deserialization construction of the java object.
2.2. @JsonCreator
Annotations are added to factory static methods
In addition to adding @JsonCreator
to 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 @JsonCreator
annotations to factory static methods can achieve the same deserialization effect.
3. @ConstructorProperties
Notes
@ConstructorProperties
The role of the annotation @JsonCreator
is 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 @JsonProperty
annotations. 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 @ConstructorProperties
annotations to the construction method can achieve the same deserialization effect.