Skip to content

AnnotationMethodHandlerAdapter.handleResponseBody prioritizes messageConverter over MediaType [SPR-6877] #11543

@spring-projects-issues

Description

@spring-projects-issues

Ted Bergeron opened SPR-6877 and commented

The nested loop should be flip flopped. The current logic iterates over the message converters, then looks at the media types. For request header:

Accept	application/json, text/javascript, */*

Which is sent via jQuery, this logic picks the first converter than can handle ```
*/*


	private void handleResponseBody(Object returnValue, ServletWebRequest webRequest)
			throws ServletException, IOException {

		HttpInputMessage inputMessage = new ServletServerHttpRequest(webRequest.getRequest());
		List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
		if (acceptedMediaTypes.isEmpty()) {
			acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
		}
		MediaType.sortBySpecificity(acceptedMediaTypes);
		HttpOutputMessage outputMessage = new ServletServerHttpResponse(webRequest.getResponse());
		Class<?> returnValueType = returnValue.getClass();
		List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
		if (messageConverters != null) {
			for (HttpMessageConverter messageConverter : messageConverters) {
				allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
				for (MediaType acceptedMediaType : acceptedMediaTypes) {
					if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
						messageConverter.write(returnValue, acceptedMediaType, outputMessage);
						this.responseArgumentUsed = true;
						return;
					}
				}
			}
		}
		throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes);
	}

In my case, I've registered the converters in the order matching the docs: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/remoting.html#rest-message-conversion

<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<!--<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"/>-->
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<!--<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>-->
</list>
</property>


If I enable the xml converter, it tries to process my request, despite the json accept header.  Nothing in the docs indicate that the ordering is very important, as I'd expect these to be mutually exclusive.  If there is a specific ordering that should be used, please add that to the docs.

The only ordering I can see is the default in the code of:

private HttpMessageConverter<?>[] messageConverters =
new HttpMessageConverter[]{new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter(),
new FormHttpMessageConverter(), new SourceHttpMessageConverter()};




---

**Affects:** 3.0.1

**Referenced from:** commits https://github.com/spring-projects/spring-framework/commit/3c8a47bd06023cf8eba681f56720c7dc5d532662, https://github.com/spring-projects/spring-framework/commit/62f9f477f5887c3c6237472d7d8db04510675ceb

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions