Peter
Peter

Reputation: 275

Spring Boot: Convert complex json string response to object

I want to convert a complex json string–which I get from a GET request–to our database. I need to loop through all the objects and find some specific ones. The problem is that all objects are different in some way. They could look like these three examples, but there are many more:

{
  "created": 1493209170473990,
  "id": "fu:9843464EDF4D053072ACEAC2362EE0D8",
  "type": "user-created"
},
{
  "created": 1493209170883075,
  "data": {
    "process_type": "wallet-tx"
  },
  "id": "fu:6BE085BF29D7C8AF4C238615CA85F31A",
  "process": "0CEB2F401E0FB9D9A44A124D0710B521",
  "type": "process-created"
},
{
  "created": 1495535185484487,
  "data": {
    "message": "electronic delivery"
  },
  "document": "25FBED0A80FEEBD6FF154D21D8E35D7E",
  "id": "fu:3C17584381C0AFB4836F73057DB7DEAB",
  "type": "info"
}

I need to find some objects with a specific type, but I cant get them out of a string. I get the request data with this call:

@RequestMapping(value="/events", method=RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
public String getEvents() {

    int created_after = 0;

    final String url = server + "/rest/client/events/" + created_after;

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/json; charset=utf-8");
    headers.set("Auth-Token", token); // user_token

    HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);

    ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

    return response.getBody();
}

I use Angular in my frontend, which could easy convert the string to an Object, but then I have to pass this again to my backend to work with the data. I want to keep everything in the backend. Do you have any idea how to solve it?

If you need more information, please ask. Thanks

EDIT: My JSON output looks like this:

[
  {
    "created": 1493209170473990,
    "id": "fu:9843464EDF4D053072ACEAC2362EE0D8",
    "type": "user-created"
  },
  {
    "created": 1493209170653925,
    "data": {
      "verify_id": "12581C42DD2DF7D80F802C50ABD144F8"
    },
    "id": "fu:06111B0A9C5B760B9269044DA97D3D6F",
    "type": "post-address-verification-confirmed"
  },
  {
    "created": 1493209171320041,
    "data": {
      "after": {
        "attempt": 1
      }
    },
    "id": "fu:7B5B2AD57C1CE97BB642931C2C3C819D",
    "process": "0CEB2F401E0FB9D9A44A124D0710B521",
    "type": "process-updated"
  },
...
]

Upvotes: 4

Views: 40892

Answers (2)

Alex Savitsky
Alex Savitsky

Reputation: 2371

The way I understand it, your objects have some common properties, as well as some optional ones. You can model the optional properties using @JsonAnyGetter and @JsonAnySetter:

class Data {
    @JsonProperty
    private Long created;
    @JsonProperty
    private String id;
    @JsonProperty
    private String type;
    private Map<String, Object> optional = new HashMap<>();
    public Data() { // empty public constructor is required
    }
    // getters/setters for all properties omitted for brevity
    @JsonAnySetter
    public void addOptional(String name, Object value) {
        optional.put(name, value);
    }
    @JsonAnyGetter
    public Object getOptional(String name) {
        return optional.get(name);
    }
}

Then you can deserialize your objects using

ObjectMapper objectMapper = new ObjectMapper();
Data data = objectMapper.readValue(j, Data.class);

or, if you've got an array of your Data objects as input,

Data[] data = objectMapper.readValue(j, Data[].class);

All properties except created, id and type will be placed in the optional map.

Upvotes: 7

Plog
Plog

Reputation: 9622

If you don't know what the structure of the JSON is going to be then you can serialize your JSON string to a Map which maps the field names in the json to their value.

This can be done using the Jackson ObjectMapper:

String jsonObject = <the string JSON response you obtained>;

ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> jsonMap = objectMapper.readValue(jsonString,
    new TypeReference<Map<String, Object>>(){});

If it's a list of JSON objects you expect then you can first map this to an array of JSON strings and then convert each one to a map:

ObjectMapper objectMapper = new ObjectMapper();
String[] jsonStrings = objectMapper.readValue(jsonString, String[]);
List<Map<String, Object>> jsonMaps = new ArrayList<>();
for (String json : jsonStrings) {
    jsonMaps.add(objectMapper.readValue(json, 
            new TypeReference<Map<String, Object>>(){});
}

Upvotes: 6

Related Questions