Announcement Announcement Module
Collapse
No announcement yet.
Spring JSON causes problems when the Spring framework is upgraded from 3.0.2 to 3.2.0 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring JSON causes problems when the Spring framework is upgraded from 3.0.2 to 3.2.0

    I was working with a web application using the Spring framework version 3.0.2 along with Hibernate (NetBeans 6.9.1). Later I came to know that there was one of bugs that was causing problems in uploading multiple files. Therefore, I upgraded the Spring version to (3.2.0).

    With the earlier version 3.0.2, AJAX was working fine with Jackson 1.9.8 (its download page) but with the later version (3.2.0), everything works fine but AJAX calls alert an error everywhere in the JavaScript code.

    Google chrome shows this error

    Failed to load resource: the server responded with a status of 406 (Not Acceptable)
    There is a simple scenario at one place when one of the countries is selected in the country select box, the corresponding state list is retrieved from the Spring controller along with DAO. The method which is mapped with a URL in the Spring controller is as follows,

    Code:
    @RequestMapping(value="ajax/GetStateList", method=RequestMethod.GET)
    public @ResponseBody List<Object[]> getStateSelectBox(HttpServletRequest request)
    {
        return cityService.getStateSelectBox(request.getParameter("countryId"));
    }
    This method is invoked when a country is selected in the country select box. The getStateSelectBox() method is defined in one of DAO classes as follows,

    Code:
    @Service
    @Transactional(readOnly = true, propagation=Propagation.REQUIRES_NEW)
    public final class CityDAO implements CityService
    {
        private SessionFactory sessionFactory;
    
        public void setSessionFactory(SessionFactory sessionFactory)
        {
            this.sessionFactory = sessionFactory;
        }
    
        @SuppressWarnings("unchecked")
        public List<Object[]> getStateSelectBox(String id)
        {
            List<Object[]> list = sessionFactory.getCurrentSession()
                                 .createQuery("select s.stateId, s.stateName from StateTable s where countryId.countryId=:id order by s.stateId")
                                 .setParameter("id", Long.parseLong(id)).list();
    
           for(Object[]o:list)
           {
               System.out.println(o[0]+" : "+o[1]);
           }
           return list;
       }
    }
    The foreach loop is just for the sake of demonstration, it displays all the states along with their id that correspond to the countryId supplied by the AJAX request but the List is not returned to JSP.

    The JavaScript code used to send this AJAX request alerts an error. It appears that there are some problems with JSON mapping. The same thing was working with the earlier version of the Spring framework (3.0.2). I'm not sure why does this cause problems with the higher version of Spring which is 3.2.0. Is there anything with the Spring version 3.2.0 which I might be missing?




    If you needed to see the JavaScript code, the full JavaScript code to achieve this would be as follows - jQuery library 1.6

    Code:
    function getStates(countryId)
    {
        if(countryId==""||countryId==null||countryId==undefined||isNaN(countryId))
        {
            var str="<select id='cmbStates' name='cmbStates' onchange='errorMessage(this.value);' class='validate[required] text-input'><option value=''>Select</option></select>";
            $('#stateList').html(str);
            alert("Please select an appropriate option.");
            return;
        }
    
        var div=document.createElement("div");
        div.id="temp";
        document.body.appendChild(div);
    
        $.ajax({
            datatype:"json",
            type: "GET",
            contentType: "application/json",
            url: "/wagafashion/ajax/GetStateList.htm",
            data: "countryId=" + countryId+"&t="+new Date().getTime(),
            success: function(response)
            {
                if(typeof response==='object'&&response instanceof Array)
                {                            
                    var str="<select id='cmbState' name='cmbState' onchange='errorMessage(this.value);' class='validate[required] text-input'><option value=''>Select</option>";
                    var l=response.length;
    
                    for(var i=0;i<l;i++)
                    {
                        str+="<option value='"+response[i][0]+"'>"+$('#temp').text(response[i][1]).html()+"</option>";
                    }
                    str+="</select>";
                    $('#stateList').html(str); // select box is written to #stateList div
                    $('#temp').remove();
                }
            },
            error: function(e)
            {
                alert('Error: ' + e);
            }
        });
    }
    To be sure, the Jackson library is on the classpath and I'm not getting any error or exception on the server side. The AJAX request succeeds and it goes to the DAO via Spring and the list of type List<Object[]> is retrieved from the database but it is not a response of JSON to JSP (which could/should be mapped to a JavaScript array). presumably, it appears that there is something missing with JSON mapping which was however not the case with the earlier version of Spring.



    I have tried to parse List<Object[]> in both of the frameworks, 3.0.2 and 3.2.0 such as

    Code:
    List<Object[]> list = cityService.getStateSelectBox(request.getParameter("countryId"));
    ObjectMapper objectMapper=new ObjectMapper();
    try
    {
        objectMapper.writeValue(new File("E:/Project/SpringHibernet/wagafashionLatest/temp.json"), list);
    }
    catch (IOException ex){}
    The file temp.json contains the following string.

    [[21,"Gujarat"],[22,"Maharashtra"],[23,"Kerala"],[24,"New Delhi"]]
    In both the cases (with both frameworks). So, it appears that the JSON response should be same in both the cases.

    The temp.json file can also be deserialized as follows.

    Code:
    try
    {
        ObjectMapper mapper=new ObjectMapper();
        List<Object[]> list = mapper.readValue(new File("E:/Project/SpringHibernet/wagafashionLatest/temp.json"), new TypeReference<List<Object[]>>() {});
    
        for(Object[]o:list)
        {
            System.out.println(o[0]+" : "+o[1]);
        }
    } 
    catch (IOException ex) 
    {
    
    }
    It works fine and the foreach loop iterates over the List of type List<Object[]>. So, the problem might be caused by the Spring framework itself. What else is required, I'm not sure. Why is it not mapped by Jackson? Is there any configuration setting that I may be missing?




    The following is the entire dispatcher-servlet.xml file.

    Code:
    <?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 id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    
        <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <ref bean="jacksonMessageConverter"/>
                </list>
            </property>
            <property name="requireSession" value="false"/>
        </bean>
    
    I have tried to add the above portion but to no avail.
    
        <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
        <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" />
        
        <bean name="indexController"
              class="org.springframework.web.servlet.mvc.ParameterizableViewController"
              p:viewName="index" />
    </beans>
    Last edited by Tiny; Dec 29th, 2012, 03:11 AM.

  • #2
    Tiny
    I think you got the http 406 message is owing to the requested url "/wagafashion/ajax/GetStateList.htm" is ended in with ".html".
    From spring 3.2 media type first decided by uri extension.
    Extension "html" means "text/html" , but your response is "application/json", so spring raise a HttpMediaTypeNotAcceptableException(I had meet this problem before).

    Comment


    • #3
      Thanks for the helpful answer - kent.yeh.

      When I try to put the following xml in my dispatcher-servlet.xml file,

      Code:
      <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>
      it causes the following exception to be thrown upon saving the xml file - dispatcher-servlet.xml.

      org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'org.springframework.web.servlet.view.ContentNegot iatingViewResolver#0' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Invocation of init method failed; nested exception is java.lang.ClassCastException: java.lang.String cannot be cast to org.springframework.http.MediaType
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean(Abstract AutowireCapableBeanFactory.java:1486)
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.doCreateBean(AbstractAu towireCapableBeanFactory.java:524)
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:461)
      at org.springframework.beans.factory.support.Abstract BeanFactory$1.getObject(AbstractBeanFactory.java:2 95)
      at org.springframework.beans.factory.support.DefaultS ingletonBeanRegistry.getSingleton(DefaultSingleton BeanRegistry.java:223)
      at org.springframework.beans.factory.support.Abstract BeanFactory.doGetBean(AbstractBeanFactory.java:292 )
      at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:194)
      at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons(Defaul tListableBeanFactory.java:607)
      at org.springframework.context.support.AbstractApplic ationContext.finishBeanFactoryInitialization(Abstr actApplicationContext.java:932)
      at org.springframework.context.support.AbstractApplic ationContext.refresh(AbstractApplicationContext.ja va:479)
      at org.springframework.web.servlet.view.ContentNegoti atingViewResolver.afterPropertiesSet(ContentNegoti atingViewResolver.java:270)
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.invokeInitMethods(Abstr actAutowireCapableBeanFactory.java:1545)
      at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean(Abstract AutowireCapableBeanFactory.java:1483)
      ... 40 more
      Dec 30, 2012 8:12:01 AM org.apache.catalina.core.StandardContext loadOnStartup
      What might be the reason? I can't search for this exception stack trace in Google either.




      My dispatcher-servlet.xml file is the same as it is specified in the question however it is mentioned below once again.

      <?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="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/schem...-beans-3.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schem...ng-aop-3.0.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schem...ing-tx-3.0.xsd
      http://www.springframework.org/schema/mvc http://www.springframework.org/schem...ng-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.Conten tNegotiatingViewResolver">
      <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.BeanNa meViewResolver"/>
      <bean class="org.springframework.web.servlet.view.Intern alResourceViewResolver">
      <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.M appingJackson2JsonView" />
      </list>
      </property>
      </bean>


      <bean class="org.springframework.web.servlet.mvc.annotat ion.DefaultAnnotationHandlerMapping" />
      <bean class="org.springframework.web.servlet.mvc.annotat ion.AnnotationMethodHandlerAdapter"/>


      <bean id="urlMapping" class="org.springframework.web.servlet.handler.Sim pleUrlHandlerMapping">
      <property name="mappings">
      <props>
      <prop key="index.htm">indexController</prop>

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


      <!-- <bean id="viewResolver"
      class="org.springframework.web.servlet.view.Intern alResourceViewResolver"
      prefix="/WEB-INF/jsp/"
      p:suffix=".jsp" />
      Initially this bean was mentioned like this was commented out-->

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

      Last edited by Tiny; Dec 30th, 2012, 11:00 PM.

      Comment


      • #4
        Tiny
        Could you try to configure your dispatcher-servlet.xml with
        Code:
            <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
            <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
                <property name="favorPathExtension" value="false" />
                <property name="favorParameter" value="false" />
                <property name="ignoreAcceptHeader" value="false" />
                <property name="mediaTypes" >
                    <value>
                        atom=application/atom+xml
                        html=text/html
                        json=application/json
                        *=*/*
                    </value>
                </property>
            </bean>
        I used this configuration to solve my problem.

        Comment


        • #5
          Hi kent.yeh

          I have tried that but unfortunately, I met with the following parse exception upon saving the dispatcher-servlet.xml file.

          Code:
          org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'content-negotiation-manager' is not allowed to appear in element 'mvc:annotation-driven'.

          Simply omitting 'content-negotiation-manager' like <mvc:annotation-driven /> doesn't solve the issue. It again met with the following error as mentioned in the original question (on Google chrome).

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



          This configuration was reported as a jira issue. After searching a lot on Google, I could find a solution on this post. Accordingly, I have now the following configuration.

          Code:
          <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"/>
                                      </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" />

          but it again doesn't get JSON to work and the original problem still remains.

          Failed to load resource: the server responded with a status of 406 (Not Acceptable)
          I have the Jackson 1.9.8 (its downloadpage) library on the classpath. With Jackson 2.1.1, it doesn't work throwing the following exception at runtime.

          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

          I'm now quite unsure as to how to make it run. I'm usually associated with StackOverflow. I have exactly the same question there but in addition to my own attempts, still I couldn't get JSON to work in Spring 3.2.0. Should I now think to use a lower version of Spring?
          Last edited by Tiny; Dec 30th, 2012, 02:35 PM.

          Comment


          • #6
            Tiny:
            I think you should check whether dispatcher-servlet.xml naming space is correct or not.
            According to 3.2 document, "content-negotiation-manager" is attribute of "mvc:annotation-driven".
            And I don't think it is necessary to build a ContentNegotiatingViewResolver bean. Look at AnnotationDrivenBeanDefinitionParser's method getContentNegotiationManager(),
            if "mvc:annotation-driven did not assigned a "content-negotiation-manager" then it build a default one.
            So it need to assign a content-negotiation-manager as we expect.
            I set favorPathExtension false to wish ContentNegotiationManager don't includ a PathExtensionContentNegotiationStrategy which determined mime type by file extension,
            and set favorParameter false to say that I don't need a additional parameter "format" to determined mime-type;
            and set ignoreAcceptHeader false to wish mine-type determined only by request header;
            and mediaTypes property to map those available mine types.

            I hope my opinion is helpful.

            Comment


            • #7
              Hi kent.yeh

              As you stated -

              I think you should check whether dispatcher-servlet.xml naming space is correct or not.
              The name space was indeed incorrect.

              Code:
              xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
              I have gone through the entire dispatcher-servlet.xml file carefully and marked that the bold face line above was written like the following.

              Code:
              http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
              It was causing the problems. JSON was enabled to work by the solution you suggested after that line was changed.

              Code:
              <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
                  <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
                      <property name="favorPathExtension" value="false" />
                      <property name="favorParameter" value="false" />
                      <property name="ignoreAcceptHeader" value="false" />
                      <property name="mediaTypes" >
                          <value>
                              atom=application/atom+xml
                              html=text/html
                              json=application/json
                              *=*/*
                          </value>
                      </property>
                  </bean>
              Thank you very much. It indeed would not have been possible without you.
              Last edited by Tiny; Dec 31st, 2012, 04:57 AM.

              Comment


              • #8
                Spring JSON causes problems when the Spring framework is upgraded from 3.0.2 to 3.2.0

                Originally posted by Tiny View Post
                Hi kent.yeh

                As you stated -



                The name space was indeed incorrect.

                Code:
                xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
                I have gone through the entire dispatcher-servlet.xml file carefully and marked that the bold face line above was written like the following.

                Code:
                http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
                It was causing the problems. JSON was enabled to work by the solution you suggested after that line was changed.

                Code:
                <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
                    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
                        <property name="favorPathExtension" value="false" />
                        <property name="favorParameter" value="false" />
                        <property name="ignoreAcceptHeader" value="false" />
                        <property name="mediaTypes" >
                            <value>
                                atom=application/atom+xml
                                html=text/html
                                json=application/json
                                *=*/*
                            </value>
                        </property>
                    </bean>
                Thank you very much. It indeed would not have been possible without you.
                Hi All,

                Am also facing the same issue and was closely following this post. I tried all of the above options as expalined below:

                My AJAX Call:

                var urlMsg = contextPath + "/switch_user.htm";
                $.ajax({
                type: "GET",
                contentType: "application/json",
                url: urlMsg,
                dataType: 'json',
                data: dataString,
                success: function(data) {


                Controller class:

                @RequestMapping(method = RequestMethod.GET, value = { WebApplicationConstants.SWITCH_USER_URL })
                public @ResponseBody
                CustomResponse switchUser(
                @RequestParam(WebApplicationConstants.SESSION_TOKE N) String gsxSessionToken,
                @RequestParam(WebApplicationConstants.SWITCH_FLAG) String switchFlag,
                HttpServletRequest request,
                HttpServletResponse response,
                final ModelMap modelMap) {



                Dispatcher servlet:

                <beans xmlns="http://www.springframework.org/schema/beans"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:mvc="http://www.springframework.org/schema/mvc"
                xmlns:context="http://www.springframework.org/schema/context"
                xmlns:jee="http://www.springframework.org/schema/jee"
                xmlns:util="http://www.springframework.org/schema/util"
                xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-3.2.xsd
                http://www.springframework.org/schema/mvc http://www.springframework.org/schem...ng-mvc-3.2.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schem...ontext-3.2.xsd
                http://www.springframework.org/schema/jee http://www.springframework.org/schem...ng-jee-3.2.xsd
                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">


                <context:component-scan base-package="controller"/>

                <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
                <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegot iationManagerFactoryBean">
                <property name="favorPathExtension" value="false" />
                <property name="favorParameter" value="false" />
                <property name="ignoreAcceptHeader" value="false" />
                <property name="mediaTypes" >
                <value>
                atom=application/atom+xml
                html=text/html
                json=application/json
                *=*/*
                </value>
                </property>
                </bean>

                HTTP Header Request:

                Accept:application/json, text/javascript, */*; q=0.01
                Content-Type:application/json
                Referer:http://myapp.corp.apple.com:6880/Web...xtjfUW6cab6CPA
                User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/534.48.3 (KHTML, like Gecko) Version/5.1 Safari/534.48.3
                X-Requested-With:XMLHttpRequest

                Response error:

                The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ()


                Any help on this would be much appreciated..Am left with no other option other than degrading to 3.1.3

                Thanks in advance...

                Regards,
                Dinup

                Comment


                • #9
                  Hi All,

                  Am also facing the same issue while upgrading to 3.2 from 3.0 and was closely following this post. I have tried all the above options as explained above..

                  AJAX call:

                  var urlMsg = contextPath + "/switch_user.htm";
                  $.ajax({
                  type: "GET",
                  contentType: "application/json",
                  url: urlMsg,
                  dataType: 'json',
                  data: dataString,
                  success: function(data) {


                  Controller for this:
                  @RequestMapping(method = RequestMethod.GET, value = { WebApplicationConstants.SWITCH_USER_URL })
                  public @ResponseBody
                  CustomResponse switchUser(
                  @RequestParam(WebApplicationConstants.SESSION_TOKE N) String gsxSessionToken,
                  @RequestParam(WebApplicationConstants.SWITCH_FLAG) String switchFlag,
                  HttpServletRequest request,
                  HttpServletResponse response,
                  final ModelMap modelMap) {

                  Dispatcher Servlet:

                  <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
                  <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegot iationManagerFactoryBean">
                  <property name="favorPathExtension" value="false" />
                  <property name="favorParameter" value="false" />
                  <property name="ignoreAcceptHeader" value="false" />
                  <property name="mediaTypes" >
                  <value>
                  atom=application/atom+xml
                  html=text/html
                  json=application/json
                  *=*/*
                  </value>
                  </property>
                  </bean>

                  HTTP header request:

                  Accept:application/json, text/javascript, */*; q=0.01
                  Content-Type:application/json
                  Referer:http://myapp.corp.apple.com:6880/Web...xtjfUW6cab6CPA
                  User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/534.48.3 (KHTML, like Gecko) Version/5.1 Safari/534.48.3
                  X-Requested-With:XMLHttpRequest




                  Response:

                  The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ()



                  Any pointer on this would of great help..Am left with no other option other than degrading to 3.1.3

                  Comment


                  • #10
                    dinup:

                    try to add produces to method switchUser
                    Code:
                    Controller for this:
                    @RequestMapping(method = RequestMethod.GET, value = { WebApplicationConstants.SWITCH_USER_URL }, produces = "application/json;charset=UTF-8")
                    public @ResponseBody
                    CustomResponse switchUser(
                    @RequestParam(WebApplicationConstants.SESSION_TOKE N) String gsxSessionToken,
                    @RequestParam(WebApplicationConstants.SWITCH_FLAG) String switchFlag,
                    HttpServletRequest request,
                    HttpServletResponse response,
                    final ModelMap modelMap) {
                     ...
                    }

                    Comment


                    • #11
                      Hi Kent,

                      Thanks for your response...I had tried previously with produces ="application/json" and it didnt work. Also now i tried with

                      Code:
                      	@RequestMapping(method = RequestMethod.GET, value = { WebApplicationConstants.SWITCH_USER_URL },produces = "application/json;charset=UTF-8")
                      Still am getting 406. Also I would like to tell you one more observation that we have made. The moment when I change the return type from an Object to a String, it works....
                      Code:
                      Existing:
                      
                      public @ResponseBody
                      CustomResponse switchUser(
                      @RequestParam(WebApplicationConstants.SESSION_TOKE N) String gsxSessionToken,
                      @RequestParam(WebApplicationConstants.SWITCH_FLAG) String switchFlag,
                      HttpServletRequest request,
                      HttpServletResponse response,
                      
                      Return Type:
                      return new CustomResponse(jsonObject.toString());
                      
                      New:
                      )
                      public @ResponseBody
                      String switchUser(
                      @RequestParam(WebApplicationConstants.SESSION_TOKE N) String gsxSessionToken,
                      @RequestParam(WebApplicationConstants.SWITCH_FLAG) String switchFlag,
                      HttpServletRequest request,
                      HttpServletResponse response,
                      
                      
                      Return Type:
                      return (jsonObject.toString());

                      But this involves changes across application and is not a recommended solution that we are looking for. Could you please let us know how we can tackle this error?
                      Last edited by dinup; Jan 14th, 2013, 11:23 PM.

                      Comment


                      • #12
                        dinup:
                        Have you add jackson-core and jackson-databind?
                        I just wrote a sample and it works.

                        Comment


                        • #13
                          Hi Kent,


                          Thanks for your timely response..I had org.codehaus.jackson.jackson-mapper and org.codehaus.jackson.jackson-core(1.9.8). Currently downloading the databind jar and trying whether it works..When I further debugged the code, there's more dimension to this. My return class CustomeResponse is invoked by a customised HTTP Message Converter.

                          Code:
                          public class ConfigurableStringHttpMessageConverter extends AbstractHttpMessageConverter<Object>{
                          
                          	/** Logger */
                          	private final static Logger logger = LoggerFactory
                          			.getLogger(ConfigurableStringHttpMessageConverter.class);
                          	private static final String CONST_TEXT ="text";
                          	private static final String CONST_PLAIN ="plain";
                          	private final List<Charset> availableCharsets;
                              private static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
                          
                              public ConfigurableStringHttpMessageConverter() {
                                  this(DEFAULT_CHARSET);
                              }
                          
                              public ConfigurableStringHttpMessageConverter(Charset defaultCharset) {
                              	super(new MediaType("application", "json", defaultCharset));
                              	MediaType mediaType = new MediaType("application", "json", defaultCharset);
                              	List<MediaType> mediaTypes = new ArrayList<MediaType>();
                              	mediaTypes.add(mediaType);
                              	this.setSupportedMediaTypes(mediaTypes);
                              	this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());    	
                          	}
                          @Override
                          	public boolean supports(Class<? > clazz) {
                          		return CustomResponse.class.isAssignableFrom(clazz);
                          	}
                          
                          	@Override
                          	protected String readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException,HttpMessageNotReadableException {
                          		MediaType contentType = inputMessage.getHeaders().getContentType();
                          		Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
                          		logger.debug("charset in READ {}",charset);
                          		logger.debug("Content Type in READ {}",contentType);
                          
                          		return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
                          	}
                          
                          
                          	@Override
                          	protected void writeInternal(Object s, HttpOutputMessage outputMessage) throws IOException {
                          		outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
                          		MediaType contentType = outputMessage.getHeaders().getContentType();
                          		logger.debug("Content Type in WRITE {}",contentType);
                          		Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
                          		logger.debug("charset in WRITE {}",charset);
                          		FileCopyUtils.copy(s.toString(), new OutputStreamWriter(outputMessage.getBody(), charset));
                          	}
                          
                          Dispatcher Servlet:
                          <bean class="com.apple.ist.gsx.util.WebAppBeanPostProcessor">
                          	  <property name="prependedMessageConvertors">
                          	   <list>
                          	    <bean id="configurableMessageConvertor" class="com.apple.ist.gsx.util.ConfigurableStringHttpMessageConverter">
                          	         <constructor-arg value="UTF-8"/>
                          	    </bean>
                          	   </list>
                          	  </property>
                          	  <property name="order" value="0"/>
                          	 </bean>
                          The customised HTTP message converter was done to enforce UTF-8 charset even for Japanese language..
                          Earlier it was setting content type to "text/plain". Now I tried explicilty setting the content type to application/json in the message converter as shown above..But it still doesn't work.

                          Thanks in advence,
                          Dinup.
                          Last edited by dinup; Jan 14th, 2013, 11:32 PM.

                          Comment


                          • #14
                            dinup:
                            If you want to use jackson with spring default message converter to convert object to json.
                            Just include jackson-core and jackson-databind into classpath, Spring 32 will automatic include default message-converter,
                            Otherwise, config message-converters register-defaults with false and put your custom message converter into configuration.
                            Code:
                             <mvc:annotation-driven>
                                    <mvc:message-converters register-defaults="true">
                                        <bean class="your.custom.message.converter"/>
                                    </mvc:message-converters>
                             </mvc:annotation-driven>

                            Comment


                            • #15
                              Hi Ken,

                              I tried with the above jackson jars and it still didnt work. Also tried registering my custom converter with register-defaults false...

                              Code:
                               <mvc:annotation-driven>
                                      <mvc:message-converters register-defaults="false">
                                          <bean class="com.apple.ist.gsx.util.ConfigurableStringHttpMessageConverter"/>
                                      </mvc:message-converters>
                               </mvc:annotation-driven>
                              Still the issue remain same..Am not sure whether its anything to do with the way my Custom Message Converter is handling the content type..Only those flows with Custom Converter is failing for now..Rest of the flow remains intact..I have pasted my custom converter code above..

                              I could see this in my logs all in these cases..This is happening after Controller sucessfully processses the request:

                              Code:
                              org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
                              2013-01-14 22:51:22,986 DEBUG [org.springframework.web.servlet.DispatcherServlet][processDispatchResult] Null ModelAndView returned to DispatcherServlet with name 'Spring Servlet': assuming HandlerAdapter completed request handling
                              Last edited by dinup; Jan 15th, 2013, 12:59 AM.

                              Comment

                              Working...
                              X