Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>@Tom: I don't think creating a custom MarshallingHttpMessageConverter will do you any good. The built-in converter is returning you the right class (Exception class) when the service fails, but it is the <code>RestTemplate</code> that doesn't know how to return Exception class to the callee because you have specified the response type as Job class.</p> <p>I read the <a href="http://www.jarvana.com/jarvana/view/org/springframework/spring-web/3.0.2.RELEASE/spring-web-3.0.2.RELEASE-sources.jar!/org/springframework/web/client/RestTemplate.java?format=ok" rel="nofollow">RestTemplate source code</a>, and you are currently calling this API:-</p> <pre><code>public &lt;T&gt; T postForObject(URI url, Object request, Class&lt;T&gt; responseType) throws RestClientException { HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(request, responseType); HttpMessageConverterExtractor&lt;T&gt; responseExtractor = new HttpMessageConverterExtractor&lt;T&gt;(responseType, getMessageConverters()); return execute(url, HttpMethod.POST, requestCallback, responseExtractor); } </code></pre> <p>As you can see, it returns type T based on your response type. What you probably need to do is to subclass <code>RestTemplate</code> and add a new <code>postForObject()</code> API that returns an Object instead of type T so that you can perform the <code>instanceof</code> check on the returned object.</p> <p><strong>UPDATE</strong></p> <p>I have been thinking about the solution for this problem, instead of using the built-in <code>RestTemplate</code>, why not write it yourself? I think that is better than subclassing <code>RestTemplate</code> to add a new method. </p> <p>Here's my example... granted, I didn't test this code but it should give you an idea:-</p> <pre><code>// reuse the same marshaller wired in RestTemplate @Autowired private Jaxb2Marshaller jaxb2Marshaller; public Object genericPost(String url) { // using Commons HttpClient HttpClient client = new HttpClient(); PostMethod method = new PostMethod(url); // add your data here method.addParameter("data", "your-data"); try { int returnCode = client.executeMethod(method); // status code is 200 if (returnCode == HttpStatus.SC_OK) { // using Commons IO to convert inputstream to string String xml = IOUtil.toString(method.getResponseBodyAsStream()); return jaxb2Marshaller.unmarshal(new StreamSource(new ByteArrayInputStream(xml.getBytes("UTF-8")))); } else { // handle error } } catch (Exception e) { throw new RuntimeException(e); } finally { method.releaseConnection(); } return null; } </code></pre> <p>If there are circumstances where you want to reuse some of the APIs from <code>RestTemplate</code>, you can build an adapter that wraps your custom implementation and reuse <code>RestTemplate</code> APIs without actually exposing <code>RestTemplate</code> APIs all over your code.</p> <p>For example, you can create an adapter interface, like this:-</p> <pre><code>public interface MyRestTemplateAdapter { Object genericPost(String url); // same signature from RestTemplate that you want to reuse &lt;T&gt; T postForObject(String url, Object request, Class&lt;T&gt; responseType, Object... uriVariables); } </code></pre> <p>The concrete custom rest template looks something like this:-</p> <pre><code>public class MyRestTemplateAdapterImpl implements MyRestTemplateAdapter { @Autowired private RestTemplate restTemplate; @Autowired private Jaxb2Marshaller jaxb2Marshaller; public Object genericPost(String url) { // code from above } public &lt;T&gt; T postForObject(String url, Object request, Class&lt;T&gt; responseType, Object... uriVariables) { return restTemplate.postForObject(url, request, responseType); } } </code></pre> <p>I still think this approach is much cleaner than subclassing <code>RestTemplate</code> and you have more control on how you want to handle the results from the web service calls.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload