[SPR-7504] Make it easier to add new Message Converters to AnnotationMethodHandlerAdapter Created: 29/Aug/10  Updated: 01/Apr/14  Resolved: 25/Jan/11

Status: Closed
Project: Spring Framework
Component/s: Web
Affects Version/s: 3.0.4
Fix Version/s: 3.1 M1

Type: Improvement Priority: Minor
Reporter: Kenneth DeLong Assignee: Rossen Stoyanchev
Resolution: Complete Votes: 0
Labels: None
Remaining Estimate: 0d
Time Spent: 0.5h
Original Estimate: 0d

Attachments: Text File 7504.patch    
Issue Links:
Relate
is related to SPR-7904 Setting default charset in StringHttp... Resolved
is related to SPR-7091 AnnotationDrivenBeanDefinitionParser ... Resolved
is related to SPR-7191 <mvc:annotation-driven / > should sup... Resolved
Reference URL: https://support.springsource.com/spring_support_client_getIncidentById/9995
Days since last comment: 6 years, 33 weeks, 6 days ago
Last commented by a User: true
Last updater: Juergen Hoeller

 Description   

See https://support.springsource.com/spring_support_client_getIncidentById/9995

I needed to use MarshallingHttpMessageConverter (so @RequestBody could bind a POST of XML to a POJO). AnnotationMethodHandlerAdapter is preconfigured in its constructor with several MessagConverters, but not MarshallingHttpMessageConverter. Using the <mvc:annotation-config/> tag, it was nearly impossible to add this MessageConverter to the AMHA. Per Spring Support, I had to write a BeanPostProcessor to look for the AMHA and then add the MTHC (and to add insult to injury, it was an array!).

There should be a simpler way to add MessageConverters; in fact, if they are found in the application context they should be added automatically, or they should be added via the mvc:annotation-config. Or anything more elegant than the BeanPostProcessor.

Also section 19.9 of the reference document implies that MarshallingHttpMessageConverter is configured by default, but it's not.



 Comments   
Comment by Oliver Gierke [ 14/Sep/10 ]

Added proposed patch (Git) to be reviewed by Arjen. I added a setter for custom HttpMessageConverter<?> that will be prepended to the default ones, just like you already can do with custom WebArgumentResolver.

Comment by Oliver Gierke [ 14/Sep/10 ]

Reassigned for review and/or further ideas.

Comment by Rossen Stoyanchev [ 25/Jan/11 ]

It is now possible to specify a list of HttpMessageConverters through the MVC namespace:

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>

This option overrides the default set of HttpMessageConverters. Hence when specified the list must include all required message converters.

Comment by Joern Huxhorn [ 01/Feb/11 ]

I tried to use the above with the current 3.1.0.BUILD-SNAPSHOT but to no avail...
Starting up the application causes a
org.xml.sax.SAXParseException: cvc-complex-type.2.1: Element 'mvc:annotation-driven' must have no character or element information item [children], because the type's content type is empty.

I assume that using the 3.0 schemas is causing this issue but I couldn't find the location of the new 3.1 schemas anywhere.
Any idea how to work around this?

Comment by Rossen Stoyanchev [ 01/Feb/11 ]

The schemas are in the jar. They don't need to be available at the URI specified in the schema location. Just make sure your schema location in the <beans> element points to spring-mvc.xsd (or spring-mvc-3.1.xsd) and not spring-mvc-3.0.xsd.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
 
</beans>

Comment by Joern Huxhorn [ 02/Feb/11 ]

Thank you very much for this fast and accurate response!
Everything is working fine now.

Comment by Joris Kuipers [ 03/Feb/11 ]

Instead of always overriding the list of default converters, forcing people to know what the defaults are exactly so that they can list them again if they only want to register one or two extra converters, why don't we add an attribute like "appendToDefaults" to the message-converters element?
In general I would like to see Spring to offer more support for keeping defaults, as very often more items are added to the default list of mvc-related components with new framework versions and I don't always want to have to keep track of that as I update my applications to benefit from them (Formatters, Converters, HttpMessageConverters, HandlerMappings, HandlerAdapters, etc). Also, the defaults sometimes include smart classpath checking for things like Jackson and Rome, which are not available to me as a simple user using this namespace: being able to append to the defaults would be much simpler.

Comment by Rossen Stoyanchev [ 04/Feb/11 ]

What we could do is place user-provided message converters in front of the default ones. So whether your provide a completely new JSON converter or an instance of say MappingJacksonHttpMessageConverter configured in a slightly different way, in both cases your converter would override or take precedence over the default ones.

With this there needs to be a way to turn off default message converter registrations entirely. That we could do through a "register-defaults" attribute on the <mvc:message-converters> element, which would be set to true by default.

Comment by Joris Kuipers [ 04/Feb/11 ]

Sounds like a good idea to me!

Generated at Thu Sep 21 06:41:22 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.