2010-12-07 14 views
10

Ich habe gerade angefangen, den Virgo Web Server zu lernen. Ich versuche mit Jakcson JSON in Spring MVC-Anwendung zu arbeiten. In dieser Phase kann ich ein serialisiertes GET-Objekt nicht abrufen. Der Server gibt "406 Not Acceptable":406 Nicht akzeptabel im Frühling MVC-Anwendung (OSGi, Virgo Web Server) mit Jackson, Rom und JAXB2

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

Das gleiche Problem tritt auf, wenn Rom und JAXB2 verwenden. Hier

ist die Projektkonfigurationsdateien und 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 - Servieren 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 Anfrage http://localhost:8080/greenpages/json.htm: Anfrageheaders von 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 

Antwortheader:

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 was kann das Problem sein?

Antwort

2

Weitere Informationen finden Sie unter http://www.checkupdown.com/status/E406.html. Ihre Client-App teilt dem Server mit, dass er die Art der zurückgesendeten Daten nicht akzeptiert.

Ich bin nicht vertraut mit den libs etc, die Sie verwenden, aber Sie sollten in der Lage sein, Ihre Header akzeptieren programmatisch (oder über etwas wie Firebug) zu sehen, was gesetzt wird. Sie können das hoffentlich dann in Ihrem Quellcode/Ihrer Konfiguration finden.

Bei einer Schätzung erwarte ich, dass Ihr Client JSON fordert, zurück zu kommen, und Ihr Server sendet es nicht.

+0

I-Daten-Request-Header von Firebug hinzugefügt. Danke für Ihre Antwort. – Alexey

+0

@Alexey - OK, das ist interessant, es sieht so aus, als würdest du die richtigen Header senden. Das bedeutet theoretisch, dass Ihr Server json oder Javascript nicht zurückgibt. Ich persönlich habe die Spring Web Services noch nicht benutzt, aber gibt es eine Möglichkeit, die Antwort abzufangen/zu inspizieren, um sicherzustellen, dass es wirklich json ist? –

16

Stellen Sie sicher, <mvc:annotation-driven> in dispatcher-servlet.xml haben - es konfiguriert Feder für Anmerkungen Einsatz neuer wie @ResponseBody.

Auch ich sehe Sie haben einige Verwirrung in der Kontextkonfiguration - dispatcher-servlet.xml wird verwendet, um DispatcherServlet 's Kontext zu konfigurieren, sollte es nicht in contextConfigLocation des übergeordneten Kontext angegeben werden.

+0

Posted die falsche Datei in der Dispatcher-Servlet.xml, bearbeitet. Ja, ich verwende in der Dispatcher-Servlet.xml. Ich habe contextConfigLocation des übergeordneten Kontexts in applicationContext.xml geändert, jetzt dispatcher-servlet.xml, das nur für den DispatcherServlet-Kontext verwendet wird. Aber der Fehler bleibt bestehen. Danke für Ihre Antwort. – Alexey

+2

@Alexey: Stellen Sie sicher, dass Sie "AnnotationMethodHandlerAdapter" nicht explizit deklariert haben. – axtavt

+0

@axtavt Ihre Lösung hat perfekt funktioniert, danke! :) – ManiSto

0

@axtavt können Sie bitte lassen Sie mich wissen, was meinst du mit keine explizite Erklärung auf AnnotationMethodHandlerAdapter. Ich habe folgende Deklaration in meiner Servlet-Datei und ich bekomme 404.

23

Die Feder fällt zurück auf die Rückgabe einer 406, wenn sie keinen JSON-Konverter finden kann.

Überprüfen Sie, ob die jackson jars tatsächlich im lib-Verzeichnis der webapp implementiert sind. Das war das Problem in meinem Fall.

1

Ich stieß auf das gleiche Problem, und ich frage mich, ob das Folgende die Ursache sein könnte.

Die Klasse AnnotationDrivenBeanDefinitionParser prüft den Klassenpfad auf Verfügbarkeit von jaxb2/jackson. Es verwendet die folgende Logik, dies zu tun:

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

Jetzt, in der Regel des Anwendungskontext des Bundles würde einen OSGi-aware Klassenlader bieten. Die Variable jaxb2present ist jedoch statisch und wird daher beim Laden der Klasse statisch gesetzt, bevor sie vom Anwendungskontext instanziiert wird. Ich vermute, dass der Klassenlader zu diesem Zeitpunkt nicht osgifähig ist und daher die gesuchte Klasse nicht finden kann.

Vorerst ich die einzige Lösung gehe davon ist manuell eine Jaxb2HttpMessageConverter (was ich nicht weiß, verkabeln, wie noch zu tun :-)

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

public @ResponseBody 

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

} 

Diese 406 Fehler zurückgibt. Wenn ich den Return-Typ int in String umwandle, ist das Problem verschwunden.

See

3

Ich hatte genau das gleiche Problem und alles, was ich brauchte, war öffentlich Getter in meiner Java-Klasse zu setzen: https://stackoverflow.com/a/18228476/20654

+1

Das war mein Fall, danke! –

+0

Ich hatte ähnliches Problem und das war auch bei mir der Fall –

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

Ich hatte ein ähnliches Problem, wo ich einen Fehler 406 bekam, weil das Java-Objekt, das ich zurückgeben wollte, nicht mit einem XmlRootElement oberhalb der Klassendefinition annotiert wurde. Die Methode zurückgegeben JSON ohne Problem, wenn ich die mitgelieferte Akzeptiert = application/json-Header auf die Anfrage aber 406 zurück, wenn ich das Akzeptieren enthalten = application/xml-Header auf die Anfrage

I Postman verwendet, um die Header zu ändern und sehen die Antworten. Sehr praktisches Werkzeug.

0

Ich hatte den gleichen Fehler. Aber ich habe Java Annotationen benutzt, ich habe alle notwendigen Abhängigkeiten. Aber ich verpasst wurde mit

@EnableWebMvc 

meine @Configuration Klasse mit Anmerkungen versehen