skip to Main Content

I have the following json that I want to serialize and deserialize.

{
  "name1": {
    "key1": "value1",
    "key2": "value2"
  }
}

Is it possible to use a key (eg. "name1" instead of "properites") as the name property in the java object either with annotation or with custom (de)serializer?

@lombok.Data
public class Example {

    private String name;

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

    public Example(String name) {
        this.name = name;
    }

    public void add(String attr1, String val1) {
        properties.put(attr1, val1);
    }

    public static void main(String[] args) throws JsonProcessingException {
        Example bean = new Example("name1");
        bean.add("key1", "value1");
        bean.add("key2", "value2");

        String result = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(bean);
        System.out.println(result);
    }
}

The result without any config is the following:

{
  "name" : "name1",
  "properties" : {
    "key1" : "value1",
    "key2" : "value2"
  }
}

2

Answers


  1. I’m not sure why you think you need the String name, this produces the JSON you want:

    public class Example {
    
        @JsonProperty("name1")
        private Map<String,String> properties = new HashMap<>();
    
    
        public void add(String attr1, String val1) {
            properties.put(attr1, val1);
        }
    
        public static void main(String[] args) throws JsonProcessingException {
            Example bean = new Example();
            bean.add("key1", "value1");
            bean.add("key2", "value2");
    
            String result = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(bean);
            System.out.println(result);
        }
    }
    
    Login or Signup to reply.
  2. If the JSON property "name1" is just an example and can vary (not known ahead of time), this might be what you’re looking for:

    @ToString
    public class Example {
    
        @JsonIgnore
        private String name;
    
        @JsonIgnore
        private Map<String, Map<String,String>> properties;
    
        public Example() {
            properties = new HashMap<>();
        }
    
        public Example(String name) {
            this();
            this.name = name;
            properties.put(name, new HashMap<>());
        }
    
        public void add(String attr1, String val1) {
            properties.get(name).put(attr1, val1);
        }
    
        @JsonAnyGetter
        public Map<String, Map<String, String>> getProperties() {
            return properties;
        }
    
        @JsonAnySetter
        public void setProperties(String name, Map<String,String> props) {
            this.name = name;
            this.properties.put(name, props);
        }
    
        public static void main(String[] args) throws JsonProcessingException {
            Example bean = new Example("name1");
            bean.add("key1", "value1");
            bean.add("key2", "value2");
    
            ObjectMapper objectMapper = new ObjectMapper();
            String result = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bean);
            System.out.println(result);
    
            Example parsed = objectMapper.readValue(result, Example.class);
            System.out.println(parsed);
        }
    }
    

    The output of that is:

    {
      "name1" : {
        "key1" : "value1",
        "key2" : "value2"
      }
    }
    
    Example(name=name1, properties={name1={key1=value1, key2=value2}})
    

    The keys to this working are @JsonAnyGetter and @JsonAnySetter which are generally for serializing/deserializing arbitrary properties that don’t have dedicated, named fields or getters.

    By using @JsonIgnore on the fields themselves, this allows the "dynamic" properties to shine through instead of the internal representation of the Java object.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search