42 votes

Spring 3.x JSON status 406 "caractéristiques non acceptables selon les en-têtes de la requête "accept" ()".

En essayant d'obtenir ma réponse en JSON en utilisant Spring 3.x, j'obtiens l'erreur 406 "La ressource identifiée par cette requête est seulement capable de générer des réponses avec des caractéristiques non acceptables selon les en-têtes "accept" de la requête ()".

Voici mon environnement

  • Spring 3.2.0.RELEASE
  • inclus jackson-mapper-asl-1.7.9.jar, jackson-core-asl-1.7.9.jar
  • Tomcat 6.x
  • mvc:annotation-driven dans le fichier XML de configuration de Spring

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 de 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, j'accède simplement au contrôleur en utilisant la méthode 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 requête est seulement capable de générer des réponses avec des caractéristiques non acceptables selon les en-têtes "accept" de la requête ()".

J'ai également essayé un mécanisme alternatif en accédant à ceci en utilisant javascript ajax pour m'assurer que mon en-tête de demande a application/JSON mais cela a conduit au même résultat Status 406

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

Voici mon REQUEST HEADER capturé à 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

J'apprécierais toute aide à cet égard.

49voto

annihilate Points 418

Je viens également de rencontrer ce même problème. Il semblerait que ce soit un problème avec la dernière version 3.2.0.RELEASE, car j'avais auparavant la version 3.1.2.RELEASE et tout fonctionnait. Après être passé à la version 3.2.0.RELEASE, tout s'est arrêté. J'ai testé avec 3.1.3.RELEASE et cela fonctionne bien. Donc, pour l'instant, je vous suggère de revenir à la version 3.1.3.RELEASE.

EDIT : Merci à un autre post sur ce site qui a fait 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-negotiation

J'ai réussi à le faire fonctionner en désactivant l'obtention du type de média basé sur l'extension du chemin demandé. Cela peut être fait de la manière suivante :

<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 du schéma xsd.

Et ceci en utilisant les jarres jackson suivantes :

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

19voto

Biju Kunjummen Points 20258

Il n'y a rien d'anormal dans votre configuration. Permettez-moi cependant de suggérer quelques petites modifications :

a) Vos espaces de noms semblent erronés - ils font référence aux schémas 3.0, changez-les en schémas 3.1 ou ne faites pas référence à la version explicitement, 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 du ContentNegotiatingViewResolver, vous pouvez tout supprimer sauf le composant component-scan y <mvc:annotation-driven/> de votre configuration

c) La demande ne fonctionnera pas directement à partir du navigateur car elle requiert explicitement un en-tête Accept de "application/json". $.getJson devrait fonctionner car il envoie les bons en-têtes.

d) Retirer le headers=Acc.. de l'@RequestMapping, et produit également, les deux sont des critères de filtrage pour faire correspondre l'appel de méthode mappé correct.

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

11voto

Anupam Pawar Points 71

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, j'ai remplacé com.fasterxml.jackson.core par com.fasterxml.jackson.core

8voto

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

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

7voto

les2 Points 3854

Je pense que vous devez ajouter un produces="application/json" à votre @RequestMapping (je n'ai pas regardé spring mvc depuis un moment donc je ne suis pas sûr à 100%) ...

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

16.3.2.6 Types de milieux productibles

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

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X