2

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}
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • As a clarification, you seem to be hinting the properties would be follow a particular naming conventions, but is it safe to assume that you might have any number of unknown fields names? `...'cat': {...}, 'dog':{...}...` – hdost Dec 09 '20 at 06:28
  • Either way if you have control over this data model I'd suggest for simplicity to move all your dynamic properties into a list of instead like `dynamicProperties: [{...},{...},{...}]` – hdost Dec 09 '20 at 06:35
  • @hdost, I have no control over the dynamic properties. those dynamic property can go from 0 up to 100. – alvagenesis Dec 09 '20 at 07:08
  • 1
    Does this answer your question? [Jackson deserialization with unknown dynamic properties](https://stackoverflow.com/questions/17685508/jackson-deserialization-with-unknown-dynamic-properties) – hdost Dec 10 '20 at 11:29

2 Answers2

2

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;
}
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
0

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.