2010-12-07 8 views
10

Acabo de empezar a aprender el servidor web de Virgo. Estoy tratando de trabajar con Jakcson JSON en la aplicación Spring MVC. En este momento no puedo obtener un objeto serializado de solicitud GET. el servidor devuelve "406 no es aceptable":406 No aceptable en la aplicación Spring MVC (OSGi, Virgo Web Server) usando Jackson, Rome y JAXB2

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

El mismo problema surge cuando se utilizan Roma y JAXB2.

Aquí es los archivos de configuración del proyecto y código:

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

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

despachador -servle t.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 Solicitud http://localhost:8080/greenpages/json.htm: Solicitar encabezados de 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 

Encabezados de respuesta:

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 

¿Cuál puede ser el problema?

Respuesta

2

Consulte http://www.checkupdown.com/status/E406.html para más detalles. Su aplicación cliente le está diciendo al servidor que no aceptará el tipo de datos que se envían.

No estoy familiarizado con las librerías, etc. que estás utilizando, pero deberías poder mirar tus encabezados de aceptación programáticamente (o mediante algo como Firebug) para ver qué se está configurando. Con suerte, puede encontrarlo en su código fuente/configuración.

Supongo que su cliente está exigiendo que JSON regrese y su servidor no lo está enviando.

+0

he añadido los datos de las cabeceras de solicitud de Firebug. Gracias por su respuesta. – Alexey

+0

@Alexey - Bien, ahora que es interesante, ciertamente parece que estás enviando los encabezados de aceptar correctos. Eso significa que, en teoría, su servidor no está devolviendo json o javascript. Personalmente, todavía no he usado los servicios de Internet, pero ¿hay alguna forma de interceptar/inspeccionar la respuesta para asegurarse de que realmente es json? –

16

Asegúrese de tener <mvc:annotation-driven> en dispatcher-servlet.xml - configura Spring para el uso de nuevas anotaciones, como @ResponseBody.

También veo que tiene alguna confusión en la configuración del contexto - dispatcher-servlet.xml se utiliza para configurar el contexto DispatcherServlet, no debe especificarse en contextConfigLocation del contexto principal.

+0

Publica el archivo incorrecto en el dispatcher-servlet.xml, editado. Sí, uso en dispatcher-servlet.xml. Cambié contextConfigLocation del contexto principal a applicationContext.xml, ahora dispatcher-servlet.xml utilizado solo para el contexto de DispatcherServlet. Pero el error persiste. Gracias por su respuesta. – Alexey

+2

@Alexey: asegúrese de no haber declarado explícitamente 'AnnotationMethodHandlerAdapter'. – axtavt

+0

@axtavt Tu solución funcionó perfectamente, ¡gracias! :) – ManiSto

0

@axtavt podría decirme a qué se refiere al no tener una declaración explícita en AnnotationMethodHandlerAdapter. Tengo una declaración siguiente en mi archivo servlet y obtengo 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> 
23

El muelle vuelve a devolver un 406 si no puede encontrar un convertidor json.

Compruebe que los archivos jar de jackson realmente se implementan en el directorio lib de la aplicación web. Este fue el problema en mi caso.

1

Me encontré con el mismo problema, y ​​me pregunto si la siguiente podría ser la causa.

La clase AnnotationDrivenBeanDefinitionParser se encarga de comprobar el classpath para la disponibilidad de jaxb2/jackson. Se utiliza la siguiente lógica para hacerlo:

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

Ahora, normalmente contexto de aplicación del paquete proporcionaría un cargador de clases osgi-conscientes. Sin embargo, la variable jaxb2present es estática, por lo que se establece estáticamente cuando se carga la clase, antes de ser instanciada por el contexto de la aplicación. Sospecho que en ese momento, el cargador de clases no es compatible con osgi y por lo tanto no puede encontrar la clase que está buscando.

Por ahora, estoy asumiendo que la única solución consiste en conectar manualmente una Jaxb2HttpMessageConverter (que no sé cómo hacerlo todavía :-)

0
@RequestMapping(value = "/{cid}/{lid}/newslice", method = RequestMethod.POST) 

public @ResponseBody 

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

} 

Esto devuelve 406 error. Cuando gire el tipo de devolución int a String, el problema desapareció.

3

que tenía exactamente el mismo problema y lo único que necesitaba era poner captadores públicas en mi clase java

Ver: https://stackoverflow.com/a/18228476/20654

+1

Este fue mi caso, ¡gracias! –

+0

Tuve un problema similar y ese fue el caso para mí también –

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

0

Solo necesita para deshacerse de @ResponseBody

0

Tuve un problema similar cuando recibía un error 406 porque el objeto java que estaba tratando de devolver no estaba anotado con un XmlRootElement sobre la definición de la clase. El método devuelve JSON sin problema cuando incluí la Acepta = aplicación encabezado/json a la solicitud, pero regresó 406 cuando incluí la Aceptar = aplicación encabezado/xml a la solicitud

I utilizarse Postman para alterar los encabezados y ver el respuestas. Herramienta muy útil.

0

Tuve el mismo error. Pero utilicé Anotaciones de Java, tengo todas las dependencias necesarias. Pero yo estaba echado para anotar con

@EnableWebMvc 

mi clase @Configuration

Cuestiones relacionadas