Spring’s RestTemplate, Jackson’s JSON deserializing and inner classes
In trying to use Spring 3’s RestTemplate that every article about says is braindead easy, I hit upon a limitation that’s taken me a few hours to iron out.
JSON I am trying to consume:
1 | {"results":[{"id":"1","details":{"title":"First Instructions","alternateTitle":"","location":"3","beginDate":"2002-12-03 15:04:00","endDate":"2003-02-27 03:00:00","frequency":"0","teacher":"1","program":"1","description":"","fees":"","status":"0"}}]} |
Hastily written service method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public CourseResult getCourseResult(Integer id) { String uriTemplate = apiUrl + "?id={id}"; RestTemplate template = new RestTemplate(); List<HttpMessageConverter<?>> messageConverters = template.getMessageConverters(); List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(messageConverters); MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter(); converters.add(jsonConverter); template.setMessageConverters(converters); TclApiResponse response = template.getForObject(uriTemplate, TclApiResponse.class, String.valueOf(id)); return response.getCourseResults()[0]; } |
Domain Object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class TclApiResponse { private CourseResult[] courseResults; public CourseResult[] getCourseResults() { // TODO Auto-generated method stub return courseResults; } public void setCourseResults(CourseResult[] courseResults) { this.courseResults = courseResults; } public class CourseResult { Integer id; Details details; [getters and setters]... } public class Details { ... } } |
I was following along with the process described in http://dlinsin.blogspot.com/2009/11/playing-with-spring-resttemplate.html, with the “real” target domain object encased in a wrapper object (in this case TclApiResponse), and kept getting the consistent error:
1 2 3 4 5 6 | org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [org.tcl.service.TclApiResponse] and content type [application/json] at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:77) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:446) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401) at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:199) ... |
After much trial and error, I finally tried separating out the domain class into distinct, non-inner classes and it started working. With a 20/20 hindsight Google search, I found 1 blog that mentions this:
http://mangayaa.blogspot.com/2009/08/jackson-json-processor.html
Hopefully this saves someone some time.


