3

Based on my previous question, I have upgraded the Spring framework from 3.0.2 to 3.2.0 for the reason mentioned in this question (Spring 3.0.2 causes problems in uploading multiple files as there was a long standing bug).

With the newer version everything works fine exception JSON. While responding, Google chrome shows this error.

Failed to load resource: the server responded with a status of 406 (Not Acceptable)

I have tried to do as specified here in the dispatcher-servlet.xml file like,

<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>

and it ends with the following exception upon saving the xml file.

java.lang.ClassCastException java.lang.String cannot be cast to org.springframework.http.MediaType


The full contents of the dispatcher-servelet.xml file is as follows, if someone needs to see.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"

       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <context:component-scan base-package="controller" />
    <context:component-scan base-package="validatorbeans" />
    <mvc:annotation-driven />




<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>

    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="index.htm">indexController</prop>

            </props>
        </property>
    </bean>

<!--<bean id="viewResolver"
       class="org.springframework.web.servlet.view.InternalResourceViewResolver"
       p:prefix="/WEB-INF/jsp/"
       p:suffix=".jsp" />

       Initially this bean was mentioned like this was given a comment. It is specified as above-->

    <bean name="indexController"
          class="org.springframework.web.servlet.mvc.ParameterizableViewController"
          p:viewName="index" />
</beans>

How to resolve this exception? Google search results of this exception could not bring me to a specific reference.


EDIT:

According to this configuration, I have now the following XML mapping.

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1" />
    <property name="contentNegotiationManager">
        <bean class="org.springframework.web.accept.ContentNegotiationManager">
            <constructor-arg>
                <bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
                    <constructor-arg>
                        <map>
                            <entry key="json" value="application/json"/>
                            <entry key="xml" value="application/xml"/>
                            <!--<entry key="html" value="text/html"/>
                            <entry key="atom" value="application/atom+xml"/-->
                        </map>
                    </constructor-arg>
                </bean>
            </constructor-arg>
        </bean>
    </property>


    <property name="defaultViews">
        <list>
            <!-- JSON View -->
            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />

            <!-- XML View -->
            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <constructor-arg>
                    <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                        <property name="packagesToScan">
                            <list>
                                <value>documentLoader.domain</value>
                            </list>
                        </property>
                    </bean>
                </constructor-arg>
            </bean>
        </list>
    </property>
</bean>

<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      p:prefix="/WEB-INF/jsp/"
      p:suffix=".jsp" />

and the ClassCastException disappeared but JSON still doesn't work. I'm still getting the same error,

Failed to load resource: the server responded with a status of 406 (Not Acceptable)

What else is still remaining? There is one jira issue still can be seen.

NOTE: I have Jackson 1.9.8 (its download page) library on the classpath. With Jackson 2.1.1, it doesn't work throwing the following exception at runtime.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.view.ContentNegotiatingViewResolver#0' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Cannot create inner bean 'org.springframework.web.servlet.view.json.MappingJacksonJsonView#bb314f' of type [org.springframework.web.servlet.view.json.MappingJacksonJsonView] while setting bean property 'defaultViews' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.view.json.MappingJacksonJsonView#bb314f' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.web.servlet.view.json.MappingJacksonJsonView]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/codehaus/jackson/map/ObjectMapper

Because Jackson 2.1.1 has the class ObjectMapper in another package - com.fasterxml.jackson.databind.ObjectMapper. What is the way?

Community
  • 1
  • 1
Tiny
  • 27,221
  • 105
  • 339
  • 599

3 Answers3

4

it is better to reference constants in MediaType class

<constructor-arg>
    <map>
        <entry key="json">
            <util:constant static-field="org.springframework.http.MediaType.APPLICATION_JSON_VALUE" />
        </entry>
        <entry key="xml">
            <util:constant static-field="org.springframework.http.MediaType.APPLICATION_ATOM_XML_VALUE" />
        </entry>
    </map>
</constructor-arg>

you will need to include util schema as well

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
Community
  • 1
  • 1
2

you should add a reference to ContentNegotiatingViewResolver. Replace

<mvc:annotation-driven />

by

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

and add the id to the bean definition:

<bean id="contentNegotiationManager"  class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">

Also, you need to update the schema location to 3.2.

xsi:schemaLocation="
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
lboullo0
  • 772
  • 7
  • 14
1

The exception occurs when you're trying to set the mediaTypes property to the ContentNegotiatingViewResolver because the value is not a plain string like "text/html" as you thought. It's a different type MediaType

Instead specify something like this.

<bean id="atomXml" class="org.springframework.http.MediaType">
<constructor-arg><value><![CDATA[application/atom+xml]]></value></constructor-arg>
</bean>

and other beans similarly.


When you want to set the mediaTypes, inject the beans created above to the ContentNegotiatingViewResolver.

<property name="mediaTypes">
    <map>
      <entry key="atom" value-ref="atomXml"/>
    </map>
</property>

Defining other relevant beans and fixing any syntax issues related to the above configuration are left as an exercise to you.

asgs
  • 3,928
  • 6
  • 39
  • 54
  • Then it says - `org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.` - a parsing error. – Tiny Dec 30 '12 at 04:00
  • You have an issue in forming the correct syntax. Recheck the bean configuration. – asgs Dec 30 '12 at 04:15
  • That have been figured out but it then says - `java.lang.IllegalArgumentException: Invalid token character '/' in token "application/atom+xml"`. – Tiny Dec 30 '12 at 04:21
  • Made an edit to place the string containing special characters within the CDATA section. – asgs Dec 30 '12 at 04:27
  • Sorry, I was outside for an emergency. I have enclosed that xml within CDATA like `<![CDATA[ ]]>`. It says - `org.xml.sax.SAXParseException: cvc-complex-type.2.3: Element 'beans' cannot have character [children], because the type's content type is element-only.` – Tiny Dec 30 '12 at 04:48
  • You've the `CDATA` in the wrong place. Check my updated post to see the correct usage of CDATA (which stands for Character Data). – asgs Dec 30 '12 at 05:11
  • This `<![CDATA[application/atom+xml]]>` causes the same exception - `java.lang.IllegalArgumentException: Invalid token character '/' in token "application/atom+xml"`. (Therefore, I have tried in a different way). – Tiny Dec 30 '12 at 05:18
  • [This](http://stackoverflow.com/q/12865093/1391249) question uses the same xml configurations as in my original post. I'm quite unsure why it doesn't work in my case! There was only one issue - "*The issue with your project was actually very small - you have protected getters in your Contest class, just change it to public methods and it should just work cleanly*". Otherwise, everything was fine according to one of the [comments](http://stackoverflow.com/questions/12865093/#comment17517711_12873170) below the accepted answer. – Tiny Dec 30 '12 at 05:36
  • 1
    As mentioned on the [Spring forum](http://forum.springsource.org/showthread.php?85004-Spring-3-0-1-Release-Media-Type-issue-Spring-Team&p=285048#post285048) (that is about 3.0.1 though), they insist upon using a **two-arguments constructor** something like ` ` The approach with CDATA is not required but it doesn't solve the **original problem** as mentioned in the question (implied by the question title itself). – Tiny Dec 30 '12 at 07:15
  • Ah I see. Did the 2-arg-constructor-based Spring configuration work? – asgs Dec 30 '12 at 08:51
  • That cause indeed appears to be a [jira](https://jira.springsource.org/browse/SPR-10119) issue. According to [this](http://forum.springsource.org/showthread.php?133343-3-1-2-gt-3-2-issue-with-ContentNegotiatingViewResolver&p=433755#post433755) configuration, I could get rid of all these errors and exceptions but this could not get JSON to work unfortunately. The problem with JSON still remains stationary (unsolved). Do you know something about Jackson2 in Spring 3.2.0? It appears that I have to leave this framework again. – Tiny Dec 30 '12 at 09:02
  • I have ultimately met with [this](http://stackoverflow.com/a/14102773/1391249) solution. Thank you very much for cooperating me. – Tiny Dec 31 '12 at 14:33
  • Thanks for the update. It seems from the post you linked, the following snippet does the trick. ` atom=application/atom+xml html=text/html json=application/json *=*/* ` – asgs Dec 31 '12 at 15:49