REST Assured 42 - 利用Jackson API ObjectMapper – Deserialization 忽略 Unknown Properties

本文介绍如何使用Jackson API的ObjectMapper配置忽略JSON反序列化过程中的未知属性,避免因JSON中出现未定义属性而导致异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

REST Assured 系列汇总 之 REST Assured 42 - 利用Jackson API ObjectMapper – Deserialization 忽略 Unknown Properties

前提条件:

关于 @JsonIgnoreProperties:

在 deserialization 中,利用 Jackson 提供的 @JsonIgnoreProperties annotation 可以忽略一些 unknown 属性,以防抛异常,详情请参考:

@JsonIgnoreProperties Annotation - Deserialization 忽略 Unknown Properties

Required Java Library

因为我们用到 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>

什么是 known 和 unknown 属性?

在进入主题之前,先来了解一下有关 knownunkonw 属性。如果一个属性存在于一个 POJO 类里,那么这个属性就是这个 POJO 类的 known 属性,反之这个属性不存在这个 POJO 类中就是 unkown 属性。让我们先看一个实例,known 属性在 deserialization 过程中缺失,将会发生什么?

在deserialization过程中缺失 known 属性

POJO 类:

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;
	} 	
}

Deserialize 缺失一些 known 属性

在 JSON 字符串不会包含所有 known 属性,如下:

import org.junit.Test;
 
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class DeserializationWithMissingKnownProperties {
 
	@Test
	public void deserializationWithMissingKnownProperties() throws JsonMappingException, JsonProcessingException
	{
		String employeeString = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\" : \"Mahajan\",\r\n" + 
				"  \"gender\" : \"Male\"\r\n" +
				"}";
		
		ObjectMapper objectMapper = new ObjectMapper();
		//objectMapper.con
		Employee employee = objectMapper.readValue(employeeString, Employee.class);
		System.out.println("Deserialization...");
		System.out.println("First name :- "+employee.getFirstName());
		System.out.println("Last name :- "+employee.getLastName());
		System.out.println("Age :- "+employee.getAge());
		System.out.println("Gender :- "+employee.getGender());
		System.out.println("Salary :- "+employee.getSalary());
		System.out.println("Married :- "+employee.getMarried());
 
	}
}

输出:

Deserialization...
First name :- Amod
Last name :- Mahajan
Age :- 0
Gender :- Male
Salary :- 0.0
Married :- false

在 JSON 字符串,有三个 known 属性 age, salary, 和 married 是缺失的,deserialization 反序列化后这些缺失的属性都是默认值。不会因为缺失部分 known 属性导致异常。

deserialization 反序列化一些额外的 unknown 属性

前面实例中,我们在 JSON 中缺失了部分 known 属性。现在我们来 JSON 中增加一些额外的 unknown 属性,观察一下将有啥行为。

Deserialize 反序列化一些 unknown 属性

import org.testng.annotations.Test;
 
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class DeserializationWithAdditionalUnknownProperties {
 
	@Test
	public void deserializationWithAdditionalUnknownProperties() 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();
		//objectMapper.con
		Employee employee = objectMapper.readValue(employeeString, Employee.class);
		System.out.println("Deserialization...");
		System.out.println("First name :- "+employee.getFirstName());
		System.out.println("Last name :- "+employee.getLastName());
		System.out.println("Age :- "+employee.getAge());
		System.out.println("Gender :- "+employee.getGender());
		System.out.println("Salary :- "+employee.getSalary());
		System.out.println("Married :- "+employee.getMarried());
 
	}
}

在 JSON 字符串中包含了一些 unknown 属性,如 fullName 和 eligibleForVote。

输出:

FAILED: deserializationWithMissingKnownProperties
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "fullName" (class JacksonTutorials.Employee), not marked as ignorable (6 known properties: "lastName", "married", "salary", "firstName", "age", "gender"])
 at [Source: (String)"{
  "firstName" : "Amod",
  "lastName" : "Mahajan",
  "gender" : "Male",
  "age" : 29,
  "salary" : 12323.56,
  "married" : false,
  "fullName" : "Amod Mahajan Gupta",
  "eligibleForVote" : false
}"; line: 8, column: 17] (through reference chain: JacksonTutorials.Employee["fullName"])

当遇到第一个 unknown 属性 “fullName”时,deserialization 反序列化失败,输出中还列出了所有 known 的属性。

ObjectMapper configuration to ignore unknown properties

上篇文章中,deserialization 过程中利用 @JsonIgnoreProperties 作用在 class 级别上忽略一些 unknown 属性。但是如果你不能访问到 POJO 类 或不允许更改 POJO 类,我们还可以通过 ObjectMapper 配置达成相同的效果。

需要用到 DeserializationFeature 枚举,将 “FAIL_ON_UNKNOWN_PROPERTIES” 设置为 false,就没有必要更改 POJO 类。

ObjectMapper Configuration Code


import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

import java.io.IOException;

public class DeserializationWithAdditionalUnknownPropertiesObjectMapper {

    @Test
    public void deserializationWithAdditionalUnknownProperties() throws IOException {
        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();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //objectMapper.con
        Employee employee = objectMapper.readValue(employeeString, Employee.class);
        System.out.println("Deserialization...");
        System.out.println("First name :- "+employee.getFirstName());
        System.out.println("Last name :- "+employee.getLastName());
        System.out.println("Age :- "+employee.getAge());
        System.out.println("Gender :- "+employee.getGender());
        System.out.println("Salary :- "+employee.getSalary());
        System.out.println("Married :- "+employee.getMarried());

    }
}

输出:

Deserialization...
First name :- Amod
Last name :- Mahajan
Age :- 29
Gender :- Male
Salary :- 12323.56
Married :- false

可以看出, JSON 字符串中包含一些 unkown 属性,serialization 成功,没有异常抛出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值