wake-up-neo.net

Spring-JSON-Anforderung, die 406 erhält (nicht akzeptabel)

das ist mein Javascript:

    function getWeather() {
        $.getJSON('getTemperature/' + $('.data option:selected').val(), null, function(data) {
            alert('Success');                               
        });
    }

das ist mein Controller:

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
@ResponseBody
public Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

spring-servlet.xml

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

Diesen Fehler erhalten:

GET http://localhost:8080/web/getTemperature/2 406 (Not Acceptable)

Header:

Antwortheader

Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  1070
Date    Sun, 18 Sep 2011 17:00:35 GMT

Anforderungsheader

Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
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
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/web/weather
Cookie  JSESSIONID=7D27FAC18050ED84B58DAFB0A51CB7E4

Interessante Anmerkung:

Ich bekomme einen 406-Fehler, aber die Abfrage für den Ruhezustand funktioniert mittlerweile. Dies sagt das Tomcat-Protokoll, wenn ich die Auswahl in der Dropbox ändere:

 select weather0_.ID as ID0_0_, weather0_.CITY_ID as CITY2_0_0_, weather0_.DATE as DATE0_0_, weather0_.TEMP as TEMP0_0_ from WEATHER weather0_ where weather0_.ID=?

Was könnte das Problem sein? Es gab zuvor zwei ähnliche Fragen in SO, ich habe alle dort akzeptierten Hinweise ausprobiert, aber sie funktionierten nicht, denke ich.

Irgendwelche Vorschläge? Fühlen Sie sich frei, Fragen zu stellen ...

77
Jaanus

406 nicht akzeptabel

Die durch die Anforderung identifizierte Ressource kann nur Antwortentitäten erzeugen, deren Inhaltseigenschaften nicht akzeptabel sind, entsprechend den in der Anforderung gesendeten Annahmeheadern.

Der Header Ihrer Anfrage Accept ist also application/json und Ihr Controller kann das nicht zurückgeben. Dies geschieht, wenn der korrekte HTTPMessageConverter nicht gefunden werden kann, um den annotierten Rückgabewert von @ResponseBody zu erfüllen. HTTPMessageConverter wird automatisch registriert, wenn Sie den <mvc:annotation-driven> verwenden, wenn bestimmte Bibliotheken von Drittanbietern im Klassenpfad angegeben sind.

Entweder haben Sie nicht die richtige Jackson-Bibliothek in Ihrem Klassenpfad oder Sie haben die <mvc:annotation-driven>-Direktive nicht verwendet.

Ich habe Ihr Szenario erfolgreich repliziert und es hat gut funktioniert, wenn Sie diese beiden Bibliotheken und keine headers="Accept=*/*"-Direktive verwenden.

  • jackson-core-asl-1.7.4.jar
  • jackson-mapper-asl-1.7.4.jar
103
Villu Sepman

Ich hatte dasselbe Problem, mit Latest Spring 4.1.1 müssen Sie folgende Pars zu pom.xml hinzufügen.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.4.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.1.1</version>
</dependency>

stellen Sie auch sicher, dass Sie folgendes Glas haben:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

406 Spring MVC Json, nicht zulässig gemäß der Anforderung "Accept" -Header

71
bekur

In einem anderen Fall wird dieser Status zurückgegeben: Wenn der Jackson-Mapper nicht herausfinden kann, wie die Bean serialisiert wird. Wenn Sie beispielsweise über zwei Zugriffsmethoden für dieselbe boolesche Eigenschaft verfügen, isFoo() und getFoo().

Was passiert, ist, dass Spring MappingJackson2HttpMessageConverter Jackson StdSerializerProvider aufruft, um zu sehen, ob er Ihr Objekt konvertieren kann. Am unteren Ende der Anrufkette wirft StdSerializerProvider._createAndCacheUntypedSerializer eine JsonMappingException mit einer informativen Nachricht. Diese Ausnahme wird jedoch von StdSerializerProvider._createAndCacheUntypedSerializer verschluckt, was Spring mitteilt, dass das Objekt nicht konvertiert werden kann. Nachdem keine Konverter mehr vorhanden sind, meldet Spring, dass ihm kein Accept-Header zur Verfügung steht, den er verwenden kann, was natürlich falsch ist, wenn Sie ihm */* geben.

Es gibt ein bug für dieses Verhalten, das jedoch als "nicht reproduzierbar" geschlossen wurde: Die gerufene Methode gibt nicht an, dass sie werfen kann, daher ist das Schlucken von Ausnahmen anscheinend eine geeignete Lösung (ja, das war Sarkasmus ). Leider hat Jackson keine Protokollierung ... und es gibt viele Kommentare in der Codebase, die dies wünschen, also vermute ich, dass dies nicht die einzige versteckte gotcha ist.

15
kdgregory

Ich hatte das gleiche Problem, meine Controller-Methode wird ausgeführt, aber die Antwort ist Fehler 406. Ich debugge AbstractMessageConverterMethodProcessor#writeWithMessageConverters und stellte fest, dass ContentNegotiationManager#resolveMediaTypes immer text/html zurückgibt, was von MappingJacksonHttpMessageConverter nicht unterstützt wird. Das Problem ist, dass org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy früher als org.springframework.web.accept.HeaderContentNegotiationStrategy funktioniert, und die Erweiterung meiner Anforderung /get-clients.html ist die Ursache für mein Problem mit Fehler 406. Ich habe gerade die Anforderungs-URL in /get-clients geändert.

14
atott

Stellen Sie sicher, dass folgende 2 jars im Klassenpfad vorhanden sind.

Wenn einer oder beide fehlen, wird dieser Fehler angezeigt.

jackson-core-asl-1.9.X.jar jackson-mapper-asl-1.9.X.jar
9
Raju Rathi

Endlich Antwort von hier gefunden:

Mapping ruhiger Ajax-Anfragen zum Frühling

Ich zitiere:

@ RequestBody/@ ResponseBody-Annotationen verwenden keine normalen Ansichtsauflöser, sie verwenden ihre eigenen HttpMessageConverters. Um diese Annotationen verwenden zu können, sollten Sie diese Konverter in AnnotationMethodHandlerAdapter wie in der Referenz beschrieben konfigurieren (wahrscheinlich benötigen Sie MappingJacksonHttpMessageConverter).

5
Jaanus

Überprüfen Sie <mvc:annotation-driven /> in dispatcherservlet.xml, wenn nicht, fügen Sie es ..__ hinzu 

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

diese Abhängigkeiten in Ihrer pom.xml 

3
SHIVA
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-base</artifactId>
    <version>2.6.3</version>
</dependency>
2
Rajan

Wahrscheinlich scrollt niemand so weit nach unten, aber keine der oben genannten Lösungen hat es für mich behoben, aber alle meine Getter-Methoden machten public.

Ich hatte meine Sichtbarkeit bei Paketsprivate verlassen. Jackson entschied, dass es sie nicht finden konnte und sprengte. (Mit @JsonAutoDetect(getterVisibility=NON_PRIVATE) wurde es nur teilweise behoben.

1
Hazel Troost

Als @atott erwähnt .

Wenn Sie die neueste Version von Jackson in Ihrer pom.xml hinzugefügt haben und Spring 4.0 oder neuer verwenden, verwenden Sie @ResponseBody für Ihre Aktionsmethode und @RequestMapping, die mit produces="application/json;charset=utf-8" konfiguriert sind. Sie haben jedoch immer noch 406 (nicht akzeptabel) Versuchen Sie dies in Ihrer MVC DispatcherServlet-Kontextkonfiguration:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
</bean>

So habe ich mein Problem endlich gelöst.

1
Raven

Ich hatte das gleiche Problem, weil mir die Annotation @EnableMvc fehlte. (Meine gesamte Federkonfiguration basiert auf Annotation, das XML-Äquivalent wäre mvc: annotation-driven).

1
jambriz

Sollte im Controller die Antworttextannotation nicht auf den Rückgabetyp und nicht auf die Methode lauten:

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
public @ResponseBody Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

Ich würde auch die RAW-Funktion jquery.ajax verwenden und sicherstellen, dass contentType und dataType richtig eingestellt sind.

Anders ausgedrückt finde ich das Federhandling von Json eher problematisch. Es war einfacher, wenn ich alles selbst mit Strings und GSON gemacht habe.

1
NimChimpsky

Frühling 4.3.10: Ich habe die folgenden Einstellungen verwendet, um das Problem zu beheben.

Schritt 1: Fügen Sie die folgenden Abhängigkeiten hinzu

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

Schritt 2: Fügen Sie Folgendes in Ihre MVC DispatcherServlet-Kontextkonfiguration ein:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>

<bean id="contentNegotiationManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false"/>
    <property name="favorParameter" value="true"/>
    <property name="ignoreAcceptHeader" value="false" />
</bean>

Seit Frühjahr 3.2 ist favorPathExtension laut der Standardkonfiguration auf true gesetzt, wenn die Anfrage-URI über geeignete Erweiterungen verfügt, wie .htm spring der Erweiterung Priorität einräumt. In Schritt 2 hatte ich die Bean contentNegotiationManager hinzugefügt, um dies zu überschreiben.

Ich hatte das gleiche Problem leider nicht von der Lösung hier gelöst, mein Problem war etwas in einer anderen Klasse. 

Ich habe zuerst geprüft, ob alle Abhängigkeiten vorhanden sind, wie von @bekur .__ vorgeschlagen. Dann habe ich die Anfrage/Antwort überprüft, die von Clients an den Server übermittelt wird. Dann überprüfte ich die RequestMappingHandlerAdapterMessageConverters und alle 7 waren an Ort und Stelle, ich fing wirklich an, den Frühling zu hassen! Ich habe dann ein Update von Spring 4.0.6.RELEASE auf 4.2.0.RELEASE durchgeführt. Ich habe eine andere Antwort als die oben genannte. Es war Request processing failed; nested exception is Java.lang.IllegalArgumentException: No converter found for return value of type 

Hier ist meine Controller-Methode 

  @RequestMapping(value = "/upload", method = RequestMethod.POST,produces = "application/json")
    public ResponseEntity<UploadPictureResult> pictureUpload(FirewalledRequest initialRequest) {

        DefaultMultipartHttpServletRequest request = (DefaultMultipartHttpServletRequest) initialRequest.getRequest();

        try {
            Iterator<String> iterator = request.getFileNames();

            while (iterator.hasNext()) {
                MultipartFile file = request.getFile(iterator.next());
                session.save(toImage(file));
            }
        } catch (Exception e) {
            return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(),HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(), HttpStatus.OK);
    } 




    public class UploadPictureResult extends WebResponse{

    private List<Image> images;

    public void setImages(List<Image> images) {
        this.images = images;
    }
}






    public class WebResponse implements Serializable {


    protected String message;

    public WebResponse() {
    }

    public WebResponse(String message) {

        this.message = message;
    }


    public void setMessage(String message) {
        this.message = message;
    }
}

Die Lösung bestand darin, UploadPictureResult WebResponse nicht zu erweitern 

Aus irgendeinem Grund konnte spring nicht feststellen, wie UploadPictureReslt konvertiert werden soll, wenn WebResponse erweitert wurde 

0
Adelin

Dies ist die Update-Antwort für springVersion = 5.0.3.RELEASE.  

Die obigen Antworten werden nur ältere SpringVersion <4.1 Version bearbeitet. Für den letzten Frühling müssen Sie folgende Abhängigkeiten in Gradle-Datei hinzufügen:

compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: fasterxmljackson
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: fasterxmljackson

fasterxmljackson=2.9.4

Ich hoffe, dass dies für diejenigen hilfreich ist, die die neueste Frühlingsversion verwenden.

Abgesehen von den offensichtlichen Problemen hatte ich noch ein anderes, das ich nicht beheben konnte, unabhängig davon, welche JARs, Abhängigkeiten und Anmerkungen in Spring-Servlet enthalten waren. Schließlich fand ich, dass ich eine falsche Dateierweiterung habe. Ich meine, ich hatte zwei separate Servlets, die in demselben Container ausgeführt wurden, und musste verschiedenen Dateierweiterungen zugeordnet werden, von denen eine ".do" war und der andere, der für Subskriptionen verwendet wurde, zufällig den Namen "" hatte. sub ". Alles andere als SUB ist eine gültige Dateierweiterung, die normalerweise für Untertiteldateien von Filmen verwendet wird. Daher überschrieb Tomcat die Kopfzeile und gab etwas wie "text/x-dvd.sub ..." zurück. Also war alles in Ordnung, aber die Anwendung erwartete JSON, erhielt aber Untertitel Daher musste ich nur das Mapping in meiner web.xml-Datei ändern, die ich hinzugefügt habe:

<mime-mapping>
    <extension>sub</extension>
    <mime-type>application/json</mime-type>
</mime-mapping>
0
infinity

Prüfen Sie, wie @joyfun die korrekte Version von jackson getan hat, aber überprüfen Sie auch unsere Header ... Accept/kann vom Client nicht übertragen werden ... Verwenden Sie Firebug oder ein ähnliches Element, um zu überprüfen, was Ihre Get-Anfrage tatsächlich sendet. Ich denke, das Kopfzeilen-Attribut der Anmerkung kann/kann/prüfen, obwohl ich nicht zu 100% sicher bin.

0
Dave G
<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.0</version>
    </dependency>

ich verwende keine SSL-Authentifizierung und dieses Jackson-Datenbind enthält die Dateien jackson-core.jar und jackson-databind.jar. Anschließend ändern Sie den Inhalt des RequestMapping wie folgt:

@RequestMapping(value = "/id/{number}", produces = "application/json; charset=UTF-8", method = RequestMethod.GET)
public @ResponseBody Customer findCustomer(@PathVariable int number){
    Customer result = customerService.findById(number);
    return result;
}

Achtung: Wenn Ihre Produkte nicht vom Typ "application/json" sind und ich dies nicht mitbekommen habe und einen 406-Fehler erhalten habe, kann Ihnen dies helfen.

0
Crabime

stellen Sie sicher, dass Sie eine korrekte Jackson-Version in Ihrem Klassenpfad haben

0
joyfun

Überprüfen Sie diesen Thread . spring mvc restcontroller geben json string p/s zurück: Sie sollten der WebMvcConfig-Klasse Jack Son Mapping config hinzufügen

@Override protected void configureMessageConverters( List<HttpMessageConverter<?>> converters) { // put the jackson converter to the front of the list so that application/json content-type strings will be treated as JSON converters.add(new MappingJackson2HttpMessageConverter()); // and probably needs a string converter too for text/plain content-type strings to be properly handled converters.add(new StringHttpMessageConverter()); }

0
Anh Lam

Stellen Sie sicher, dass das gesendete Objekt (Wetter in diesem Fall) Getter/Setter enthält

0
Riadh