Configure Spring MVC ContentNegotiatingViewResolver to generate RSS feeds

The spring 3.2 document provides the following example for configuring the ContentNegotiatingViewResolver for generating rss feeds:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="mediaTypes">
    <map>
      <entry key="atom" value="application/atom+xml"/>
      <entry key="html" value="text/html"/>
      <entry key="json" value="application/json"/>
    </map>
  </property>
  <property name="viewResolvers">
    <list>
      <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
      </bean>
    </list>
  </property>
  <property name="defaultViews">
    <list>
      <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
    </list>
  </property>
</bean>

However when I run this, I got class cast exception with the mediaTypes properties

java.lang.ClassCastException: java.lang.String cannot be cast to org.springframework.http.MediaType
 at org.springframework.web.accept.MappingMediaTypeFileExtensionResolver.<init>(MappingMediaTypeFileExtensionResolver.java:56)
 at org.springframework.web.accept.AbstractMappingContentNegotiationStrategy.<init>(AbstractMappingContentNegotiationStrategy.java:42)
 at org.springframework.web.accept.PathExtensionContentNegotiationStrategy.<init>(PathExtensionContentNegotiationStrategy.java:74)
 at org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy.<init>(ServletPathExtensionContentNegotiationStrategy.java:47)
 at org.springframework.web.accept.ContentNegotiationManagerFactoryBean.afterPropertiesSet(ContentNegotiationManagerFactoryBean.java:166)
 at org.springframework.web.servlet.view.ContentNegotiatingViewResolver.afterPropertiesSet(ContentNegotiatingViewResolver.java:270)

This is because the map expects a MediaType objects as values but got String objects instead, e.g. “application/atom+xml”. The correct way to setup the view resolver should be:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
 <property name="contentNegotiationManager">   [1]
      <bean class="org.springframework.web.accept.ContentNegotiationManager">
           <constructor-arg>
                <bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
                     <constructor-arg>
                     <map>
                        <entry key="atom">
                             <util:constant static-field="org.springframework.http.MediaType.APPLICATION_ATOM_XML" />  [2]
                        </entry>
                        <entry key="rss" value-ref="rssMediaType"/>
                     </map>
                     </constructor-arg>
                </bean>
           </constructor-arg>
      </bean>
 </property>

Note:

  1. The use of property contentNegotiationManager and injection of the bean ContentNegotiationManager
  2. Static field of MediaType org.springframework.http.MediaType.APPLICATION_ATOM_XML
  3. The MediaType class does not define a constant for RSS type so you have to create your own:
<bean id="rssMediaType" class="org.springframework.http.MediaType">
      <constructor-arg value="application"/>
      <constructor-arg value="rss+xml"/>
</bean>

About Raymond Lee
Professional Java/EE Developer, software development technology enthusiast.

Comments are closed.