简体   繁体   English

406使用Jackson,Rome和JAXB2在Spring MVC应用程序(OSGi,Virgo Web Server)中不可接受

[英]406 Not Acceptable in Spring MVC application (OSGi, Virgo Web Server) using Jackson, Rome and JAXB2

I just started learning the Virgo Web Server. 我刚开始学习Virgo Web Server。 I'm trying to work with Jakcson JSON in Spring MVC application. 我正在尝试使用Spring MVC应用程序中的Jakcson JSON。 At this stage I can not get a GET request serialized object. 在这个阶段,我无法获得GET请求序列化对象。 The server returns "406 Not Acceptable": 服务器返回“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. 使用Rome和JAXB2时会出现同样的问题。

Here is the project configuration files and code: 这是项目配置文件和代码:

Fragment pom.xml: 片段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.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 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 调度员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 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 的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: AJAX请求http:// localhost:8080 / greenpages / json.htm :来自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? 可能是什么问题?

Spring falls back to returning a 406 if it can't find a json converter. 如果找不到json转换器,Spring会回退到406。

Verify that the jackson jars are actually deployed to the webapp's lib directory. 验证jackson jar实际上是否已部署到webapp的lib目录中。 This was the problem in my case. 这是我的问题。

Make sure you have <mvc:annotation-driven> in dispatcher-servlet.xml - it configures Spring for use of new annotations such as @ResponseBody . 确保在dispatcher-servlet.xml<mvc:annotation-driven> - 它将Spring配置为使用新的注释,例如@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. 此外,我发现您在上下文配置中有一些混淆 - dispatcher-servlet.xml用于配置DispatcherServlet的上下文,不应在父上下文的contextConfigLocation中指定。

I had exactly the same problem and all I needed was to put public getters in my java class 我有完全相同的问题,我需要的是将公共getter放入我的java类

See: https://stackoverflow.com/a/18228476/20654 请参阅: https//stackoverflow.com/a/18228476/20654

See http://www.checkupdown.com/status/E406.html for details. 有关详细信息,请参见http://www.checkupdown.com/status/E406.html 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. 我不熟悉您正在使用的库等,但您应该能够以编程方式(或通过Firebug之类的东西)查看您的接受标头,以查看正在设置的内容。 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. 猜测我希望你的客户要求JSON回来而你的服务器没有发送它。

<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]" .springsource.org.codehaus.jackson.mapper;版本= “[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]" go.web.dm; version =“[3.0.0,4.0.0)”,org.codehaus.jackson.map; version =“[1.4.3,1.4.3]”

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. AnnotationDrivenBeanDefinitionParser类负责检查jaxb2 / jackson可用性的类路径。 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. 现在,通常bundle的应用程序上下文将提供一个osgi感知的类加载器。 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. 但是,jaxb2present变量是静态的,因此在加载类之前,它会在由应用程序上下文实例化之前进行静态设置。 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. 我怀疑在那个时候,类加载器不是osgi感知的,所以它找不到它正在寻找的类。

For now, I am assuming the only workaround is to manually wire up an Jaxb2HttpMessageConverter (which I don't know how to do yet :-) 现在,我假设唯一的解决方法是手动连接Jaxb2HttpMessageConverter(我不知道该怎么做:-)

@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. 这将返回406错误。 When I turn return type int to String, the problem disappeared. 当我将返回类型int转换为String时,问题就消失了。

你只需要摆脱@ResponseBody

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. 我有一个类似的问题,我得到406错误,因为我试图返回的java对象没有使用类定义上方的XmlRootElement注释。 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 当我将Accepts = application / json标头包含在请求中时,该方法返回JSON没有问题,但当我将Accept = application / xml标头包含在请求中时返回406

I used Postman to alter the headers and view the responses. 我使用Postman来改变标题并查看回复。 Very handy tool. 非常方便的工具。

I had the same error. 我有同样的错误。 But I used Java Annotations, I have all necessary dependencies. 但我使用Java Annotations,我有所有必要的依赖。 But I was missed to annotate with 但我错过了注释

@EnableWebMvc 

my @Configuration class 我的@Configuration课程

@axtavt could you please let me know what do you mean by not having explicit declaration on AnnotationMethodHandlerAdapter. @axtavt你能不能通过AnnotationMethodHandlerAdapter上的明确声明告诉我你是什么意思。 I am having following declaration in my servlet file and I am getting 404. 我在我的servlet文件中有以下声明,我得到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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM