UnrecognizedPropertyException in Java
Last Updated :
04 May, 2022
In the Restful Web services application, we parse a JSON request string which is then mapped to a java class. The JSON string is unmarshalled to the java class using the Jackson library. If the JSON string consists of properties that cannot be mapped to java class attributes, then we encounter UnrecognizedPropertyException. Let’s understand this with an Illustration given below.
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.
In setting up in eclipse, we need to create a maven project and add the following dependency in the ‘pom.xml file’.
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
</dependencies>
This will download the following jars in our project.
jackson-databind-2.2.3.jar
jackson-annotations-2.2.3.jar
jackson-core-2.2.3.jar
Now proceeding further, let us serialize and Deserialize using the Jackson library where we use Jackson library to serialize employee object to json file which is created in src/main/resources folder. Jackson’s library also has APIs which pretty much print the json file as implemented below.
Example
Java
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;
class Employee {
private String id;
private String name;
private String deptName;
private double salary;
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;
}
}
class GFG {
public static void main(String[] args)
{
ObjectMapper mapper = new ObjectMapper();
Employee employee = generateEmployee();
try {
mapper.writeValue(
new File(
"/home/suchitra/Desktop/suchitra/projects/java-concurrency-examples/json-parsing/src/main/resources/emp.json" ),
employee);
String empJson
= mapper.writeValueAsString(employee);
System.out.println(empJson);
String empJsonPrettyPrint
= mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(employee);
System.out.println( "Pretty print format" );
System.out.println(empJsonPrettyPrint);
}
catch (JsonGenerationException e) {
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
private static Employee generateEmployee()
{
Employee employee = new Employee();
employee.setId( "e01010" );
employee.setName( "Jane" );
employee.setDeptName( "Sales" );
employee.setSalary( 100000.00 );
return employee;
}
}
|
Output:
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0}
Pretty print format
{
"id" : "e01010",
"name" : "Jane",
"deptName" : "Sales",
"salary" : 100000.0
}
The file emp.json gets created in src/main/resources folder.
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0}
Now let us understand UnrecognizedPropertyException through an example when do we get this exception while parsing json files.
Implementation:
- We create a json file with a new property added as phoneNumber. However, this property is not present in the Employee class.
- When Jackson library tries to unmarshal/deserialize the json field values to the class attributes, it cannot recognize this property and it throws UnrecognizedPropertyException.
- We create a file emp1.json in src/main/resources. The file emp1.json has a new property phoneNumber which is not a part of Employee class.
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0,"phoneNumber": 98218281812}
Example
Java
import java.io.*;
class Employee {
private String id;
private String name;
private String deptName;
private double salary;
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 GFG {
public static void main(String[] args)
{
ObjectMapper mapper = new ObjectMapper();
try {
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 (JsonParseException e) {
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
|
Output:
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.
Now let us discuss a way out to get rid of this exception. Below are two ways with which we can incorporate for the same which are as follows:
- Disabling the object mapper to deserialize on unknown properties.
- Providing an annotation at the class level @JsonIgnoreProperties.
Method 1: Disabling the object mapper to deserialize on unknown properties.
In order to solve this issue, we disable the object mapper to deserialize on unknown properties. So the object mapper will unmarshal/deserialize only those properties from json file which are mapped to the java class. We have emp1.json which is similar to the previous example.
emp1.json
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0,"phoneNumber": 98218281812}
Example
Java
package com.sample.json;
import java.io.*;
public class Employee {
private String id;
private String name;
private String deptName;
private double salary;
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 GFG {
public static void main(String[] args)
{
ObjectMapper mapper = new ObjectMapper();
try {
mapper.disable(DeserializationFeature
.FAIL_ON_UNKNOWN_PROPERTIES);
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 (JsonParseException e) {
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
|
Output:
Reading values of employee attributes from a json file
Employee [id=e01010, name=Jane, deptName=Sales, salary=100000.0]
Method 2: Providing an annotation at the class level @JsonIgnoreProperties
Another approach is to provide an annotation at the class level @JsonIgnoreProperties(ignoreUnknown = true). This annotation tells jackson to ignore those attributes which cannot be mapped to java class. This is the same emp1.json from the previous example.
emp1.json
{"id":"e01010","name":"Jane","deptName":"Sales","salary":100000.0,"phoneNumber": 98218281812}
Example
Java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.io.*;
@JsonIgnoreProperties (ignoreUnknown = true )
public class Employee {
private String id;
private String name;
private String deptName;
private double salary;
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 GFG {
public static void main(String[] args)
{
ObjectMapper mapper = new ObjectMapper();
try {
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 (JsonParseException e) {
e.printStackTrace();
}
catch (JsonMappingException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
|
Output:
Reading values of employee attributes from a json file
Employee [id=e01010, name=Jane, deptName=Sales, salary=100000.0]
Share your thoughts in the comments
Please Login to comment...