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 Javascript
AJAX
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.
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.
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>
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
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>
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
}
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
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>
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.
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:
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.
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
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>
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.
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.