1. Overview
In this article, we will discuss the scenarios that would cause Jackson UnrecognizedPropertyException error and how we can fix it.
2. Jackson UnrecognizedPropertyException
Let’s understand the primary reason for getting this error.
Assume you are using the Jackson library in your project to deserialize the JSON to Java object. If the JSON contains fields that are not defined in the Java object, then the application would throw UnrecognizedPropertyException
.
3. Ignore new or unknown fields Jackson
Consider that the JSON input contains fields that are not required in your project. Since we don’t need those fields in our code, we rarely define them in our Java class.
Assume we have a Student
class with id
property.
public class Student { public Student(long id) { this.id = id; } private long id; public long getId() { return id; } public void setId(long id) { this.id = id; } @Override public String toString() { return "Student [id=" + id + "]"; } }
In the below code, the json
input contains id
, studentName
and dept
fields. Since we don’t require the fields studentName
and dept
in our code, we haven’t defined them in the Student
class.
ObjectMapper mapper = new ObjectMapper(); String json = "{\"id\": 1001, \"studentName\": \"John\", \"dept\": \"IT\"}"; Student student = mapper.readValue(json, Student.class); System.out.println(student);
If you run the above code, then it produces the following UnrecognizedPropertyException
error.
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "studentName" (class com.tedblob.jackson.fieldname.models.Student), not marked as ignorable (one known property: "id"]) at [Source: (String)"{"id": 1001, "studentName": "John", "dept": "IT"}"; line: 1, column: 30] (through reference chain: com.tedblob.jackson.fieldname.models.Student["studentName"])
3.1. Ignore unknown fields at class level
You can use @JsonIgnoreProperties annotation at the class level to ignore any unknown fields in Jackson.
This annotation ignores processing of JSON properties during deserialization. If you know the JSON specific fields that is not required in your Java class, then you can prevent those by defining them explicitly:
@JsonIgnoreProperties({ "studentName", "dept" })
To ignore any unknown properties in JSON input with no exception:
@JsonIgnoreProperties(ignoreUnknown = true) public class Student { private long id; }
Depending on your Jackson version, you must use a different import statement:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.codehaus.jackson.annotate.JsonIgnoreProperties;
3.2. Ignore unknown fields using ObjectMapper
You can configure your ObjectMapper to ignore unknown properties:
ObjectMapper objectMapper = new ObjectMapper(); import org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES; objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); import com.fasterxml.jackson.databind.DeserializationFeature; objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
If you run the deserialization code now, then it outputs:
Student [id=1001]
3.3. Avoid Jackson UnrecognizedPropertyException using properties
Alternatively, you can define spring.jackson.deserialization.fail-on-unknown-properties
as false
in your project properties file to ignore unknown JSON fields during deserialization.
application.properties file:
spring.jackson.deserialization.fail-on-unknown-properties=false
application.yml file:
spring: jackson: deserialization: fail-on-unknown-properties:false
3.4. Avoid UnrecognizedPropertyException globally using Jackson2ObjectMapperBuilder
You can use Jackson2ObjectMapperBuilder
to build your ObjectMapper
instance. By default, this builder disables DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
. So whenever you convert your JSON to Java object using its ObjectMapper, there won’t be any UnrecognizedPropertyException
failure.
@Autowired Jackson2ObjectMapperBuilder objectBuilder;
For example, the below code creates an ObjectMapper
instance by calling the build
method of Jackson2ObjectMapperBuilder
.
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder @SpringBootApplication public class JacksonFieldNameApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(JacksonFieldNameApplication.class, args); } @Autowired Jackson2ObjectMapperBuilder objectBuilder; @Override public void run(String... args) throws Exception { ObjectMapper mapper = objectBuilder.build(); String json = "{\"id\": 1001, \"studentName\": \"John\", \"dept\": \"IT\"}"; Student student = mapper.readValue(json, Student.class); System.out.println(student); } }
If you run the above code, then it produces the following result:
Student [id=1001]
4. Jackson UnrecognizedPropertyException: private fields without setter or getter
If your property is private, then Jackson uses the setter and getter methods to update the value during deserialization.
Assume you have defined all the fields or properties in your Java class so that both input JSON and output Java class have identical fields. But missing setter and getter methods of private fields still results in the UnrecognizedPropertyException
error.
The following Student
class contains a private id
field without any setter or getter methods.
public class Student { public Student(long id) { this.id = id; } private long id; @Override public String toString() { return "Student [id=" + id + "]"; } }
If you execute the following code, then it would produce the UnrecognizedPropertyException
error:
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "id" (class com.tedblob.jackson.fieldname.models.Student), not marked as ignorable (0 known properties: ]) at [Source: (String)"{"id": 1001}"; line: 1, column: 12] (through reference chain: com.tedblob.jackson.fieldname.models.Student["id"])
@SpringBootApplication public class JacksonFieldNameApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(JacksonFieldNameApplication.class, args); } @Override public void run(String... args) throws Exception { ObjectMapper mapper = new ObjectMapper(); String json = "{\"id\": 1001}"; Student student = mapper.readValue(json, Student.class); System.out.println(student); } }
To avoid this error, you can add the setter or getter method to your private field. However, there are alternatives to perform deserialization without adding a setter or getter. Refer to this section for the same.
5. Conclusion
To sum up, we have discussed the various scenarios where we could get the UnrecognizedPropertyException
error and also the solutions for each one of them.