Sunday, November 17, 2024
Google search engine
HomeLanguagesJavaHow to Ignore Unknown Properties While Parsing JSON in Java?

How to Ignore Unknown Properties While Parsing JSON in Java?

There are unknown properties while parsing JSON in java of which the most common problem while parsing JSON in Java using Jackson API is that it fails when JSON contains unknown properties which means the Java class doesn’t have all the field corresponding to all JSON properties. For example, if you are consuming JSON from a REST Web Service and the next day they added a new field into JSON then the code will break because Jackson will throw UnrecognizedPropertyException and stop parsing JSON. This is troublesome and can cause problems in production if one is not aware. The issue could have simply been avoided if one is familiar with Jackson library.

Methods:

There are two ways to ignore Unknown fields are provided by Jackson API. Both approaches will be discussed here and we will also see how to use them and when to use @JsonIgnoreProperties and when to ignore unknown fields in JSON globally at the ObjectMapper level. They are as follows:

  1. At the class level using @JsonIgnoreProperties annotation.
  2. At the ObjectMapper level using configure() method.

Method 1: Using @JsonIgnoreProperties

If a Model class is being created to represent the JSON in Java, then the class can be annotated as @JsonIgnoreProperties(ignoreUnknown = true) to ignore any unknown field. It means that if a new field is added later on JSON which represents this model then Jackson will not throw UnrecognizedPropertyException while parsing JSON in Java. This approach not only ignores unknown properties for that model class but also provides more control.

Example:

Java




// Java Program that demonstrates the use of
// @JsonIgnoreProperties
  
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.Serializable;
  
/*
 * Java Program to iterate over JSONObject of json-simple
 */
@JsonIgnoreProperties(ignoreUnknown = true)
class Student implements Serializable {
    private static final long serialVersionUID
        = -740085147914603262L;
  
    private String id;
    private String name;
    private String school;
    private String section;
    private String major;
  
    // getters and setters
    public String getID() { return id; }
  
    public void setID(String id) { this.id = id; }
  
    public String getName() { return name; }
  
    public void setName(String id) { this.name = name; }
  
    public String getSchool() { return school; }
  
    public void setSchool(String id) { this.id = id; }
  
    public String getSection() { return id; }
  
    public void setSection(String id) { this.id = id; }
  
    public String getMajor() { return id; }
  
    public void setMajor(String id) { this.id = id; }
  
    @Override public String toString()
    {
  
        return "Student{"
            + "name='" + name + '\'' + ", id='" + id + '\''
            + ", school='" + school + '\'' + ", section='"
            + section + '\'' + ", major='" + major + '\''
            + '}';
    }
}
  
class StudentMain {
    public static void main(String[] args)
        throws IOException
    {
        // JSON string
        String jsonString
            = "{\"name\":\"Krish\",\"id\":\"2019071075\"\"phone\":\"111-111-1111\"}";
        System.out.println("Input json string : ");
        System.out.println(jsonString);
        System.out.println("");
        
        // convert to object;
        Student s = toStudent(jsonString);
        
        // print information
        System.out.println("Generated java class:");
        System.out.println(s);
    }
  
    private static Student toStudent(String jsonData)
        throws IOException
    {
        // create object mapper instance
        ObjectMapper om = new ObjectMapper();
        
        // convert JSON string to Java Object
        return om.readValue(jsonData, Student.class);
    }
}


Output:

Input json string :
{"name":"Krish","phone":"111-111-1111"}

Generated java class:
Employee{name='Krish', id='2019071075', school='null', section='null', major='null'}

Output Explanation:

The approach of annotating classes with @JsonIgnoreProperties allows for finer control over which objects should ignore unknown fields and which should not. On the other hand, a developer may forget to put the annotation to a class, and then the problem could occur.

Method 2: Using Jackson

Configuring ObjectMapper is another way to deal with unknown properties in JSON while parsing so that it does not fail when it encounters an unknown property. This also solves the problem of UnrecognizedPropertyException. 

This setting is enabled by calling configure() method as shown below: 

import com.fasterxml.jackson.databind.DeserializationFeature; 
import com.fasterxml.jackson.databind.ObjectMapper; 

ObjectMapper objectMapper = new ObjectMapper(); 
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Note: Unknown properties will be ignored by this for any JSON it’s going to parse. This option should only be used if you can’t annotate a class with @JsonIgnoreProperties annotation.

Example:

Java




// Java Program that demonstrates the use of ObjectMapper
// Configuration
  
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
  
/* * Java Program to iterate over JSONObject of json-simple
 */
class JacksonTest {
    // JSON string
    private static String json
        = "{\r\n"
          + "\"name\" : \"Jack Ryan\",\r\n"
          + "\"id\" : \"2019071075\",\r\n"
          + "\"school\" : St. Jude's School,\r\n"
          + "\"section\" : B\r\n"
          + "}";
    public static void main(String args[])
        throws IOException
    {
        // create object mapper instance
        ObjectMapper om = new ObjectMapper();
        // configure ignore unknown properties
        om.configure(DeserializationFeature
                         .FAIL_ON_UNKNOWN_PROPERTIES,
                     false);
        // convert JSON string to Java Object
        Student effectiveJava
            = om.readValue(json, Student.class);
        System.out.println("Input json string");
        System.out.println(json);
        System.out.println("Generated java class: ");
        System.out.println(effectiveJava);
    }
}
  
class Student {
    private String name;
    private String id;
    private String school;
  
    public Student()
    {
        // no argument constructor required by Jackson
    }
  
    public Student(String name, String id, String school)
    {
        this.name = name;
        this.id = id;
        this.school = school;
    }
    // getters and setters
    public String getID() { return id; }
  
    public void setID(String id) { this.id = id; }
  
    public String getName() { return name; }
  
    public void setName(String id) { this.name = name; }
  
    public String getSchool() { return school; }
  
    public void setSchool(String id) { this.id = id; }
  
    @Override public String toString()
    {
        return "Student{"
            + "name='" + name + '\'' + ", id='" + id + '\''
            + ", school='" + school + '\'' + '}';
    }
}


Output :

Input json string
 {
   "name" : "Jack Ryan",
   "id" : "2019071075",
   "school" : "St. Jude's School",
   "section" : "B" 
  } 
 Generated java class:
 Student [name=Jack Ryan, id=2019071075, school=St. Jude's School]

Output Explanation:

The approach of configuring the object mapper in line with a dependency injection framework, ensuring that the same object mapper is used throughout the whole system, will guarantee the extinction of the exception throughout the application, but leaving the developers blindfolded in relation to the evolves that occur in API being consumed.

However, the preferred approach is to ignore unknown properties at the class level using @JsonIgnoreProperties(ignoreUnknown = true) and only do this on the ObjectMapper level if you can’t annotate your class with this annotation i.e. you don’t own the class. It’s also a best practice to annotated your model class with @JsonIgnoreProperties to avoid issues.

RELATED ARTICLES

Most Popular

Recent Comments