Home > Enterprise >  Deserialize json object which properties can be changed each time
Deserialize json object which properties can be changed each time

Time:12-13

I have the following json content:

{
      "arguments": {
        "key" : "value"
      }
}

But, it can dynamically change depending on the specified configuration of the json file.

For example once can be like above, but sometimes it can be empty arguments: {} or something it may be configured something like this:

      "arguments": {
        "someKeyName" : "someValue"
      }

or even:

      "arguments": {
        "someKeyName": "someKeyValue",
        "someKeyName2": "someKeyValue2"
      }

My question is, how can I handle the deserialization with Jackson's object mapper or some other alternative, without knowing what would the properties be of the arguments object each time I have to handle the deserialization ?

CodePudding user response:

You can de-serialize it into a Map<String, Object> and you will always get a map but its internal content would be different each time. you can do something like this:

Map<String, Object> data = objectReader.forType(Map.class).readValue(jsonString);

BTW, I wrote my own JsonUtils class which is a thin wrapper over JSON-Jackson library that simplifies a bit serializing and deserializing JSON strings. reading a simple map would look like:

Map<String, Object> map = JsonUtils.readObjectFromJsonString("{\"a\": \"b\"}", Map.class);

But with my class you don't need to instantiate and configure ObjectMapper instance. Here is JsonUtils Javadoc. If you want to use it this class is part of Open source MgntUtils library written and maintained by me. You can get MgntUtils library as Maven artifact or on Github (including source code and Javadoc)

CodePudding user response:

Assume (spring-boot-starter ):

package com.example.demo;

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

@Getter
public class Dto {

  final Map<String, Object> arguments = new HashMap<>();

  public Map<String, Object> getArguments() {
    return arguments;
  }
}

..then we can (already) test:

package com.example.demo;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoJacksonApplicationTests {

  @Autowired
  ObjectMapper objectMapper;

  @Test
  void test1() throws JsonProcessingException {
    Dto dto = objectMapper.readValue(
        """
        {
          "arguments": {
            "key" : "value"
          }
        }
        """, Dto.class);
    assertEquals("value", dto.getArguments().get("key"));
  }

  @Test
  void test2() throws JsonProcessingException {
    Dto dto = objectMapper.readValue(
        """
        {
          "arguments": {
            "someKeyName" : "someValue"
          }
        }
        """, Dto.class);
    assertEquals("someValue", dto.getArguments().get("someKeyName"));
  }

  @Test
  void test3() throws JsonProcessingException {
    Dto dto = objectMapper.readValue(
        """
        {
          "arguments": {
            "someKeyName": "someKeyValue",
            "someKeyName2": "someKeyValue2"
          }
        }
        """, Dto.class);
    assertEquals("someKeyValue", dto.getArguments().get("someKeyName"));
    assertEquals("someKeyValue2", dto.getArguments().get("someKeyName2"));
  }
}
  • Related