Java的UnrecognizedPropertyException
在 Restful Web 服务应用程序中,我们解析一个 JSON 请求字符串,然后将其映射到一个Java类。使用 Jackson 库将 JSON字符串解组到Java类。如果 JSON字符串包含无法映射到Java类属性的属性,那么我们会遇到 UnrecognizedPropertyException。让我们通过下面给出的插图来理解这一点。
Illustration:
We have an Employee class with attributes like name, id, department and salary. We then create a json string with all these properties. We will then try to deserialize the JSON string to Employee class.
在eclipse中设置时,我们需要创建一个maven项目,并在'pom.xml文件'中添加如下依赖。
com.fasterxml.jackson.core
jackson-databind
2.2.3
这将在我们的项目中下载以下 jars。
jackson-databind-2.2.3.jar
jackson-annotations-2.2.3.jar
jackson-core-2.2.3.jar
现在继续,让我们使用 Jackson 库进行序列化和反序列化,其中我们使用 Jackson 库将员工对象序列化为在src/main/resources 文件夹中创建的 json 文件。 Jackson 的库也有API s,它几乎打印了下面实现的 json 文件。
例子
Java
// Java Program to Serialize and Deserialize
// Using the Jackson library
// Importing input output classes
// Importing Jackson classes
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.*;
import java.io.File;
import java.io.IOException;
// Helper class
class Employee {
// Member variables of this class
private String id;
private String name;
private String deptName;
private double salary;
// Member functions
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDeptName() { return deptName; }
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
}
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// creates an object mapper instance
ObjectMapper mapper = new ObjectMapper();
// creates an employee instance.
Employee employee = generateEmployee();
// java object to json
// Try block to check for exceptions
try {
// Serializes the java object to json and
// creates a file in src/main/resources
mapper.writeValue(
new File(
"/home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp.json"),
employee);
// Creating a json string
String empJson
= mapper.writeValueAsString(employee);
// Print and display
System.out.println(empJson);
// Pretty print
String empJsonPrettyPrint
= mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(employee);
System.out.println("Pretty print format");
System.out.println(empJsonPrettyPrint);
}
// Catch block 2
// Catch block to handle exceptions
// related to json generation
catch (JsonGenerationException e) {
// Print the exception along with line number
// using printStackTrace() method
e.printStackTrace();
}
// Catch block 2
// Catch block to handle exceptions
// related to json mapping
catch (JsonMappingException e) {
e.printStackTrace();
}
// Catch block 3
// Catch block to handle basic exceptions
catch (IOException e) {
e.printStackTrace();
}
// Convert to a json string
}
private static Employee generateEmployee()
{
Employee employee = new Employee();
employee.setId("e01010");
employee.setName("Jane");
employee.setDeptName("Sales");
employee.setSalary(100000.00);
return employee;
}
}
Java
// Java Program to Illustrate UnrecognizedPropertyException
// While parsing json files
// Importing input output classes
import java.io.*;
// Class 1
// Helper class
class Employee {
// Member variables of this class
private String id;
private String name;
private String deptName;
private double salary;
// Member functions of this class
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDeptName() { return deptName; }
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
@Override public String toString()
{
return "Employee [id=" + id + ", name=" + name
+ ", deptName=" + deptName
+ ", salary=" + salary + "]";
}
}
// Class 2
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an object of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// Try block to check for exceptions
try {
// mapper reads from json file and deserializes
// it to Employee object
Employee emp = mapper.readValue(
new File(
"/home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp1.json"),
Employee.class);
System.out.println(
"Reading values of employee attributes from a json file");
System.out.println(emp.toString());
}
// Catch Block 1
// Handling json parsing exception
catch (JsonParseException e) {
// Print and display the exception along with
// line number using printStackTrace() method
e.printStackTrace();
}
// Catch Block 2
// Handling json mapping exception
catch (JsonMappingException e) {
e.printStackTrace();
}
// Catch Block 3
// Catch block to handle basc exceptios
catch (IOException e) {
e.printStackTrace();
}
}
}
Java
// Java Program to Remove UnrecognizedPropertyException by
// Disabling the object mapper to deserialize on unknown
// properties.
package com.sample.json;
// Importing input output classes
import java.io.*;
// Class 1
// Helper class
public class Employee {
// Member variables of this class
private String id;
private String name;
private String deptName;
private double salary;
// Member methods of this class
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDeptName() { return deptName; }
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
@Override public String toString()
{
return "Employee [id=" + id + ", name=" + name
+ ", deptName=" + deptName
+ ", salary=" + salary + "]";
}
}
// Class 2
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an object of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// Try block to check for exceptions
try {
// Disabling the mapper object to deserialize
// properties which cannot be mapped to java
// class
mapper.disable(DeserializationFeature
.FAIL_ON_UNKNOWN_PROPERTIES);
// mapper reading the json file and
// deserializes it to employee object
Employee emp = mapper.readValue(
new File(
"/home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp1.json"),
Employee.class);
// Display message only
System.out.println(
"Reading values of employee attributes from a json file");
// Print and display
System.out.println(emp.toString());
}
// Catch block to handle exceptions
// Catch block 1 to deal with json parsing exception
catch (JsonParseException e) {
e.printStackTrace();
}
// Catch block 2 to deal with json mapping exception
catch (JsonMappingException e) {
e.printStackTrace();
}
// Catch block 2 to deal with basic I/O exceptions
catch (IOException e) {
e.printStackTrace();
}
}
}
Java
// Java Program to Remove UnrecognizedPropertyException by
// Providing an annotation at the class level
// @JsonIgnoreProperties
// Importing required classes
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.io.*;
@JsonIgnoreProperties(ignoreUnknown = true)
// Class 1
// Helper class
public class Employee {
// Member variables of this class
private String id;
private String name;
private String deptName;
private double salary;
// Mamber functions of this class
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDeptName() { return deptName; }
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
@Override public String toString()
{
return "Employee [id=" + id + ", name=" + name
+ ", deptName=" + deptName
+ ", salary=" + salary + "]";
}
}
// Class 2
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an object of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// Try block to check for exceptions
try {
// Mapper reads from emp1.json and deserializes
// it to employee object. It ignores those
// properties which are not mapped to java class
Employee emp = mapper.readValue(
new File(
"/home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp1.json"),
Employee.class);
System.out.println(
"Reading values of employee attributes from a json file");
System.out.println(emp.toString());
}
// Catch block to handle the exceptions
// Catch Block 1
catch (JsonParseException e) {
// Print the exception along wth line number
// using printStackTrace() method
e.printStackTrace();
}
// Catch Block 2
catch (JsonMappingException e) {
e.printStackTrace();
}
// Catch Block 3
// Handling basic I/O exceptions
catch (IOException e) {
e.printStackTrace();
}
}
}
输出:
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0}
Pretty print format
{
"id" : "e01010",
"name" : "Jane",
"deptName" : "Sales",
"salary" : 100000.0
}
文件 emp.json 在 src/main/resources 文件夹中创建。
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0}
现在让我们通过一个例子来理解UnrecognizedPropertyException,我们在解析json文件时是什么时候得到这个异常的。
执行:
- 我们创建了一个 json 文件,其中添加了一个新属性作为 phoneNumber。但是,该属性不存在于 Employee 类中。
- 当 Jackson 库尝试将 json 字段值解组/反序列化为类属性时,它无法识别此属性并抛出 UnrecognizedPropertyException。
- 我们在 src/main/resources 中创建一个文件 emp1.json。文件 emp1.json 有一个新属性 phoneNumber,它不是 Employee 类的一部分。
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0,"phoneNumber": 98218281812}
例子
Java
// Java Program to Illustrate UnrecognizedPropertyException
// While parsing json files
// Importing input output classes
import java.io.*;
// Class 1
// Helper class
class Employee {
// Member variables of this class
private String id;
private String name;
private String deptName;
private double salary;
// Member functions of this class
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDeptName() { return deptName; }
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
@Override public String toString()
{
return "Employee [id=" + id + ", name=" + name
+ ", deptName=" + deptName
+ ", salary=" + salary + "]";
}
}
// Class 2
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an object of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// Try block to check for exceptions
try {
// mapper reads from json file and deserializes
// it to Employee object
Employee emp = mapper.readValue(
new File(
"/home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp1.json"),
Employee.class);
System.out.println(
"Reading values of employee attributes from a json file");
System.out.println(emp.toString());
}
// Catch Block 1
// Handling json parsing exception
catch (JsonParseException e) {
// Print and display the exception along with
// line number using printStackTrace() method
e.printStackTrace();
}
// Catch Block 2
// Handling json mapping exception
catch (JsonMappingException e) {
e.printStackTrace();
}
// Catch Block 3
// Catch block to handle basc exceptios
catch (IOException e) {
e.printStackTrace();
}
}
}
输出:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "phoneNumber" (class com.sample.json.Employee), not marked as ignorable (4 known properties: , "deptName", "salary", "id", "name"])
at [Source: /home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp1.json; line: 1, column: 93] (through reference chain: com.sample.json.Employee["phoneNumber"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)
at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:555)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:708)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1160)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:315)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1988)
at com.sample.json.TestParsingException.main(TestParsingException.java:19)
Note: The exception states that it is unable to recognize the property phoneNumber which is a part of emp1.json file. This is because it is unable to map this property with the attributes of the Employee class.
现在让我们讨论摆脱这个异常的方法。以下是我们可以合并的两种方式,如下所示:
- 禁用对象映射器对未知属性进行反序列化。
- 在类级别@JsonIgnoreProperties 提供注释。
方法 1:禁用对象映射器对未知属性进行反序列化。
为了解决这个问题,我们禁用对象映射器对未知属性进行反序列化。因此,对象映射器将仅解组/反序列化 json 文件中映射到Java类的那些属性。我们有 emp1.json,它类似于前面的例子。
emp1.json
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0,"phoneNumber": 98218281812}
例子
Java
// Java Program to Remove UnrecognizedPropertyException by
// Disabling the object mapper to deserialize on unknown
// properties.
package com.sample.json;
// Importing input output classes
import java.io.*;
// Class 1
// Helper class
public class Employee {
// Member variables of this class
private String id;
private String name;
private String deptName;
private double salary;
// Member methods of this class
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDeptName() { return deptName; }
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
@Override public String toString()
{
return "Employee [id=" + id + ", name=" + name
+ ", deptName=" + deptName
+ ", salary=" + salary + "]";
}
}
// Class 2
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an object of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// Try block to check for exceptions
try {
// Disabling the mapper object to deserialize
// properties which cannot be mapped to java
// class
mapper.disable(DeserializationFeature
.FAIL_ON_UNKNOWN_PROPERTIES);
// mapper reading the json file and
// deserializes it to employee object
Employee emp = mapper.readValue(
new File(
"/home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp1.json"),
Employee.class);
// Display message only
System.out.println(
"Reading values of employee attributes from a json file");
// Print and display
System.out.println(emp.toString());
}
// Catch block to handle exceptions
// Catch block 1 to deal with json parsing exception
catch (JsonParseException e) {
e.printStackTrace();
}
// Catch block 2 to deal with json mapping exception
catch (JsonMappingException e) {
e.printStackTrace();
}
// Catch block 2 to deal with basic I/O exceptions
catch (IOException e) {
e.printStackTrace();
}
}
}
输出:
Reading values of employee attributes from a json file
Employee [id=e01010, name=Jane, deptName=Sales, salary=100000.0]
方法二:在类级别提供注解@JsonIgnoreProperties
另一种方法是在类级别提供注释@JsonIgnoreProperties(ignoreUnknown = true)。这个注解告诉 jackson 忽略那些不能映射到Java类的属性。这与上一个示例中的 emp1.json 相同。
emp1.json
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0,"phoneNumber": 98218281812}
例子
Java
// Java Program to Remove UnrecognizedPropertyException by
// Providing an annotation at the class level
// @JsonIgnoreProperties
// Importing required classes
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.io.*;
@JsonIgnoreProperties(ignoreUnknown = true)
// Class 1
// Helper class
public class Employee {
// Member variables of this class
private String id;
private String name;
private String deptName;
private double salary;
// Mamber functions of this class
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDeptName() { return deptName; }
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public double getSalary() { return salary; }
public void setSalary(double salary)
{
this.salary = salary;
}
@Override public String toString()
{
return "Employee [id=" + id + ", name=" + name
+ ", deptName=" + deptName
+ ", salary=" + salary + "]";
}
}
// Class 2
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating an object of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// Try block to check for exceptions
try {
// Mapper reads from emp1.json and deserializes
// it to employee object. It ignores those
// properties which are not mapped to java class
Employee emp = mapper.readValue(
new File(
"/home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp1.json"),
Employee.class);
System.out.println(
"Reading values of employee attributes from a json file");
System.out.println(emp.toString());
}
// Catch block to handle the exceptions
// Catch Block 1
catch (JsonParseException e) {
// Print the exception along wth line number
// using printStackTrace() method
e.printStackTrace();
}
// Catch Block 2
catch (JsonMappingException e) {
e.printStackTrace();
}
// Catch Block 3
// Handling basic I/O exceptions
catch (IOException e) {
e.printStackTrace();
}
}
}
输出:
Reading values of employee attributes from a json file
Employee [id=e01010, name=Jane, deptName=Sales, salary=100000.0]