udith
udith

Reputation: 302

Json string to Java object with dynamic keys

I want to insert a REST API response to java object. My sample response as below.

    {
        "key1": [
          {
            "name": "test1",
            "id": "id1",            
          }
        ],
        "key2": [
          {
            "name": "test2",
            "id": "id2",            
          },
          {
            "name": "test3",
            "id": "id3", 
          }
        ]
      }

For that I created "User" class for repeating object

@Data
public class User {
    private String name;
    private String id;    
}

API response body only accept Class<T> and for that I parsed Map.class to that function as I want to insert json response data to Map<String, List<User>> instead of java class object.

public Mono<Map> getUserInfo(String number) {
        return apiAdaptor.getRequest(urlConfiguration.getUserApi(), Map.class, true
                , number);
    }


public <T> Mono<T> getRequest(String url, Class<T> responseClass, boolean isDds,
                                  String... urlArgs) {
        return Mono.just(this.accessToken)
                .flatMap(token -> this.webClient.get()
                        .uri(url, urlArgs)                     
                        .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                        .exchange()
                        .flatMap(clientResponse -> getClassResponse(clientResponse, responseClass, isDds))                        
                );
    }


private UserResponse handleSuccess(Map map) {        
        Map<String, List<User>> apiRes = map;
}

But when I looping through API response (apiRes) it gave "java.util.LinkedHashMap cannot be cast to User". As I checked, if Jackson cannot identified the exact format it will automatically converted to "LinkedHashMap". Please help.

Please note that I'm new to java development.

Upvotes: 1

Views: 2021

Answers (2)

pirho
pirho

Reputation: 12235

One trick is to declare class of its own to preserve generic types to be compiled and casted correctly. So like:

@SuppressWarnings("serial")
public class DynKeyUserMap extends HashMap<String, List<User>> {}

Then instead of using Map.class use DynKeyUserMap.class to prevent casting problems.

Upvotes: 2

vishnu g
vishnu g

Reputation: 109

I am not sure which Httpclient you are using for your development. However with a RestTemplate Client you do as below

Map<String, List<User>> responseMap= new HashMap<>();
ResponseEntity<Map<String, List<User>>> response =new RestTemplateBuilder().build().getForEntity(url, responseMap.getClass());

I used the builder so that default message converters are used.

Upvotes: 0

Related Questions