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:
{"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:
public CourseResult getCourseResult(Integer id) {
String uriTemplate = apiUrl + "?id={id}";
RestTemplate template = new RestTemplate();
List> messageConverters = template.getMessageConverters();
List> converters = new ArrayList>(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:
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:
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.