J'utilise Spring MVC avec JSON comme spécifié dans Ajax Simplification Spring 3.0 article .
Après de nombreuses tentatives et variations de mon code en fonction des conseils fournis sur différents forums, mon code ne fonctionne toujours pas.
Je continue d’obtenir l’erreur suivante: (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 "accepter" en-têtes ().
J'ai dans mon appconfig.xml comme requis.
app-config.xml
<context:component-scan base-package="org.ajaxjavadojo" />
<!-- Configures Spring MVC -->
<import resource="mvc-config.xml" />
mvc-config.xml
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "index" view -->
<mvc:view-controller path="/" view-name="index"/>
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<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/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
</bean>
C'est ce que j'ai pour mon contrôleur
@Controller
@RequestMapping (value = "/convert")
public class ConversionController {
@RequestMapping(method=RequestMethod.GET)
public String getConversionForm(){
return "convertView";
}
@RequestMapping(value = "/working", headers="Accept=application/json", method=RequestMethod.GET)
public @ResponseBody Conversion getConversion(){
Conversion d = new Conversion("d");
return d;
}
}
jsp jquery call
function convertToDecimal(){
$.getJSON("convert/working", {key: "r"}, function(aConversion){
alert("it worked.");
$('#decimal').val(aConversion.input);
});
}
J'apprécierais vraiment toute contribution sur ce sujet. Je vous remercie
Essayez de supprimer la limitation d'en-tête pour Accept
, mettez un point d'arrêt et voyez quelle est la valeur réelle. Ou faites ceci avec FireBug.
Jetez également un coup d’œil à ce problème jquery
Pour retourner une réponse JSON à partir de la méthode annotée @ResponseBody
-, vous avez besoin de deux choses:
<mvc:annotation-driven />
(vous l'avez déjà)Vous n'avez pas besoin de ContentNegotiatingViewResolver
et headers
dans @RequestMapping
.
J'ai eu ce problème après avoir mis à niveau Spring à 4.1.x à partir de 3.2.x. J'ai corrigé en mettant à niveau Jackson de 1.9.x à 2.2.x (plus rapide).
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
Ajoutez org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
et org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
à DispatcherServlet-servlet.xml. et se référer au premier dans la seconde en utilisant
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jacksonMessageConverter"/>
</list>
</property>
</bean>
Moi aussi j'ai eu cette erreur et en déboguant au fond du trou du lapin je suis tombé sur cette exception
Java.lang.IllegalArgumentException: définitions getter en conflit pour la propriété "erreur": com.mycomp.model.OutputJsonModel # isError (0 paramètres) et com.mycomp.model.OutputJsonModel # getError (0 paramètres)
Donc, fondamentalement, dans mon haricot Java, j'avais quelque chose comme:
private boolean isError;
private ErrorModel error;
public ErrorModel getError() {
return error;
}
public void setError(ErrorModel error) {
this.error = error;
}
public boolean isError() {
return isError;
}
public void setError(boolean isError) {
this.isError = isError;
}
Changer l'un des noms de variable membre d'erreur en un autre élément résolut les problèmes.
J'ai eu ce problème aussi, vous devez ajouter <mvc:annotation-driven />
dans votre configuration xml
et
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind-version}</version>
</dependency>
dans votre pom.xml
J'ai utilisé la configuration Java et j'ai eu la même erreur. J'ai manqué d'ajouter le @EnableWebMvc au fichier de configuration. Cette erreur est résolue après l’ajout du @EnableWebMvc dans mon fichier webconfig.
De plus, l'objet renvoyé par votre contrôleur Spring doit avoir les méthodes de lecture et de définition appropriées.
package com.raghu.dashboard.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.raghu.dashboard.dao.ITaskDAO;
import com.raghu.dashboard.dao.TaskDAOImpl;
@Configuration
@EnableWebMvc //missed earlier...after adding this it works.no 406 error
@ComponentScan(basePackages = { "com.raghu.dashboard.api", "com.raghu.dashboard.dao" })
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() { return null;}
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MongoConfiguration.class};
}
protected String[] getServletMappings() {
return new String[]{"*.htm"};
}
@Bean(name = "taskDao")
public ITaskDAO taskDao() {
return new TaskDAOImpl();
}
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
return resolver;
}
}
AppInitializer.Java
package com.raghu.dashboard.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class AppInitalizer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext)
throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(com.raghu.dashboard.config.WebConfig.class);
context.scan("com.raghu.dashboard.api");
return context;
}
}
Assurez-vous également que l'objet qui est renvoyé a le getter et le setter appropriés.
Exemple:
@RequestMapping(value = "/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<TaskInfo> findAll() {
logger.info("Calling the findAll1()");
TaskInfo taskInfo = dashboardService.getTasks();
HttpHeaders headers = new HttpHeaders();
headers.add("Access-Control-Allow-Origin", "*");
ResponseEntity<TaskInfo> entity = new ResponseEntity<TaskInfo>(taskInfo,
headers, HttpStatus.OK);
logger.info("entity is := " + entity);
return entity;
}
L'objet TaskInfo doit avoir le getter et le setter appropriés. sinon, l'erreur 406 sera levée.
Fichier POM pour référence:
<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.raghu.DashBoardService</groupId>
<artifactId>DashBoardService</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>DashBoardService Maven Webapp</name>
<url>http://maven.Apache.org</url>
<properties>
<!-- Spring -->
<spring-framework.version>4.0.6.RELEASE</spring-framework.version>
<jackson.version>2.4.0</jackson.version>
<jaxb-api.version>2.2.11</jaxb-api.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-Java-driver</artifactId>
<version>2.10.1</version>
</dependency>
<!-- Spring Data Mongo Support -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-dao</artifactId>
<version>2.0.3</version>
</dependency>
<!-- Jackson mapper -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.7.1</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>DashBoardService</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
Eh bien, les réponses sur cette page sont peut-être exactes mais elles n’ont pas bien expatié. C'est ce que j'ai fait
J'ai ajouté ceci à mon pom.xml
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.8</version>
</dependency>
Puis j'ai ajouté des en-têtes à mon RequestMapping comme ci-dessous
@RequestMapping(value="/admin/getGallery", method = RequestMethod.GET, headers={"Content-Type=application/json"})
Puis, dans mon jquery ajax, j’ai ajouté - contentType: "application/json", de sorte que
jQuery.ajax({
type:'GET',
url:"getGallery.html",
data: "designId="+designId,
processData:false,
contentType: "application/json",
//dataType: "json",
success:function(data){
console.log(data);
},
error : function(e) {
console.log("ERROR: ", e);
},
});
Puis dans mon servlet j'ai ajouté
<bean id="jsonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<!-- Bind the return value of the Rest service to the ResponseBody. -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="jsonHttpMessageConverter" />
</util:list>
</property>
</bean>
Si vous rencontrez des problèmes avec la balise util dans votre servlet, ajoutez simplement le même fichier de servlet.
xmlns:util="http://www.springframework.org/schema/util"
et
xsi:schemaLocation="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
problème n’est pas lié à jquery. même bug dit qu'il s'agit d'un problème côté serveur. s'il vous plaît assurez-vous que les 2 suivants jar présents dans le chemin de classe: -
jackson-core-asl-1.9.X.jar jackson-mapper-asl-1.9.X.jar
Voir ma réponse à un problème similaire ici avec Spring MVC interprétant l’extension de l’URI et modifiant le type MIME attendu produit en arrière-plan, produisant ainsi un 406.
J'ai également été confronté au même problème et j'ai téléchargé ce fichier [jar]: ( http://www.Java2s.com/Code/Jar/j/Downloadjacksonall190jar.htm )! et placé dans le dossier lib et l'application fonctionne comme un charme :)
Au lieu de @RequestMapping(...headers="Accept=application/json"...)
, utilisez @RequestMapping(... , produces = "application/json")
Avec jQuery, vous pouvez définir contentType sur le type souhaité (application/json; charset = UTF-8 'ici) et définir le même en-tête côté serveur.
N'OUBLIEZ PAS D'EFFACER LE CACHE LORS DU TEST.
Comme le dit axtavt, mvc: mappeur JSON jackson et annotation est tout ce dont vous avez besoin. J'ai suivi cette procédure et demandé à mon application de renvoyer les chaînes JSON et XML à partir de la même méthode sans changer de code, à condition qu'il y ait @XmlRootElement et @XmlElement dans l'objet que vous retournez du contrôleur. La différence était dans le paramètre accept passé dans la demande ou dans l'en-tête. Pour renvoyer xml, tout appel normal à partir du navigateur le fera, sinon il passera l'acceptation en tant qu'application/xml. Si vous souhaitez que JSON soit renvoyé, utilisez "application/json" dans le paramètre accept de la requête.
Si vous utilisez firefox, vous pouvez utiliser tamperdata et modifier ce paramètre.