Search code examples
javaspringapipojo

Spring mapping JSON to java POJO


I have API which returns JSON in this format:

[
    { "shrtName": "abc", "validFrom": "2016-10-23", "name": "aaa", "version": 1 },
    { "shrtName": "def", "validFrom": "2016-11-20", "name": "bbb", "version": 1 },
    { "shrtName": "ghi", "validFrom": "2016-11-22", "name": "ccc", "version": 1 }   
]

I have this code which reads API and returns it as a String. But I want to read this API and map it into the Java POJO class.

public String downloadAPI(){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.set("API-Key", "4444444-3333-2222-1111-88888888"); 
        HttpEntity<?> requestEntity = new HttpEntity<Object>(headers);
        String URL = "https://aaaaaaa.io/api/v1/aaaaaaaaa?date=2015-04-04;
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
        ResponseEntity<String> response = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, String.class);
        return response.getBody();
}

My questions:
1) Format of POJO?
2) Changes in my method (return type POJO instead of String)


Solution

  • Your JSON is an array that's why []

    Create POJO

    public class MyPOJO {
        private String shrtName;
        private Date validFrom;
        private String name;
        private int version;    
    }
    

    Remove message converter and refactor restTemplate exchange method to

    ResponseEntity<MyPOJO[].class> response = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, MyPOJO[].class);
    

    This is generic function that I use for GET requests

        public <T> T getRequestAndCheckStatus(final String url, final Class<T> returnTypeClass,
                                              final List<MediaType> mediaTypes,
                                              final Map<String, String> headerParams,
                                              final Map<String, Object> queryParams) throws Exception {
    
            final HttpHeaders headers = new HttpHeaders();
            headers.setAccept(mediaTypes);
            setHeaderParamsIfExists(headers, headerParams);
            final HttpEntity<String> requestEntity = new HttpEntity<>(headers);
    
            UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
            setQueryParamsIfExists(uriBuilder, queryParams);
    
            final ResponseEntity<T> entity = restTemplate
                    .exchange(getUrl(uriBuilder),
                              HttpMethod.GET,
                              requestEntity,
                              returnTypeClass);
    
            Assert.assertEquals(HttpStatus.OK, entity.getStatusCode());
            return entity.getBody();
        }
    
        private void setHeaderParamsIfExists(HttpHeaders headers, Map<String, String> headerParams) {
            if(headerParams != null && !headerParams.isEmpty())
                headerParams.entrySet()
                        .forEach(entry -> headers.set(entry.getKey(), entry.getValue()));
        }
    
        private void setQueryParamsIfExists(UriComponentsBuilder uriBuilder, Map<String, Object> queryParams) {
            if(queryParams != null && !queryParams.isEmpty())
                queryParams.entrySet()
                        .forEach(entry -> uriBuilder.queryParam(entry.getKey(), entry.getValue()));
        }
    
        private URI getUrl(UriComponentsBuilder uriBuilder) {
            return uriBuilder.build().encode().toUri();
        }
    

    In your case you would call it by

        getRequestAndCheckStatus("https://aaaaaaa.io/api/v1/aaaaaaaaa", MyPOJO[].class,                    
                                 Collections.singletonList(MediaType.APPLICATION_JSON_UTF8), 
                                 new HashMap<String, String>(){{ put("API-Key", "4444444-3333-2222-1111-88888888"); }}), 
                                 new HashMap<String, Object>(){{ put("Date", "2015-04-04"); }});
    
    • Additionaly, for Date I recommend to use long and then in controller parse it to Date. I see that you use https protocol, have you configured certificate ?