Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RestTemplate + Jackson

I want to use Spring's RestTemplate plus Jackson to consume a WebService. I have followed several tutorials and have come to the point of creating the DAOs. This is the method where I get all of my domain objects:

// Create a Rest template
RestTemplate restTemplate = new RestTemplate();

// Create a list for the message converters

List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();

// Add the Jackson Message converter
messageConverters.add(new MappingJacksonHttpMessageConverter());

// Add the message converters to the restTemplate
restTemplate.setMessageConverters(messageConverters);

List<Station> resultList = Arrays.asList(restTemplate.getForObject(BASE_URL, Station[].class));

return resultList;

But my Web Service does not return an array of Station objects right away, but rather a more semantic expression in this way:

{"success":true,"message":"Records Retrieved Successfully","data":{"totalCount":"14","stations":[{"id":"1264","station":"Station 1","idJefatura":"1","syncDate":"2013-01-24 13:20:43"}, ...] }}

So my problem is, I'm not sure how to "tell" RestTemplate to parse the object list right after the "stations" indicator, without creating an ad hoc object, which does not seem like the proper solution.

Is there any way to specify the right syntax for RestTemplate?

EDIT: I created a wrapper object like this:

public class RestResponseObject {

    private boolean success;
    private String message;
    private Data data;

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public class Data {
        private int totalCount;
        private List<Station> stations;

        public int getTotalCount() {
            return totalCount;
        }

        public void setTotalCount(int totalCount) {
            this.totalCount = totalCount;
        }

        public List<Station> getStations() {
            return stations;
        }

        public void setStations(List<Station> estaciones) {
            this.stations= estaciones;
        }
    }
}

But I am struggling as to how to make this object generic, since the key name of my object list in the JSON response is dependant of that domain object's class.

like image 802
MichelReap Avatar asked Aug 20 '13 06:08

MichelReap


People also ask

Does RestTemplate use Jackson?

The RestTemplate uses the Jackson to create a Jackson java bean from the provided JSON. This bean is returned to the DataProvider. The DataProvider maps the Jackson bean to our own java bean, the data bean, and returns this to the calling application.

Is RestTemplate getting deprecated?

RestTemplate will still be used. But in some cases, the non-blocking approach uses much fewer system resources compared to the blocking one.

Does RestTemplate use ObjectMapper?

So, by simply using the RestTemplateBuilder our RestTemplate will automatically use a MappingJackson2HttpMessageConverter configured with an ObjectMapper that uses the required ParameterNamesModule.


1 Answers

There are two solutions here:

  1. You can write your own Deserializer implementation, where you parse the JSON and take only the station list and convert it to the List object. The Deserializer can be set on the RestTemplate. Have a look at how to write custom desrializer for Jackson
  2. The other thing what you can do is to write a class which maps the Rest response. This class should contain the List object as a member variable. Then Spring by default will convert to the new class and you can get the stations from that class.

Here is an example.

The response class

public class MyResponseClass {
      // other variables
     private List<Station> stations; //it getters and setters
}

In the Rest Client

MyResponseClass response = restTemplate.getForObject(BASE_URL, MyResponseClass.class)
List<Station> resultList = response.getStations()
like image 93
Dhanush Gopinath Avatar answered Nov 09 '22 18:11

Dhanush Gopinath