Dynamic Json string to Java Object

1.1k Views Asked by At

How would you map this JSON string with dynamic properties to a Java object?

{    
    'name' : 'John',
    'lastname': 'Doe',
    'dynamicProperty1': { 'label' : 'size', 'value': 'large'},
    'dynamicProperty2': { 'label' : 'color', 'value': 'blue'},
    'dynamicProperty3': { 'label' : 'height', 'value': 200},
    'dynamicProperty...': { 'label' : 'points', 'value': 300}
}
2

There are 2 best solutions below

4
On

you can implement a Java class to hold name, lastName and hashmaps to store dynamic properties. Example -

public class Person {
   String name;
   String lastName;
   Map<String,Object> dynamicProperty1;
   Map<String,Object> dynamicProperty2;
   Map<String,Object> dynamicProperty3;
}

Or if you have the variable amount of dynamic property maps ( as suggested in the comments), you can do something like below

public class Person {
   String name;
   String lastName;
   Map<String,Map<String, Object>> dynamicPropertyMaps;
 }

And then inside your mapper class, you can create hashmaps based on the values in JSON and put them in the dynamicPropertyMaps Map.

0
On

You can use JsonAnySetter annotation:

import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public class HandleDynamicKeysInJsonApp {

    public static void main(String[] args) throws IOException {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();

        Person person = mapper.readValue(jsonFile, Person.class);
        System.out.println(person);
    }
}

@Data
class Person {
    private String name;

    @JsonProperty("lastname")
    private String lastName;

    private Map<String, Label> labels = new LinkedHashMap<>();

    @JsonAnySetter
    public void addDynamicProperties(String key, Label label) {
        labels.put(key, label);
    }
}

@Data
class Label {
    private String label;
    private Object value;
}