REST Assured 37 - @JsonInclude Annotation – Payload 中忽略值为Null & Empty Values的字段

REST Assured 系列汇总 之 REST Assured 37 - @JsonInclude Annotation – Payload 中忽略值为Null & Empty Values的字段

Jackson libray 一个重要的 annotation @JsonInclude,它可以清除值为默认值,null, empty的属性。本文将了解 paylaod中忽略值为 null 和 empty的属性。

Maven Dependency
因为要使用 Jackson API提供的一个 annotation,我们需要导入 Jackson library,我在用的是 maven 构建工具。

尽量用 Central Maven Repository 最新的 Jackson 依赖包,例如如下:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.5</version>
</dependency>

当然有些依赖包也会传递依赖Jackson,就不用再添加 Jackson依赖了,如 json schema validator

 <!-- json schema validation -->
  <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>json-schema-validator</artifactId>
      <version>4.3.0</version>
 </dependency>

前面文章@JsonInclude Annotation 忽略默认值有了解 Include 枚举中有不同的值。

Usage of NON_NULL

Java语言中,默认变量的值如下:

Data TypeDefault Value (for fields)
byte0
short0
int0
long0L
float0.0f
double0.0d
char‘u0000’
String (or any object)null
booleanfalse

最危险的默认值就是 NULL ,如果我们没有验证值为 null 的变量,可能会出现异常 NullPointerException 终止程序。有时忽略所有默认值并非是好的,我们只是想忽略 NULL 值。所以这种情况,我们可以用 IncludeNON_NULL 枚举值,如下:

import com.fasterxml.jackson.annotation.JsonInclude;
 
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Employee {
 
	// 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;
	
	// 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;
	} 	
}

将 Java Object 转换成 JSON Object

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
 
 
public class AnnotationJsonIncludeExample {
 
	public static void main(String[] args) throws JsonProcessingException {
 
		// Just create an object of Pojo class
		Employee employee = new Employee();
		// Set value as you wish
		employee.setFirstName("Amod");
		employee.setMarried(true);
		// Converting a Java class object to a JSON payload as string
		ObjectMapper objectMapper = new ObjectMapper();
		String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
		System.out.println(employeeJson);
	}
}

输出:

{
  "firstName" : "Amod",
  "age" : 0,
  "salary" : 0.0,
  "married" : true
}

我们没有对字段 ‘lastName’, ‘gender’,’age’ 和 ‘salary’ 设置值,因为字段 ‘lastName’ 和 ‘gender’ 默认值都是 NULL,所以在序列化过程中是被忽略了。而字段 ‘age’ 和 ‘salary’ 默认值均为 0 , 所以被包含在JSON中,可以从输出中看出。

Usage of NON_EMPTY
NON_EMPTY 范围大于 NON_NULL,或则可以说 NON_EMPTY 包括 NON_NULL 和其它,根据官方文档

NON_EMPTY + NON_NULL + NON_ABSENT

如果类的属性值是 NULLEmpty,在序列化时可能需要忽略。NULL 我们前面了解过,主要用于 String 和 引用类型变量。EMPTY有点棘手, 空值的定义取决于数据类型。

  1. 一个 NULL 值可以认为是 EMPTY
  2. 对于 Collection 和 Map, 可以调用 isEmpty() 方法判断是否为EMPTY
  3. 对一个相数组或字符串,通过长度可以判断是否为EMPTY
    A NULL value is also considered as EMPTY.

一个有不同类型数据的POJO类

import java.util.List;
import java.util.Map;
 
public class SeniorEmployee {
 
	// 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[] mobileNo;
	private List<String> cars;
	private Map<String,String> familyMembers;
	
	// 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[] getMobileNo() {
		return mobileNo;
	}
	public void setMobileNo(String[] mobileNo) {
		this.mobileNo = mobileNo;
	}
	public List<String> getCars() {
		return cars;
	}
	public void setCars(List<String> cars) {
		this.cars = cars;
	}
	public Map<String, String> getFamilyMembers() {
		return familyMembers;
	}
	public void setFamilyMembers(Map<String, String> familyMembers) {
		this.familyMembers = familyMembers;
	}
}

不设置任何值

@Test(priority = 1)
	public void noValuessetForAnyField() throws JsonProcessingException {
		// Just create an object of Pojo class
		SeniorEmployee seniorEmployee = new SeniorEmployee();
		// Converting a Java class object to a JSON payload as string
		ObjectMapper objectMapper = new ObjectMapper();
		String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(seniorEmployee);
		System.out.println("Output of noValuessetForAnyField...");
		System.out.println(employeeJson);
	}
{
  "firstName" : null,
  "lastName" : null,
  "gender" : null,
  "age" : 0,
  "salary" : 0.0,
  "married" : false,
  "mobileNo" : null,
  "cars" : null,
  "familyMembers" : null
}

我们看到字段都是默认值。我们可以通过 NON_NULL 来忽略上面所有 NULL值,让我们在Class级别上加上 NON_NULL ,创建如下对象:

@Test(priority = 1)
	public void noValueSetForArrayListMap() throws JsonProcessingException {
		// Just create an object of Pojo class
		SeniorEmployee seniorEmployee = new SeniorEmployee();
		seniorEmployee.setFirstName("Amod");
		seniorEmployee.setLastName("Mahajan");
		seniorEmployee.setAge(29);
		seniorEmployee.setGender("Male");
		seniorEmployee.setSalary(12323.56);
		seniorEmployee.setMarried(false);
		
		// Empty array
		String[] mobileNo = {};
		seniorEmployee.setMobileNo(mobileNo);
		
		// Empty list
		List<String> cars = new ArrayList<String>();
		seniorEmployee.setCars(cars);
		
		// Empty Map
		Map<String,String> familyMembers = new HashMap<>();
		seniorEmployee.setFamilyMembers(familyMembers);
		
		// Converting a Java class object to a JSON payload as string
		ObjectMapper objectMapper = new ObjectMapper();
		String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(seniorEmployee);
		System.out.println("Output of noValueSetForArrayListMap...");
		System.out.println(employeeJson);
	}

输出:

Output of valueSetForFields...
{
  "firstName" : "Amod",
  "lastName" : "Mahajan",
  "gender" : "Male",
  "age" : 29,
  "salary" : 12323.56,
  "married" : false,
  "mobileNo" : [ ],
  "cars" : [ ],
  "familyMembers" : { }
}

可以看出 NON_NULL 没有实现忽略 empty 值的目的。我们把 NON_EMPTY 加到 class 级别。

import com.fasterxml.jackson.annotation.JsonInclude;
 
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class SeniorEmployee

再回到 第一个@Test 方法并执行,输出结果如下:

{
  "age" : 0,
  "salary" : 0.0,
  "married" : false
}

再回到 第二个@Test 方法并执行,输出结果如下:

{
  "firstName" : "Amod",
  "lastName" : "Mahajan",
  "gender" : "Male",
  "age" : 29,
  "salary" : 12323.56,
  "married" : false
}

可以看出所有 NULL 和 EMPTY的值都忽略了,当然也可以将 annotation 加到属性级别。

完整代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.junit.Test;
 
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class NonEmptyExample {
 
	@Test(priority = 1)
	public void noValuesSetForAnyField() throws JsonProcessingException {
		// Just create an object of Pojo class
		SeniorEmployee seniorEmployee = new SeniorEmployee();
		// Converting a Java class object to a JSON payload as string
		ObjectMapper objectMapper = new ObjectMapper();
		String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(seniorEmployee);
		System.out.println("Output of noValuesSetForAnyField...");
		System.out.println(employeeJson);
	}
	
	@Test(priority = 2)
	public void valueSetForFields() throws JsonProcessingException {
		// Just create an object of Pojo class
		SeniorEmployee seniorEmployee = new SeniorEmployee();
		seniorEmployee.setFirstName("Amod");
		seniorEmployee.setLastName("Mahajan");
		seniorEmployee.setAge(29);
		seniorEmployee.setGender("Male");
		seniorEmployee.setSalary(12323.56);
		seniorEmployee.setMarried(false);
		
		String[] mobileNo = new String[2];
		mobileNo[0] = "12345";
		mobileNo[1] = "67890";
		seniorEmployee.setMobileNo(mobileNo);
		
		List<String> cars = new ArrayList<String>();
		cars.add("Audi");
		cars.add("bmw");
		seniorEmployee.setCars(cars);
		
		Map<String,String> familyMembers = new HashMap<>();
		familyMembers.put("1", "Father");
		familyMembers.put("2", "Mother");
		familyMembers.put("3", "Brother");
		seniorEmployee.setFamilyMembers(familyMembers);
		// Converting a Java class object to a JSON payload as string
		ObjectMapper objectMapper = new ObjectMapper();
		String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(seniorEmployee);
		System.out.println("Output of valueSetForFields...");
		System.out.println(employeeJson);
	}
	
	@Test(priority = 3)
	public void noValueSetForArrayListMap() throws JsonProcessingException {
		// Just create an object of Pojo class
		SeniorEmployee seniorEmployee = new SeniorEmployee();
		seniorEmployee.setFirstName("Amod");
		seniorEmployee.setLastName("Mahajan");
		seniorEmployee.setAge(29);
		seniorEmployee.setGender("Male");
		seniorEmployee.setSalary(12323.56);
		seniorEmployee.setMarried(false);
		
		// Empty array
		String[] mobileNo = {};
		seniorEmployee.setMobileNo(mobileNo);
		
		// Empty list
		List<String> cars = new ArrayList<String>();
		seniorEmployee.setCars(cars);
		
		// Empty Map
		Map<String,String> familyMembers = new HashMap<>();
		seniorEmployee.setFamilyMembers(familyMembers);
		
		// Converting a Java class object to a JSON payload as string
		ObjectMapper objectMapper = new ObjectMapper();
		String employeeJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(seniorEmployee);
		System.out.println("Output of noValueSetForArrayListMap...");
		System.out.println(employeeJson);
	}
}

输出:

Output of noValuesSetForAnyField...
{
  "age" : 0,
  "salary" : 0.0,
  "married" : false
}
Output of valueSetForFields...
{
  "firstName" : "Amod",
  "lastName" : "Mahajan",
  "gender" : "Male",
  "age" : 29,
  "salary" : 12323.56,
  "married" : false,
  "mobileNo" : [ "12345", "67890" ],
  "cars" : [ "Audi", "bmw" ],
  "familyMembers" : {
    "1" : "Father",
    "2" : "Mother",
    "3" : "Brother"
  }
}
Output of noValueSetForArrayListMap...
{
  "firstName" : "Amod",
  "lastName" : "Mahajan",
  "gender" : "Male",
  "age" : 29,
  "salary" : 12323.56,
  "married" : false
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值