web-dev-qa-db-fra.com

Spring 3.x Statut JSON 406 "Caractéristiques non acceptables selon la demande" Accepter "en-têtes ()"

En essayant d'obtenir ma réponse dans JSON en utilisant Spring 3.x, j'obtiens le 406 error "La ressource identifiée par cette demande est uniquement capable de générer des réponses avec des caractéristiques non acceptables selon request" accepter "en-têtes ()."

Voici mon environnement

* Spring 3.2.0.RELEASE
* included jackson-mapper-asl-1.7.9.jar, jackson-core-asl-1.7.9.jar
* Tomcat 6.x
* mvc:annotation-driven in Spring configuration XML file

Mon contrôleur: 

@RequestMapping("/contest")
public class ContestController {

    @RequestMapping(value="{name}", headers="Accept=*/*", method = RequestMethod.GET)
    public @ResponseBody Contest getContestInJSON(@PathVariable String name) {
        Contest contest = new Contest();
        contest.setName(name);
        contest.setStaffName(new String("contestitem1"));

        return contest;
    }

}

Mon fichier de configuration Spring

<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"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<context:component-scan base-package="com.contestframework.controllers" />

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">

<property name="mediaTypes">
    <map>
      <entry key="atom" value="application/atom+xml"/>
      <entry key="html" value="text/html"/>
      <entry key="json" value="application/json"/>
    </map>
 </property>

 <property name="viewResolvers">
 <list>
  <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/"/>
    <property name="suffix" value=".jsp"/>
  </bean>
 </list>
 </property>

 <property name="defaultViews">
  <list>
   <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
  </list>
 </property>

 </bean>

<mvc:annotation-driven />

</beans>

Après cela, je viens d’accéder au contrôleur en utilisant ci-dessous:

http://domain/SpringWebProject/json/contest/abcd

et la réponse que j’obtiens est le statut 406: "La ressource identifiée par cette demande est uniquement capable de générer des réponses avec des caractéristiques non acceptables selon la requête" accepte "les en-têtes ()."

J'ai aussi essayé un autre mécanisme en accédant à ceci en utilisant JavascriptAJAX pour m'assurer que l'en-tête de ma demande a application/JSON, mais cela a conduit au même résultat Statut 406

$.getJSON('contest/abcd', function(data) {
console.log(data) }

Voici ma DEMANDE EN-TÊTE capturée à partir du navigateur:

Request URL:http://localhost:8080/SpringWebProject/json/contest/abcd
Request Method:GET
Status Code:406 Not Acceptable

Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:JSESSIONID=59689C95B0B9C21494EB0AB9D9F7BCCD
Host:localhost:8080
Referer:http://localhost:8080/SpringWebProject/json/welcome
User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
X-Requested-With:XMLHttpRequest
Response Headersview source
Content-Length:1070
Content-Type:text/html;charset=utf-8
Date:Fri, 12 Oct 2012 18:23:40 GMT
Server:Apache-Coyote/1.1

Appréciez toute aide à cet égard.

41
user1740567

Il n’ya rien de mal dans votre configuration, laissez-moi vous suggérer quelques petites modifications:

a) Vos espaces de noms semblent incorrects - ils font référence aux schémas 3.0, il suffit de les changer en 3.1 ou de ne pas faire explicitement référence à la version, de cette façon par exemple.

xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans.xsd

OU 

xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

b) Vous n'avez pas besoin de ContentNegotiatedViewResolver, vous pouvez tout supprimer sauf les component-scan et <mvc:annotation-driven/> de votre configuration.

c) La requête ne fonctionnera pas directement à partir du navigateur car elle requiert explicitement un en-tête Accept de "application/json" - l'appel $.getJson devrait fonctionner, car il envoie les en-têtes appropriés.

d) Supprimez le headers=Acc.. de @RequestMapping et produit également des critères de filtrage pour faire correspondre le bon appel de méthode mappée.

Avec cela, il n'y a aucune raison pour que le JSON ne soit pas servi, pouvez-vous s'il vous plaît essayer avec cela et voir comment ça se passe.

19
Biju Kunjummen

Je viens aussi de vivre ce même problème. Il semblerait que ce soit un problème avec la dernière version 3.2.0.RELEASE, comme j’avais précédemment eu 3.1.2.RELEASE et que tout fonctionnait bien. Après passage à 3.2.0.RELEASE, il se brise. J'ai testé avec 3.1.3.LELEASE et cela fonctionne bien. Donc, pour le moment, je suggère de revenir à la version 3.1.3.LELEASE

EDIT: Merci à un autre message sur ce site qui a un lien vers l’emplacement suivant: http://static.springsource.org/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html# mvc-config-content-negotiations

Je travaille maintenant en désactivant l'obtention du type de média en fonction de l'extension du chemin demandé. Cela peut être fait par ce qui suit:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers -->
    <property name="favorPathExtension" value="false" />
</bean>

Et spécifiez la version 3.2 pour tous les emplacements de schéma xsd.

Et ceci utilise les pots Jackson suivants:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.1.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.1.2</version>
</dependency>
49
annihilate

J'ai eu le même problème et je l'ai résolu en ajoutant la dépendance suivante

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>${jackson.version}</version>
</dependency>

Auparavant, je le fais avec la dépendance suivante

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${com.jackson.core-version}</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>${com.jackson.core-version}</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${com.jackson.core-version}</version>
</dependency>

En bref, je remplace com.fasterxml.jackson.core par org.codehaus.jackson

11
Anupam Pawar

J'ai eu ce problème dans Spring MVC 4. L'ajout des annotations jackson, jackson-core et jackson-databind n'a pas résolu le problème. Essayez cette bibliothèque:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.1.2</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.1.2</version>
</dependency>
<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.9.13</version>
</dependency>
8
Weslei Prudencio

Je pense que vous devez ajouter un produit = "application/json" à votre @RequestMapping (vous n'avez pas regardé Spring mvc depuis un moment, donc je ne suis pas 100% positif) ...

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html

16.3.2.6 Types de supports de production

Vous pouvez restreindre le mappage principal en spécifiant une liste de types de supports pouvant être produits. La demande ne sera mise en correspondance que si l'en-tête de demande Accepter correspond à l'une de ces valeurs. De plus, l'utilisation de la condition de production garantit que le type de contenu utilisé pour générer la réponse respecte les types de support spécifiés dans la condition de production. Par exemple:

@Controller
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {    
    // implementation omitted
}
7
les2

J'ai eu le même problème et le commentaire ajouté par Biju Kunjummen dans cette réponse a parfaitement fonctionné pour moi

https://stackoverflow.com/a/12873170/20654

C'est avoir des getters publics dans ma classe Java

7
OscarRyz

J'ai eu un problème similaire, il a été résolu lorsque j'ai ajouté la bibliothèque jackson-databind.

Ce sont mes dépendances:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.12</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.3</version>
</dependency>
6
burcakulug

Ne commettez pas la même erreur que moi, passez toute la journée à jouer avec la configuration de Spring, alors qu'en fait votre objet renvoyé dans un service Web n'est pas correctement marshalé en XML. Il semble que Spring détecte une erreur de marshaling JAXB et ne la signale pas. Utilisez ce code pour valider le marshaling JAXB:

MyClass myclass = new MyClass();
//populate myclass here

JAXBContext context = JAXBContext.newInstance(MyClass.class);

Marshaller m = context.createMarshaller();
StringWriter w = new StringWriter();

m.marshal(myclass, w);
System.out.println(w);

Cela a produit et affiché une exception. La cause a été corrigée et mon service Web est disponible à la fois en XML et en JSON. 

4
Steven Neiner

Merci de partager votre expérience. J'ai rencontré le même problème et cela fonctionne pour moi en utilisant la configuration comme indiqué ci-dessous:

  1. Spring MVC Version: 3.2.5.RELEASE
  2. Apache-Tomcat-6.0.24
  3. JDK1.6
  4. jackson-core-asl-1.9.10.jar
  5. jackson-mapper-asl-1.9.10.jar

Fichier de configuration MVC Spring: 

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers -->
    <property name="favorPathExtension" value="false" />
</bean>

Classe de modèle: Country.Java

 private Integer countryId;
 private String name;
 //public setters and getters

Méthode du contrôleur:

@RequestMapping(value = "/get_country_json",method = RequestMethod.GET)
@ResponseBody
public Country getCountry()

Descripteur de déploiement (web.xml)

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

URL requise pour appeler la méthode du contrôleur: /SpringCURDApp/get_country_json.htm

J'espère que cela peut aider quelqu'un.

4
Vikram Thakur

Prochainement: 

Pour Spring MVC 4.1.6, il y en a assez: 

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

(jackson-databind} _ a une dépendance sur les artefacts core et annotations.


En détails:

Qu'est-ce que l'erreur HTTP 406

406 Inacceptable La ressource demandée est uniquement capable de générer un contenu inacceptable selon les en-têtes Accepter envoyés dans la demande.

Cela signifie que le serveur ne peut pas générer de contenu que MEDIA TYPE déclaré dans Accepter En-tête. 

Mais comment le serveur sait-il quel MEDIA TYPE il peut générer et lequel non? 

Spring Web a le concept de HttpMessageConverter . Certains de ces convertisseurs sont déjà enregistrés dans Spring et AbstractMessageConverterMethodArgumentResolver les conserve dans la propriété messageConverters.

Pendant le traitement de la demande AbstractMessageConverterMethodProcessor analyse ce que spring peut convertir et enregistre toutes les variables MEDIA TYPES} prises en charge dans productibleMediaTypes variable. Si vous le souhaitez, MEDIA TYPE n'est pas réalisable, puis affiche l'erreur 406 == Je ne peux pas générer le type de support demandé. Pardon.

Pour couper la longue histoire - enregistrez les convertisseurs requis. Dans votre cas, c'est la bibliothèque jackson qui produit application/json

3
Sergii Shevchyk

Peut-être devriez-vous mettre à jour votre bibliothèque jackson. J'utilise Spring v4.3.8 et je l'utilise comme suit:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.8.7</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.8.7</version>
</dependency>
0
Allen

Veuillez consulter http://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-config-content- negociation tu peux voir 

"Pour les extensions de fichier dans l'URI de la demande, la configuration Java MVC et l'espace de noms MVC, enregistre automatiquement les extensions telles que .json, .xml, .Rss et .atom si les dépendances correspondantes, telles que Jackson , JAXB2 ou Rome sont présents sur le chemin de classe. "

Vous devez ajouter ".json" à la fin de l'URI (comme http: //domain/SpringWebProject/json/contest/abcd.json ) Cela fonctionne pour moi. 

0

J'ai eu le même problème, mais c'était bizarre. Je vais expliquer comment je l'ai résolu. 

Dans mon web.xml, mon servlet dispacher a été mis en correspondance avec * .htm

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

et peu importe ce que j'ai fait, ça a toujours jeté -

La ressource identifiée par cette requête est uniquement capable de générer des réponses avec des caractéristiques non acceptables selon l'en-tête de requête "accepter"

Finalement je l'ai changé pour

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

et cela a fonctionné. Ce que je pense, c'est quand vous spécifiez 

<mvc:annotation-driven/> 

l'extension est prioritaire sur accept en-tête et .htm créait des problèmes. Et évidemment, je ne pouvais pas utiliser xml ou json car le servlet lui-même n'était pas mappé. 

Je voudrais aussi ajouter que produit une annotation que Spring essaiera de mapper et acceptera l’en-tête de la demande entrante. Je faisais la méthode de gestionnaire de demandes générique pour JSON et XML. Depuis que j’utilise Java 8 et que Jaxb est intégré à Java, Java 7 n’ayant pas besoin de dépendance JAXB. Pour JSON, je n’avais besoin que d’ajouter -

<dependency org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.8.5"/>

J'utilise ivy pour la gestion de la dépendance.

0
Aniket Thakur