Search code examples
javajsonspringresttemplate

How can I associate JSON object of the api response to java classes when having the intermediate json "data" attribute?


Thank you for clicking here. I have an JSON REST API (providing by Directus CMS). All API responses contains a json object with a "data" attribute containing what I want.

{
    "data": {
        "id": 1,
        "status": "published",
        "sort": null,
        "user_created": "5a91c184-908d-465e-a7d5-4b648029bbe0",
        "date_created": "2022-04-26T09:43:37.000Z",
        "user_updated": "5a91c184-908d-465e-a7d5-4b648029bbe0",
        "date_updated": "2022-05-30T14:23:50.000Z",
        "Titre": "Réseaux Sociaux",
        "Description": "Retrouvez les dernières news en direct sur nos réseaux sociaux!",
        "Lien": "https://www.instagram.com/univlorraine/",
        "ImageArrierePlan": "f23ffd53-7244-4439-a8cf-41bd0fd3aa72",
        "Erreur_Bloc": null
    }
}

This data attribute can be a object or a list of objects depending the request.

I have a Java Spring application with a service consuming the API. I'm using RestTemplate with exchange method.

public Object callAPI(String url, HttpMethod httpMethod, Object body, MultiValueMap<String, String> headers, Class<?> classe) {
    final RestTemplate rt = new RestTemplate();
    try {
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        rt.setRequestFactory(requestFactory);
        final HttpEntity<?> request = new HttpEntity<>(body, headers);
        final ResponseEntity<?> response = rt.exchange(url, httpMethod, request, classe);
        if (response.getStatusCode().equals(HttpStatus.OK)) {
            return response.getBody();
        }
        else return response.getStatusCode();
    } catch (final Exception e) {
        System.out.println(e);
        return null;
    }
}

In the exchange method I pass an existing class to directly link response data with the provided class. The probleme is that I have this data attribute which prevents me from linking the data.

Does anyone have a solution to this probleme please?

----UPDATE----

Thanks to the response of AlbiKai, I created a generic Wrapper class :

public class Wrapper<T> {
    private T data;

    public void set(T data) {
        this.data = data;
    }

    public T get() {
        return data;
    }
}

I then tried to put this Wrapper in the exchange :

    public <classe> Object callAPI(String url, HttpMethod httpMethod, Object body, MultiValueMap<String, String> headers, Class<?> classe) {
        final RestTemplate rt = new RestTemplate();
        try {
            HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
            rt.setRequestFactory(requestFactory);
            final HttpEntity<?> request = new HttpEntity<>(body, headers);
            final ResponseEntity<?> response = rt.exchange(url, httpMethod, request, Wrapper<classe>.class);

But I get the error "Cannot select from parameterized type" on the Wrapper :/


Solution

  • I gave up with the Wrapper etc... I just pass a String class and work with it in my controllers to delete this "data" property and map the string with a class.

    Service :

        public String callAPI(String url, HttpMethod httpMethod, Object body, MultiValueMap<String, String> headers) {
            final RestTemplate rt = new RestTemplate();
            try {
                HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
                rt.setRequestFactory(requestFactory);
                final HttpEntity<?> request = new HttpEntity<>(body, headers);
                final ResponseEntity<String> response = rt.exchange(url, httpMethod, request, String.class);
                if (response.getStatusCode().equals(HttpStatus.OK)) {
                    return response.getBody();
                }
                else return response.getStatusCode().toString();
            } catch (final Exception e) {
                System.out.println(e);
                return null;
            }
        }
    

    One controller :

        public List<BlocInformation> getBlocInformation() {
            String url = "http://localhost:8055/items/bloc_information/?fields=*,Erreur_Bloc.*";
            final RestAPIService blocService = new RestAPIService();
            String response = blocService.callAPI(url, HttpMethod.GET, null, null);
            if (response != null) {
                String result = response.substring(8, response.length() - 1);
                ObjectMapper mapper = new ObjectMapper();
                List<BlocInformation> blocInformationList = null;
                try {
                    blocInformationList = Arrays.asList(mapper.readValue(result, BlocInformation[].class));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return blocInformationList;
            }
            return null;
        }