Keith Donald
added a comment - 20/Jan/10 7:10 AM I'm wondering why would this be useful? I thought it was the client's responsibility to send along the contentType they can accept. Then the message converter can just respond to that.

A single MessageConverter is configured that accepts String and can produce "text/plain" and "text/html".

If a browser sends Accept "/", the result would be "text/html". That's because a produces is used not only to match the method to the request but it is also the top preference for the actual content type to write out. As opposed to the default media type of a converter or the order the converters.

Hence I do think SPR-7353 addresses the motivations listed for this issue.

Rossen Stoyanchev
added a comment - 12/Jan/12 7:57 AM @Cédric, your example would actually work:
@RequestMapping (value = "/foo/bar" , produces = "text/html" )
@ResponseBody
public String handle() { return "whatever" ; }
A single MessageConverter is configured that accepts String and can produce "text/plain" and "text/html".
If a browser sends Accept " / ", the result would be "text/html". That's because a produces is used not only to match the method to the request but it is also the top preference for the actual content type to write out. As opposed to the default media type of a converter or the order the converters.
Hence I do think SPR-7353 addresses the motivations listed for this issue.

Cédric Laruelle
added a comment - 16/Jan/12 9:41 AM Hi Rossen.
Thanks for taking time to look into this.
In my example, I have a single message converter, so I'm not using the default Spring MessageConverter that accepts String.
Actually, I think you make a mistake saying it is also the top preference for the actual content type to write out . Could you please let me know where in the code produces is used to determine the output content type ? As far as I can see, in AnnotationMethodHandlerAdapter,
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
if (getMessageConverters() != null) {
for (MediaType acceptedMediaType : acceptedMediaTypes) {
for (HttpMessageConverter messageConverter : getMessageConverters()) {
if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
messageConverter.write(returnValue, acceptedMediaType, outputMessage);
if (logger.isDebugEnabled()) {
MediaType contentType = outputMessage.getHeaders().getContentType();
if (contentType == null) {
contentType = acceptedMediaType;
}
logger.debug("Written [" + returnValue + "] as \"" + contentType +
"\" using [" + messageConverter + "]");
}
this.responseArgumentUsed = true;
return;
}
}
}
for (HttpMessageConverter messageConverter : messageConverters) {
allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
}
}
starting line 1019
So as far as I can see, the output content type only depends on :
The return type which defines the converter to use
The accept headers
The supported media types for the converter

Ah, I see now where the difference comes from. The produces/consumes @RequestMapping conditions (along with all other Spring 3.1 improvements related to annotates controllers) are only implemented in the new @MVC support classes. You'll find pointers to the details in the What's New in 3.1 section of the reference docs.

In short the AnnotationMethodHandlerAdapter doesn't contain this functionality. The RequestMappingHandlerAdapter does and the code you wanted to see is in AbstractMessageConverterMethodProcessor#writeWithMessageConverters.

Rossen Stoyanchev
added a comment - 16/Jan/12 10:00 AM Ah, I see now where the difference comes from. The produces/consumes @RequestMapping conditions (along with all other Spring 3.1 improvements related to annotates controllers) are only implemented in the new @MVC support classes. You'll find pointers to the details in the What's New in 3.1 section of the reference docs.
In short the AnnotationMethodHandlerAdapter doesn't contain this functionality. The RequestMappingHandlerAdapter does and the code you wanted to see is in AbstractMessageConverterMethodProcessor#writeWithMessageConverters.

Thanks for that answer.
You're right ! I'm sorry for my mistake, for some reason, I did not make the connection between the new @MVC support classes and the produces/consumes.
Thanks again for your time !

Cédric Laruelle
added a comment - 17/Jan/12 2:50 AM Thanks for that answer.
You're right ! I'm sorry for my mistake, for some reason, I did not make the connection between the new @MVC support classes and the produces/consumes.
Thanks again for your time !