Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I deserialize a JSON to a Java class which has known mandatory fields, but can have several unknown fields?

I have an input JSON which has fields what I sure inside. But, I need a flexibility to add several extra fields. I don't know the name of the extra fields, but I have to handle it.

I was thinking adding a MaP field which contains all of extra fields, but the inputs are not mapped into this field.

I want to deserialize the JSON in a Dropwizard endpoint.

Is there a way to do with Jackson?

Example:

JSON payload 1:

{
  "first_name": "John",
  "last_name": "Doe",
  "date_of_birth": "01/01/1990",
  "postcode": "1234"
}

JSON payload 2:

{
  "first_name": "Alice",
  "last_name": "Havee",
  "phone_no": 012345678,
  "passport_no": "AB 123456"
}

Later on JSON payload 3 can have even different fields.

Java DTO:

public class PersonDTO {

    // mandatory field
    private String firstName;

    // mandatory field
    private String lastName;

    // Unknown optional fields?

    // No args constructor
    // Getters
    // Setters
}
like image 566
LordSerius Avatar asked Jul 17 '19 17:07

LordSerius


People also ask

How do I ignore unrecognized fields Jackson?

You can ignore the unrecognized fields by configuring the ObjectMapper class: mapper. configure(DeserializationFeature. FAIL_ON_UNKNOWN_PROPERTIES, false);

How do you serialize and deserialize JSON object in Java?

Deserialization in the context of Gson means converting a JSON string to an equivalent Java object. In order to do the deserialization, we need a Gson object and call the function fromJson() and pass two parameters i.e. JSON string and expected java type after parsing is finished.

How do I deserialize JSON?

A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.

What is JSON serialization and deserialization in Java?

JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).


2 Answers

You can use JsonAnySetter annotation:

class PersonDTO {

    @JsonProperty("first_name")
    private String firstName;

    @JsonProperty("last_name")
    private String lastName;

    private Map<String, String> extras = new HashMap<>();

    @JsonAnySetter
    public void setExtras(String name, String value) {
        this.extras.put(name, value);
    }

    // No args constructor
    // Getters
    // Setters
}

See also:

  • JSON Jackson deserialization multiple keys into same field
  • Adding a dynamic json property as java pojo for jackson
  • How to use dynamic property names for a Json object
like image 68
Michał Ziober Avatar answered Oct 16 '22 13:10

Michał Ziober


There are couple of things that you can do if you are using Jackson:-

  1. You can make use of @JsonAnyGetter and @JsonAnySetter annotation and create your class as:-

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;

import java.util.HashMap;
import java.util.Map;

public class PersonDTO {

    // mandatory field
    private String firstName;

    // mandatory field
    private String lastName;

    // Unknown optional fields?
    // Capture all other fields that Jackson do not match other members
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

    // No args constructor
    // Getters
    // Setters
}
  1. If you don't want the unknown fields in your PersonDTO then you can simply ignore unknown properties using annotation @JsonIgnoreProperties at class level eg
@JsonIgnoreProperties(ignoreUnknown = true)
public class PersonDTO { //TODO:- }
  1. The ObjectMapper can also be configured to ignore unknowns e.g.:-
new ObjectMapper()
  .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
like image 20
Ajay Avatar answered Oct 16 '22 14:10

Ajay