406 Not Acceptable in Spring MVC application (OSGi, Virgo Web Server) using Jackson, Rome and JAXB2
Asked Answered
B

11

10

I just started learning the Virgo Web Server. I'm trying to work with Jakcson JSON in Spring MVC application. At this stage I can not get a GET request serialized object. The server returns "406 Not Acceptable":

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

The same problem arises when using Rome and JAXB2.

Here is the project configuration files and code:

Fragment pom.xml:

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>com.springsource.org.codehaus.jackson</artifactId>
  <version>1.0.0</version>
</dependency>
<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>com.springsource.org.codehaus.jackson.mapper</artifactId>
  <version>1.0.0</version>
</dependency>

MANIFEST.MF

Manifest-Version: 1.0
Import-Bundle: com.springsource.org.apache.taglibs.standard;version="[
 1.1.2,1.3)",com.springsource.org.codehaus.jackson;version="[1.0.0,1.0
 .0]",com.springsource.org.codehaus.jackson.mapper;version="[1.0.0,1.0
 .0]"
Bundle-Version: 2.3.0
Tool: Bundlor 1.0.0.RELEASE
Bundle-Name: GreenPages Web
Import-Library: org.springframework.spring;version="[3.0, 3.1)"
Bundle-ManifestVersion: 2
Bundle-SymbolicName: greenpages.web
Web-ContextPath: greenpages
Import-Package: javax.servlet.jsp.jstl.core;version="[1.1.2,1.2.0)",ja
 vax.sql,org.apache.commons.dbcp,org.eclipse.virgo.web.dm;version="[2.
 0.0, 3.0.0)",org.springframework.core.io;version="[3.0.0.RELEASE,3.1.
 0)",org.springframework.stereotype;version="[3.0.0.RELEASE,3.1.0)",or
 g.springframework.ui;version="[3.0.0.RELEASE,3.1.0)",org.springframew
 ork.web.bind.annotation;version="[3.0.0.RELEASE,3.1.0)",org.springfra
 mework.web.servlet.mvc.annotation;version="[3.0.0.RELEASE,3.1.0)",org
 .springframework.web.servlet.view;version="[3.0.0.RELEASE,3.1.0)"

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

  <welcome-file-list>
    <welcome-file>/WEB-INF/pages/index.jsp</welcome-file>
  </welcome-file-list>

  <!-- CONFIGURE A PARENT APPLICATION CONTEXT -->
  <context-param>
    <param-name>contextClass</param-name>
    <param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>
  </context-param>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- DISPATCHER SERVLET CONFIG -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

</web-app>

dispatcher-servlet.xml

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:component-scan base-package="greenpages.web"/>

    <!-- Configures the @Controller programming model -->
    <mvc:annotation-driven />

    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

GreenPagesController.java

package greenpages.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class GreenPagesController {

 @RequestMapping("/home.htm")
 public void home() {
 }

 // MappingJacksonHttpMessageConverter (requires Jackson on the classpath - particularly useful for serving JavaScript clients that expect to work with JSON)
 @RequestMapping(value="/json.htm", method=RequestMethod.POST)
 public @ResponseBody String readJson(@RequestBody JavaBean bean) {
  return "Read from JSON " + bean;
 }

 @RequestMapping(value="/json.htm", method=RequestMethod.GET)
 public @ResponseBody Object writeJson() {
  return new Object();
 }

}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
   <title>Simple jsp page</title>
   <script type="text/javascript" src="/greenpages/scripts/jquery-1.4.4.min.js"></script>
   <script type="text/javascript">
  $.getJSON("json.htm", function(message) {
   console.log(message);
  });
   </script>
  </head>
  <body>

  <form action="test.htm" method="get">
      <input type="text" name="name">
      <input type="submit">
  </form>

  </body>
</html>

AJAX Request http://localhost:8080/greenpages/json.htm: Request Headers from Firebug:

GET /greenpages/json.htm HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
X-Requested-With: XMLHttpRequest
Referer: http://localhost:8080/greenpages/
Cookie: JSESSIONID=18000E4E096D7978F61F5D1E8105B784; JSESSIONID=35FB0925786699EC587A1B64F30517AD

Response Headers:

HTTP/1.1 406 Not Acceptable
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1070
Date: Tue, 07 Dec 2010 11:15:58 GMT

In what may be the problem?

Brigham answered 7/12, 2010 at 9:12 Comment(0)
S
23

Spring falls back to returning a 406 if it can't find a json converter.

Verify that the jackson jars are actually deployed to the webapp's lib directory. This was the problem in my case.

Syst answered 17/8, 2011 at 10:11 Comment(0)
I
16

Make sure you have <mvc:annotation-driven> in dispatcher-servlet.xml - it configures Spring for use of new annotations such as @ResponseBody.

Also I see you have some confusion in context configuration - dispatcher-servlet.xml is used to configure DispatcherServlet's context, it shouldn't be specified in contextConfigLocation of the parent context.

Infidelity answered 7/12, 2010 at 13:18 Comment(3)
Posted the wrong file in the dispatcher-servlet.xml, edited. Yes, I use <mvc:annotation-driven /> in dispatcher-servlet.xml. I changed contextConfigLocation of the parent context to applicationContext.xml, now dispatcher-servlet.xml used only for DispatcherServlet's context. But the error persists. Thank you for your response.Brigham
@Alexey: Make sure you don't have explicitly declared AnnotationMethodHandlerAdapter.Infidelity
Had this issue earlier. We had <tx:annotation-driven> but it looks like you need the mvc one for some reason or other.Raber
P
3

I had exactly the same problem and all I needed was to put public getters in my java class

See: https://mcmap.net/q/369905/-spring-3-x-json-status-406-quot-characteristics-not-acceptable-according-to-the-request-quot-accept-quot-headers-quot

Parlando answered 14/8, 2013 at 9:51 Comment(1)
I had similar issue and that was the case for me tooPasteup
D
2

See http://www.checkupdown.com/status/E406.html for details. Your client app is telling the server that it won't accept the type of data being sent back.

I'm not familiar with the libs etc that you're using, but you should be able to look at your accept headers programatically (or via something like Firebug) to see what is being set. You can hopefully then find that in your source code/configuration.

At a guess I expect that your client is demanding JSON to come back and your server isn't sending it.

Draftsman answered 7/12, 2010 at 9:54 Comment(2)
I added data of request headers from Firebug. Thank you for your response.Brigham
@Brigham - OK, now that's interesting, it certainly looks like you're sending the right accept headers. That means in theory your server isn't returning json or javascript. I personally haven't used the Spring web services stuff yet, but is there a way you can intercept/inspect the response to make sure it really is json?Draftsman
Q
1

I ran into the same issue, and I am wondering if the following might be the cause.

The AnnotationDrivenBeanDefinitionParser class is in charge of checking the classpath for jaxb2 / jackson availability. It uses the following logic to do so:

private static final boolean jaxb2Present =
        ClassUtils.isPresent("javax.xml.bind.Binder", AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

Now, normally the bundle's application context would provide an osgi-aware class loader. However, the jaxb2present variable is static, and so it is getting set statically when the class is loaded, before being instantiated by the application context. I suspect that at that point in time, the class loader is not osgi-aware and so it cannot find the class it is looking for.

For now, I am assuming the only workaround is to manually wire up an Jaxb2HttpMessageConverter (which I don't know how to do yet :-)

Queston answered 2/4, 2012 at 23:16 Comment(0)
S
1
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">


<context:component-scan base-package="com.roshka.osgi.controller">

</context:component-scan>



<mvc:annotation-driven />
<context:annotation-config />

Import-Bundle: org.eclipse.virgo.web.dm,com

.springsource.org.codehaus.jackson.mapper;version="[1.4.3,1.4.3]"

Import-Package: javax.servlet;version="[3.0.0, 3.5.0)",org.eclipse.vir

go.web.dm;version="[3.0.0, 4.0.0)",org.codehaus.jackson.map;version="[1.4.3,1.4.3]"

Sudarium answered 18/12, 2013 at 14:6 Comment(0)
B
0

@axtavt could you please let me know what do you mean by not having explicit declaration on AnnotationMethodHandlerAdapter. I am having following declaration in my servlet file and I am getting 404.

<bean
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jsonConverter" />
        </list>
    </property>
</bean>

<bean id="jsonConverter"
    class="com.clickable.pro.data.bll.internal.response.MyMappingJacksonHttpMessageConverter">
    <property name="supportedMediaTypes" value="application/json" />
    <property name="objectMapper" ref="jaxbJacksonObjectMapper" />
    <property name="prefixJson" value="true"></property>
    <property name="prefixJsonString" value="while(1);"></property>
</bean>
Burkes answered 10/8, 2011 at 11:7 Comment(0)
P
0
@RequestMapping(value = "/{cid}/{lid}/newslice", method = RequestMethod.POST)

public @ResponseBody

int addSlice(@PathVariable int cid, @PathVariable int lid, @RequestParam("t") String t) {

}

This returns 406 error. When I turn return type int to String, the problem disappeared.

Presidio answered 3/7, 2013 at 8:55 Comment(0)
B
0

You just need to get rid of @ResponseBody

Broadminded answered 21/3, 2014 at 19:26 Comment(0)
A
0

I had a similar issue where I was getting a 406 error because the java object I was trying to return was not annotated with an XmlRootElement above the class definition. The method returned JSON without issue when I included the Accepts=application/json header to the request but returned 406 when I included the Accept=application/xml header to the request

I used Postman to alter the headers and view the responses. Very handy tool.

Affected answered 3/4, 2014 at 17:31 Comment(0)
U
0

I had the same error. But I used Java Annotations, I have all necessary dependencies. But I was missed to annotate with

@EnableWebMvc 

my @Configuration class

Uriiah answered 12/12, 2014 at 16:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.