Results 1 to 5 of 5

Thread: Spring MVC 3.1 and Json "Not Acceptable" response - what should I check?

  1. #1
    Join Date
    Feb 2009
    Location
    Denmark
    Posts
    21

    Question Spring MVC 3.1 and Json "Not Acceptable" response - what should I check?

    I have run into a problem exposing a rest service.

    In my @Controller I have annotated the return type with @ResponseBody but I get 406 "Not Acceptable".

    I have searched forums and tried googling and have found many people stating all I have to do is put the Jackson libraries in my web-inf/lib and have mvc:annotation-config in my servlet config. I did that already.

    Next, I tried debugging my controller to see what happened after my domain object was returned from the controller.

    I can follow the trace down till where Spring iterates over my registered MessageConverters in org.springframework.web.servlet.mvc.method.annotat ion.AbstractMessageConverterMethodProcessor#writeW ithMessageConverters.
    I have double checked that MappingJacksonHttpMessageConverter is in the list - but messageConverter.canWrite(returnValueClass, selectedMediaType) returns false for all my MessageConverters - selectedMediaType is "application/json".


    My domain object is really simple - it has three fields - int, string , string and a public default no-args constructor.

    So I guess I must have done something wrong in my configuration - but I cannot seem to figure out what it is:

    web.xml references rootContext-config for ContextLoaderListener and mvc-config.xml for DispatcherServlet. (Ran out of space, so had to remove it from the post)

    All Spring namespaces in my configuration files are version 3.1.
    rootContext-config.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans ...>
    
        <context:component-scan base-package="org.joensson.nasdvr">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
    
        <!-- Weaves in transactional advice around @Transactional methods -->
        <tx:annotation-driven transaction-manager="transactionManager" />
    
        <context:annotation-config/>
    
        <import resource="common-config.xml"/>
    
        <!-- BoneCP configuration -->
        <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
            <property name="driverClass" value="com.mysql.jdbc.Driver" />
            <property name="jdbcUrl" value="jdbc:mysql://${db.server}/${db.databasename}" />
            <property name="username" value="${db.username}"/>
            <property name="password" value="${db.password}"/>
            <property name="idleConnectionTestPeriodInSeconds" value="60"/>
            <property name="idleMaxAgeInMinutes" value="240"/>
            <property name="maxConnectionsPerPartition" value="15"/>
            <property name="minConnectionsPerPartition" value="5"/>
            <property name="partitionCount" value="3"/>
            <property name="acquireIncrement" value="5"/>
            <property name="statementsCacheSize" value="100"/>
            <property name="releaseHelperThreads" value="3"/>
        </bean>
    
        <jdbc:initialize-database data-source="dataSource">
            <jdbc:script location="classpath:/db/schema.sql"/>
        </jdbc:initialize-database>
    
    
        <!-- Hibernate SessionFactory -->
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="annotatedClasses">
                <list>
                    <value>org.joensson.nasdvr.model.Actor</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.format_sql">true</prop>
                    <prop key="hibernate.show_sql">true</prop>
    
                    <prop key="bonecp.idleMaxAge">240</prop>
                    <prop key="bonecp.idleConnectionTestPeriod">60</prop>
                    <prop key="bonecp.partitionCount">3</prop>
                    <prop key="bonecp.acquireIncrement">10</prop>
                    <prop key="bonecp.maxConnectionsPerPartition">60</prop>
                    <prop key="bonecp.minConnectionsPerPartition">20</prop>
                    <prop key="bonecp.statementsCacheSize">50</prop>
                    <prop key="bonecp.releaseHelperThreads">3</prop>
                </props>
            </property>
        </bean>
    
    
        <!-- A transaction manager for working with Hibernate SessionFactories -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>
    
    </beans>
    mvc-config.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans ...>
    
    
        <import resource="common-config.xml"/>
    
        <mvc:annotation-driven>
    <!--        <mvc:message-converters register-defaults="true">
                <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                </bean>
            </mvc:message-converters> -->
        </mvc:annotation-driven>
    
    
        <context:component-scan base-package="org.joensson.nasdvr.web"/>
    
    
        <task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
        <task:executor id="myExecutor" pool-size="5"/>
        <task:scheduler id="myScheduler" pool-size="10"/>
    
    
    </beans>
    pom.xml dependencies:
    Code:
        <properties>
            <spring.version>3.1.1.RELEASE</spring.version>
            <jackson.version>1.9.4</jackson.version>
            <org.aspectj-version>1.6.9</org.aspectj-version>
            <org.slf4j-version>1.5.11</org.slf4j-version>
        </properties>
    
      <dependencies>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-core</artifactId>
              <version>${spring.version}</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-context</artifactId>
              <version>${spring.version}</version>
              <exclusions>
                  <!-- Exclude Commons Logging in favor of SLF4j -->
                  <exclusion>
                      <groupId>commons-logging</groupId>
                      <artifactId>commons-logging</artifactId>
                  </exclusion>
              </exclusions>
          </dependency>
    
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-webmvc</artifactId>
              <version>${spring.version}</version>
          </dependency>
    
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-aop</artifactId>
              <version>${spring.version}</version>
          </dependency>
    
          <!-- AspectJ -->
          <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjrt</artifactId>
              <version>${org.aspectj-version}</version>
          </dependency>
    
    
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-aspects</artifactId>
              <version>${spring.version}</version>
          </dependency>
          <dependency>
              <groupId>cglib</groupId>
              <artifactId>cglib</artifactId>
              <version>2.2.2</version>
          </dependency>
    
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-jdbc</artifactId>
              <version>${spring.version}</version>
          </dependency>
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-orm</artifactId>
              <version>${spring.version}</version>
          </dependency>
    
          <!-- Jackson json mapper -->
          <dependency>
              <groupId>org.codehaus.jackson</groupId>
              <artifactId>jackson-core-asl</artifactId>
              <version>${jackson.version}</version>
          </dependency>
          <dependency>
              <groupId>org.codehaus.jackson</groupId>
              <artifactId>jackson-mapper-asl</artifactId>
              <version>${jackson.version}</version>
          </dependency>
    
          <!-- Logging -->
          <dependency>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-api</artifactId>
              <version>${org.slf4j-version}</version>
          </dependency>
    
          <dependency>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-simple</artifactId>
              <version>${org.slf4j-version}</version>
          </dependency>
    
          <dependency>
              <groupId>org.hibernate</groupId>
              <artifactId>hibernate-core</artifactId>
              <version>3.6.8.Final</version>
          </dependency>
          <dependency>
              <groupId>javassist</groupId>
              <artifactId>javassist</artifactId>
              <version>3.12.1.GA</version>
          </dependency>
          <dependency>
              <groupId>com.jolbox</groupId>
              <artifactId>bonecp</artifactId>
              <version>0.7.1.RELEASE</version>
          </dependency>
    
    
          <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>5.1.18</version>
              <scope>runtime</scope>
          </dependency>
    
    
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-test</artifactId>
              <version>${spring.version}</version>
              <scope>test</scope>
          </dependency>
    
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.8.2</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    @RequestMapping:
    Code:
        @RequestMapping(value = "showSchedule",  method = RequestMethod.GET)
        public @ResponseBody Actor showSchedule(Model model) {
            //TODO
            Actor actor = new Actor();
            actor.setActorName("Jackie Chan");
            actor.setCharacterName("Some name");
            Actor actor1 = actorDao.storeActor(actor);
            return actor1;
    
        }
    Any tips will be greatly appreciated, this is driving me nuts :-/

  2. #2
    Join Date
    Feb 2009
    Location
    Denmark
    Posts
    21

    Default Forget to include the error message

    Code:
    HTTP ERROR 406
    
    Problem accessing /nasdvr/rest/schedule/showSchedule. Reason:
    
        Not Acceptable
    Powered by Jetty://

  3. #3
    Join Date
    Feb 2009
    Location
    Denmark
    Posts
    21

    Cool

    Quote Originally Posted by joensson View Post

    Any tips will be greatly appreciated, this is driving me nuts :-/


    I finally figured out what was wrong. It turned out that the problem was caused by my POJO not having getter-methods and jackson defaulting to non_private field access.

    So the fix for me was to either add @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) as a class annotation on each of my POJO's / @Entity's that could be returned from my @Controller or to add getters for the fields in my POJOs.

    It even makes sense now

  4. #4
    Join Date
    Aug 2004
    Posts
    2

    Default

    Thank you, joensson. This had me stumped for more time than I will admit to.

  5. #5
    Join Date
    Feb 2009
    Location
    Denmark
    Posts
    21

    Default

    I'm glad my solution has helped others - I too spent way too much time figuring out what caused this problem.

    I guess I was just too used to Spring handling property field access for me, to think that Jackson could have another default setting.
    At least the fix is easy once you find out what is wrong.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •