REST Assured 系列汇总 之 REST Assured 39 - @JsonIgnore Annotation – Serialization 和 Deserialization 移除某些字段
前提条件:
因为我们用到 Jackson API, 所以确保导入 Jackson Databind 依赖包。
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.1</version>
</dependency>
POJO without JsonIgnore
一个 POJO 类中可能有多个字段,有时我们并不需要某些字段参与 serialization 和 deserialization 处理。
POJO 类中,可能有些属性是是通过其它属性获取的,例如:我们知道一个人的 first name 和 last name,那我们就可以知道这个人的 full name。如果我们知道一个人的 age,那么我们就知道这个人是否能选举权。出于类似这种需求,我们可以添加 getter 方法来获取这些属性的值,但是我们并不允许通过外面去设置这些值。
POJO without JsonIgnore
public class EmployeePojoWithoutJsonIgnore {
// private variables or data members of pojo class
private String firstName;
private String lastName;
private String gender;
private int age;
private double salary;
private boolean married;
private String fullName;
private boolean eligibleForVote;
// Getter and setter methods
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public boolean getMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
public String getFullName() {
return this.fullName;
}
public boolean getEligibleForVote() {
return this.eligibleForVote;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public void setEligibleForVote(boolean eligibleForVote) {
this.eligibleForVote = eligibleForVote;
}
}
序列化上面的 POJO 类:
@Test
public void serializationWithoutJsonIgnore() throws JsonProcessingException {
// Just create an object of Pojo class
EmployeePojoWithoutJsonIgnore employeePojoWithoutJsonIgnore = new EmployeePojoWithoutJsonIgnore();
employeePojoWithoutJsonIgnore.setFirstName("Amod");
employeePojoWithoutJsonIgnore.setLastName("Mahajan");
employeePojoWithoutJsonIgnore.setAge(29);
employeePojoWithoutJsonIgnore.setGender("Male");
employeePojoWithoutJsonIgnore.setSalary(12323.56);
employeePojoWithoutJsonIgnore.setMarried(false);
employeePojoWithoutJsonIgnore.setFullName("Animesh Prashant");
employeePojoWithoutJsonIgnore.setEligibleForVote(false);
// Converting a Java class object to a JSON payload as string
ObjectMapper objectMapper = new ObjectMapper();
String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeePojoWithoutJsonIgnore);
System.out.println("Serialization...");
System.out.println(employeeJson);
}
输出:
Serialization...
{
"firstName" : "Amod",
"lastName" : "Mahajan",
"gender" : "Male",
"age" : 29,
"salary" : 12323.56,
"married" : false,
"fullName" : "Animesh Prashant",
"eligibleForVote" : false
}
反序列化上面 POJO 类:
@Test
public void deserializationWithoutJsonIgnore() throws JsonMappingException, JsonProcessingException
{
String employeeString = "{\r\n" +
" \"firstName\" : \"Amod\",\r\n" +
" \"lastName\" : \"Mahajan\",\r\n" +
" \"gender\" : \"Male\",\r\n" +
" \"age\" : 29,\r\n" +
" \"salary\" : 12323.56,\r\n" +
" \"married\" : false,\r\n" +
" \"fullName\" : \"Amod Mahajan Gupta\",\r\n" +
" \"eligibleForVote\" : false\r\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
EmployeePojoWithoutJsonIgnore employeePojoWithoutJsonIgnore2 = objectMapper.readValue(employeeString, EmployeePojoWithoutJsonIgnore.class);
System.out.println("Deserialization...");
System.out.println("First name :- "+employeePojoWithoutJsonIgnore2.getFirstName());
System.out.println("Last name :- "+employeePojoWithoutJsonIgnore2.getLastName());
System.out.println("Age :- "+employeePojoWithoutJsonIgnore2.getAge());
System.out.println("Gender :- "+employeePojoWithoutJsonIgnore2.getGender());
System.out.println("Salary :- "+employeePojoWithoutJsonIgnore2.getSalary());
System.out.println("Married :- "+employeePojoWithoutJsonIgnore2.getMarried());
System.out.println("Eligible for vote :- "+employeePojoWithoutJsonIgnore2.getEligibleForVote());
System.out.println("Full name :- "+employeePojoWithoutJsonIgnore2.getFullName());
}
输出:
Deserialization...
First name :- Amod
Last name :- Mahajan
Age :- 29
Gender :- Male
Salary :- 12323.56
Married :- false
Eligible for vote :- false
Full name :- Amod Mahajan Gupta
从上面的输出可以看出,字段 “fullName” 和 “eligibleForVote” 设置的值是错误的,我们可能通过其它属性来计算它们的值。理论上来说,这些字段只需提供 getter 方法来实现快速访问。
完整的代码:
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class SerialiDeserialExampleWithoutJsonIgnore {
@Test
public void serializationWithoutJsonIgnore() throws JsonProcessingException {
// Just create an object of Pojo class
EmployeePojoWithoutJsonIgnore employeePojoWithoutJsonIgnore = new EmployeePojoWithoutJsonIgnore();
employeePojoWithoutJsonIgnore.setFirstName("Amod");
employeePojoWithoutJsonIgnore.setLastName("Mahajan");
employeePojoWithoutJsonIgnore.setAge(29);
employeePojoWithoutJsonIgnore.setGender("Male");
employeePojoWithoutJsonIgnore.setSalary(12323.56);
employeePojoWithoutJsonIgnore.setMarried(false);
employeePojoWithoutJsonIgnore.setFullName("Animesh Prashant");
employeePojoWithoutJsonIgnore.setEligibleForVote(false);
// Converting a Java class object to a JSON payload as string
ObjectMapper objectMapper = new ObjectMapper();
String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeePojoWithoutJsonIgnore);
System.out.println("Serialization...");
System.out.println(employeeJson);
}
@Test
public void deserializationWithoutJsonIgnore() throws JsonMappingException, JsonProcessingException
{
String employeeString = "{\r\n" +
" \"firstName\" : \"Amod\",\r\n" +
" \"lastName\" : \"Mahajan\",\r\n" +
" \"gender\" : \"Male\",\r\n" +
" \"age\" : 29,\r\n" +
" \"salary\" : 12323.56,\r\n" +
" \"married\" : false,\r\n" +
" \"fullName\" : \"Amod Mahajan Gupta\",\r\n" +
" \"eligibleForVote\" : false\r\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
EmployeePojoWithoutJsonIgnore employeePojoWithoutJsonIgnore2 = objectMapper.readValue(employeeString, EmployeePojoWithoutJsonIgnore.class);
System.out.println("Deserialization...");
System.out.println("First name :- "+employeePojoWithoutJsonIgnore2.getFirstName());
System.out.println("Last name :- "+employeePojoWithoutJsonIgnore2.getLastName());
System.out.println("Age :- "+employeePojoWithoutJsonIgnore2.getAge());
System.out.println("Gender :- "+employeePojoWithoutJsonIgnore2.getGender());
System.out.println("Salary :- "+employeePojoWithoutJsonIgnore2.getSalary());
System.out.println("Married :- "+employeePojoWithoutJsonIgnore2.getMarried());
System.out.println("Eligible for vote :- "+employeePojoWithoutJsonIgnore2.getEligibleForVote());
System.out.println("Full name :- "+employeePojoWithoutJsonIgnore2.getFullName());
}
}
有些字段是可选的或则这段时间我们想要忽略。在 serialization 和 deserialization 过程中,我们想忽略 POJO 类中的任意属性,我们可以通过 Jackson API 的 @JsonIgnore 作用在想要忽略的属性上。它是一个标记注解,表明属性的访问函数被 serialization 和 deserialization 忽略. 这个注释加在任意想要移除的访问函数上(可能是 getter,setter,或字段,或 creator parameter).
POJO with JsonIgnore
“fullName” 和 “eligibleForVote” 字段加上 @JsonIgnore 注释
import com.fasterxml.jackson.annotation.JsonIgnore;
public class EmployeePojoWithJsonIgnore {
// private variables or data members of pojo class
private String firstName;
private String lastName;
private String gender;
private int age;
private double salary;
private boolean married;
@JsonIgnore
private String fullName;
@JsonIgnore
private boolean eligibleForVote;
// Getter and setter methods
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public boolean getMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
public String getFullName() {
return this.fullName;
}
public boolean getEligibleForVote() {
return this.eligibleForVote;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public void setEligibleForVote(boolean eligibleForVote) {
this.eligibleForVote = eligibleForVote;
}
}
Serialization using POJO with JsonIgnore
@Test
public void serializationWithJsonIgnore() throws JsonProcessingException {
// Just create an object of Pojo class
EmployeePojoWithJsonIgnore employeePojoWithJsonIgnore = new EmployeePojoWithJsonIgnore();
employeePojoWithJsonIgnore.setFirstName("Amod");
employeePojoWithJsonIgnore.setLastName("Mahajan");
employeePojoWithJsonIgnore.setAge(29);
employeePojoWithJsonIgnore.setGender("Male");
employeePojoWithJsonIgnore.setSalary(12323.56);
employeePojoWithJsonIgnore.setMarried(false);
employeePojoWithJsonIgnore.setFullName("Animesh Prashant");
employeePojoWithJsonIgnore.setEligibleForVote(false);
// Converting a Java class object to a JSON payload as string
ObjectMapper objectMapper = new ObjectMapper();
String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeePojoWithJsonIgnore);
System.out.println("Serialization...");
System.out.println(employeeJson);
}
输出:
Serialization...
{
"firstName" : "Amod",
"lastName" : "Mahajan",
"gender" : "Male",
"age" : 29,
"salary" : 12323.56,
"married" : false
}
Deserialization using POJO with JsonIgnore
@Test
public void deserializationWithJsonIgnore() throws JsonMappingException, JsonProcessingException
{
String employeeString = "{\r\n" +
" \"firstName\" : \"Amod\",\r\n" +
" \"lastName\" : \"Mahajan\",\r\n" +
" \"gender\" : \"Male\",\r\n" +
" \"age\" : 29,\r\n" +
" \"salary\" : 12323.56,\r\n" +
" \"married\" : false,\r\n" +
" \"fullName\" : \"Amod Mahajan Gupta\",\r\n" +
" \"eligibleForVote\" : false\r\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
EmployeePojoWithJsonIgnore employeePojoWithJsonIgnore2 = objectMapper.readValue(employeeString, EmployeePojoWithJsonIgnore.class);
System.out.println("Deserialization...");
System.out.println("First name :- "+employeePojoWithJsonIgnore2.getFirstName());
System.out.println("Last name :- "+employeePojoWithJsonIgnore2.getLastName());
System.out.println("Age :- "+employeePojoWithJsonIgnore2.getAge());
System.out.println("Gender :- "+employeePojoWithJsonIgnore2.getGender());
System.out.println("Salary :- "+employeePojoWithJsonIgnore2.getSalary());
System.out.println("Married :- "+employeePojoWithJsonIgnore2.getMarried());
System.out.println("Eligible for vote :- "+employeePojoWithJsonIgnore2.getEligibleForVote());
System.out.println("Full name :- "+employeePojoWithJsonIgnore2.getFullName());
}
输出:
Deserialization...
First name :- Amod
Last name :- Mahajan
Age :- 29
Gender :- Male
Salary :- 12323.56
Married :- false
Eligible for vote :- false
Full name :- null
完整代码:
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class SerialiDeserialExampleWithJsonIgnore {
@Test
public void serializationWithJsonIgnore() throws JsonProcessingException {
// Just create an object of Pojo class
EmployeePojoWithJsonIgnore employeePojoWithJsonIgnore = new EmployeePojoWithJsonIgnore();
employeePojoWithJsonIgnore.setFirstName("Amod");
employeePojoWithJsonIgnore.setLastName("Mahajan");
employeePojoWithJsonIgnore.setAge(29);
employeePojoWithJsonIgnore.setGender("Male");
employeePojoWithJsonIgnore.setSalary(12323.56);
employeePojoWithJsonIgnore.setMarried(false);
employeePojoWithJsonIgnore.setFullName("Animesh Prashant");
employeePojoWithJsonIgnore.setEligibleForVote(false);
// Converting a Java class object to a JSON payload as string
ObjectMapper objectMapper = new ObjectMapper();
String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employeePojoWithJsonIgnore);
System.out.println("Serialization...");
System.out.println(employeeJson);
}
@Test
public void deserializationWithJsonIgnore() throws JsonMappingException, JsonProcessingException
{
String employeeString = "{\r\n" +
" \"firstName\" : \"Amod\",\r\n" +
" \"lastName\" : \"Mahajan\",\r\n" +
" \"gender\" : \"Male\",\r\n" +
" \"age\" : 29,\r\n" +
" \"salary\" : 12323.56,\r\n" +
" \"married\" : false,\r\n" +
" \"fullName\" : \"Amod Mahajan Gupta\",\r\n" +
" \"eligibleForVote\" : false\r\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
EmployeePojoWithJsonIgnore employeePojoWithJsonIgnore2 = objectMapper.readValue(employeeString, EmployeePojoWithJsonIgnore.class);
System.out.println("Deserialization...");
System.out.println("First name :- "+employeePojoWithJsonIgnore2.getFirstName());
System.out.println("Last name :- "+employeePojoWithJsonIgnore2.getLastName());
System.out.println("Age :- "+employeePojoWithJsonIgnore2.getAge());
System.out.println("Gender :- "+employeePojoWithJsonIgnore2.getGender());
System.out.println("Salary :- "+employeePojoWithJsonIgnore2.getSalary());
System.out.println("Married :- "+employeePojoWithJsonIgnore2.getMarried());
System.out.println("Eligible for vote :- "+employeePojoWithJsonIgnore2.getEligibleForVote());
System.out.println("Full name :- "+employeePojoWithJsonIgnore2.getFullName());
}
}
从输出看出,字段 fullName 和 eligibleForVote 在序列化时被忽略没有输出,在反序列化时并没有按设定的JSON中的值赋值,而是保持默认值,所以加上 @JsonIgnore 注释的字段在 serialization 和 deserialization 过称中均被忽略。@JsonIgnore annotation 也可用于 getter 和 setter 方法.
@JsonIgnore 只加在 getter 方法上
@JsonIgnore
public String getFullName() {
return this.fullName;
}
@JsonIgnore
public boolean getEligibleForVote() {
return this.eligibleForVote;
}
运行上面@Test 方法,得到输出:
Serialization...
{
"firstName" : "Amod",
"lastName" : "Mahajan",
"gender" : "Male",
"age" : 29,
"salary" : 12323.56,
"married" : false
}
Deserialization...
First name :- Amod
Last name :- Mahajan
Age :- 29
Gender :- Male
Salary :- 12323.56
Married :- false
Eligible for vote :- false
Full name :- null
@JsonIgnore 只加在 setter 方法上
@JsonIgnore
public void setFullName(String fullName) {
this.fullName = fullName;
}
@JsonIgnore
public void setEligibleForVote(boolean eligibleForVote) {
this.eligibleForVote = eligibleForVote;
}
运行上面@Test 方法,得到输出:
Serialization...
{
"firstName" : "Amod",
"lastName" : "Mahajan",
"gender" : "Male",
"age" : 29,
"salary" : 12323.56,
"married" : false
}
Deserialization...
First name :- Amod
Last name :- Mahajan
Age :- 29
Gender :- Male
Salary :- 12323.56
Married :- false
Eligible for vote :- false
Full name :- null
可以得出加在 setter 或 getter 方法,跟加在字段上效果是一样的,字段 “eligibleForVote” 和 “fullName” 在 serialization 和 deserialization 均被忽略。