how to convert LinkedHashMap to Custom java object?

前端 未结 3 1176
孤独总比滥情好
孤独总比滥情好 2020-12-29 21:49

I\'m trying to get the data from one app to another via RESTful WS and it works, but I cannot use this data since I cannot cast it... WS returns a List of objects like this:

相关标签:
3条回答
  • 2020-12-29 22:09

    import:

    import com.fasterxml.jackson.databind.ObjectMapper;
    

    object:

    private ObjectMapper mapper = new ObjectMapper();
    

    examples:

    PremierDriverInfoVariationDTO premierDriverInfoDTO = 
    mapper.convertValue(json, PremierDriverInfoVariationDTO.class); 
    log.debug("premierDriverInfoDTO : {}", premierDriverInfoDTO);
    

    or

    Map<String, Boolean> map = mapper.convertValue(json, Map.class);
    log.debug("result : {}", map);
    assertFalse(map.get("eligiblePDJob"));
    
    0 讨论(0)
  • 2020-12-29 22:11

    You need to do this:

    List<ConsultantDto> myObjects =
        mapper.readValue(jsonInput, new TypeReference<List<ConsultantDto>>(){});
    

    (From this SO answer)

    The reason you have to use TypeReference is because of an unfortunate quirk of Java. If Java had a proper generics, I bet your syntax would have worked.

    0 讨论(0)
  • 2020-12-29 22:22

    In my use case, I had 10 different APIs. All my API Responses were in the same json format but the content was different in one of the tags - /result/data

    {
        "success": true,
        "result": {
            "type": "transactions",
            "data": {}
        },
        "error": [],
        "metadata": {
            "version": "v1",
            "code": 200,
            "desc": "OK",
            "trackingId": "TRACKINGID-1588097123800-1234567890",
            "generatedTimestamp": "2020-07-14T09:41:06.198Z"
        },
        "link": {
            "self": "/v1/myapp/customer/enquiry"
        }
    }
    

    In my spring boot code, I used the following generic method for all my API calls -

    <T, R> ApiResponse<R> execute(URI uri, T entity, Class<R> clazz) {
        HttpEntity<T> httpEntity = new HttpEntity<>(entity);
        ApiResponse<R> body = this.restTemplate.exchange(uri, HttpMethod.POST, httpEntity,
                new ParameterizedTypeReference<ApiResponse<R>>() {
                }).getBody();
        return body;
    }
    

    It gave me the same error as you reported above. Based on this and some other SO answers, I tried the below as well and it did not work -

    <T, R> ApiResponse<R> execute(URI uri, T entity, Class<R> clazz) {
        HttpEntity<T> httpEntity = new HttpEntity<>(entity); 
        ResponseEntity<String> response = this.scVaultCoreApi.exchange(uri, HttpMethod.POST, httpEntity, String.class);
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(response.getBody(), new TypeReference<ApiResponse<R>>() {
            });
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
    

    The other solution that worked was manually parsing the response stream using the ObjectMapper in jackson. But I couldn't do that for so many APIs I was using and the above error came in some APIs calls only. So, only for those APIs, instead of relying on the TypeReference conversion to the Class, I did not change the above methods that I defined, but I extracted the ApiResponse<T> as ApiResponse<Object> and parsed it as a LinkedHashMap only and created my particular class object manually.

    ApiResult<MyResponse> res = execute(uri, payload, MyResponse.class).getResult();
    Map<String, Map<String, Object>> map = (Map<String, Map<String, Object>>) res.getData();
    MyResponse myResponse = MyResponse.builder()
        .accountBalance(new BigDecimal(map.get("key").get("balance").toString()))
        .clientName((String) map.get("key").get("clientName"))
        .build();
        
    

    Best thing about this solution was that I did not have to change the base class execute method and the other API calls were working fine and only for the troubled API, I wrote the manual object creation code.

    0 讨论(0)
提交回复
热议问题