Java 406 在使用 Jackson、Rome 和 JAXB2 的 Spring MVC 应用程序(OSGi、Virgo Web 服务器)中不可接受

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4374985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 16:40:14  来源:igfitidea点击:

406 Not Acceptable in Spring MVC application (OSGi, Virgo Web Server) using Hymanson, Rome and JAXB2

javaspring-mvcHymansonjaxb2rome

提问by Alexey

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

我刚开始学习 Virgo Web Server。我正在尝试在 Spring MVC 应用程序中使用 Jakcson JSON。在这个阶段我无法获得 GET 请求序列化对象。服务器返回“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.Hymanson</groupId>
  <artifactId>com.springsource.org.codehaus.Hymanson</artifactId>
  <version>1.0.0</version>
</dependency>
<dependency>
  <groupId>org.codehaus.Hymanson</groupId>
  <artifactId>com.springsource.org.codehaus.Hymanson.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.Hymanson;version="[1.0.0,1.0
 .0]",com.springsource.org.codehaus.Hymanson.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

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

绿页控制器.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() {
 }

 // MappingHymansonHttpMessageConverter (requires Hymanson 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

索引.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?

可能是什么问题?

回答by Martijn Verburg

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

有关详细信息,请参阅http://www.checkupdown.com/status/E406.html。您的客户端应用程序告诉服务器它不会接受发回的数据类型。

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.

我不熟悉您正在使用的库等,但您应该能够以编程方式(或通过 Firebug 之类的方式)查看您的接受标头以查看正在设置的内容。然后,您有望在源代码/配置中找到它。

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

猜测我希望您的客户端要求返回 JSON 而您的服务器没有发送它。

回答by axtavt

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

确保您已<mvc:annotation-driven>dispatcher-servlet.xml- 它配置 Spring 以使用新的注解,例如@ResponseBody.

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

此外,我看到您在上下文配置方面有些困惑 -dispatcher-servlet.xml用于配置DispatcherServlet的上下文,不应contextConfigLocation在父上下文中指定它。

回答by Pradeep Kumar Mishra

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

@axtavt 你能告诉我你在 AnnotationMethodHandlerAdapter 上没有明确声明是什么意思。我在我的 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.MyMappingHymansonHttpMessageConverter">
    <property name="supportedMediaTypes" value="application/json" />
    <property name="objectMapper" ref="jaxbHymansonObjectMapper" />
    <property name="prefixJson" value="true"></property>
    <property name="prefixJsonString" value="while(1);"></property>
</bean>

回答by oksayt

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

如果找不到 json 转换器,Spring 会回退到返回 406。

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

验证 Hymanson jar 是否实际部署到 webapp 的 lib 目录。这就是我的问题。

回答by MicGer

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 / Hymanson availability. It uses the following logic to do so:

AnnotationDrivenBeanDefinitionParser 类负责检查 jaxb2 / Hymanson 可用性的类路径。它使用以下逻辑来执行此操作:

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.

现在,通常包的应用程序上下文会提供一个 osgi-aware 类加载器。但是,jaxb2present 变量是静态的,因此在加载类时静态设置它,然后由应用程序上下文实例化。我怀疑在那个时间点,类加载器不是 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(我还不知道该怎么做:-)

回答by strongwillow

@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 intto String, the problem disappeared.

这将返回 406 错误。当我将返回类型int 转换为 String 时,问题就消失了。

回答by OscarRyz

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

回答by jrey

<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.Hymanson.mapper;version="[1.4.3,1.4.3]"

.springsource.org.codehaus.Hymanson.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.Hymanson.map;version="[1.4.3,1.4.3]"

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

回答by codebusta

You just need to get rid of @ResponseBody

你只需要摆脱@ResponseBody

回答by gffny

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

我有一个类似的问题,我收到 406 错误,因为我尝试返回的 java 对象没有在类定义上方使用 XmlRootElement 进行注释。当我将 Accepts=application/json 标头包含到请求中时,该方法返回 JSON 没有问题,但当我将 Accept=application/xml 标头包含到请求中时返回 406

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

我使用Postman更改标题并查看响应。非常方便的工具。