Note that there are some explanatory texts on larger screens.

plurals
  1. POSpring RestTemplate Behavior when handling responses with a status of NO_CONTENT
    primarykey
    data
    text
    <p>Okay, I have a class NamedSystems, that has as its only field a Set of NamedSystem. </p> <p>I have a method to find NamedSystems by certain criteria. That's not really important. When it gets results, everything works fine. However, when it can't find anything, and thus returns a null (or empty -- I've tried both ways) set, I get problems. Let me explain.</p> <p>I'm using the Spring RestTemplate class and I'm making a call like this in a unit test:</p> <pre><code>ResponseEntity&lt;?&gt; responseEntity = template.exchange(BASE_SERVICE_URL + "? alias={aliasValue}&amp;aliasAuthority={aliasAssigningAuthority}", HttpMethod.GET, makeHttpEntity("xml"), NamedSystems.class, alias1.getAlias(), alias1.getAuthority()); </code></pre> <p>Now, since this would normally return a 200, but I want to return a 204, I have an interceptor in my service that determines if a ModelAndView is a NamedSystem and if its set is null. If so, I then the set the status code to NO_CONTENT (204). </p> <p>When I run my junit test, I get this error:</p> <pre><code>org.springframework.web.client.RestClientException: Cannot extract response: no Content-Type found </code></pre> <p>Setting the status to NO_CONTENT seems to wipe the content-type field (which does make sense when I think about it). So why is it even looking at it?</p> <p>Spring's HttpMessageConverterExtractor extractData method:</p> <pre><code>public T extractData(ClientHttpResponse response) throws IOException { MediaType contentType = response.getHeaders().getContentType(); if (contentType == null) { throw new RestClientException("Cannot extract response: no Content-Type found"); } for (HttpMessageConverter messageConverter : messageConverters) { if (messageConverter.canRead(responseType, contentType)) { if (logger.isDebugEnabled()) { logger.debug("Reading [" + responseType.getName() + "] as \"" + contentType +"\" using [" + messageConverter + "]"); } return (T) messageConverter.read(this.responseType, response); } } throw new RestClientException( "Could not extract response: no suitable HttpMessageConverter found for response type [" + this.responseType.getName() + "] and content type [" + contentType + "]"); } </code></pre> <p>Going up the chain a bit to find out where that Extractor is set, I come to RestTemplate's exchange() method that I used in the test:</p> <pre><code>public &lt;T&gt; ResponseEntity&lt;T&gt; exchange(String url, HttpMethod method, HttpEntity&lt;?&gt; requestEntity, Class&lt;T&gt; responseType, Object... uriVariables) throws RestClientException { HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(requestEntity, responseType); ResponseEntityResponseExtractor&lt;T&gt; responseExtractor = new ResponseEntityResponseExtractor&lt;T&gt;(responseType); return execute(url, method, requestCallback, responseExtractor, uriVariables); } </code></pre> <p>So, it's trying to convert what amounts to nothing because of the supplied response type from the exchange call. If I change the responseType from NamedSystems.class to null, it works as expected. It doesn't try to convert anything. If I had tried to set the status code to 404, it also executes fine. </p> <p>Am I misguided, or does this seem like a flaw in RestTemplate? Sure, I'm using a junit right now so I know what's going to happen, but if someone is using RestTemplate to call this and doesn't know the outcome of the service call, they would naturally have NamedSystems as a response type. However, if they tried a criteria search that came up with no elements, they'd have this nasty error.</p> <p>Is there a way around this without overriding any RestTemplate stuff? Am I viewing this situation incorrectly? Please help as I'm a bit baffled. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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