J'aimerais avoir un JSON bidirectionnel pour Java sérialisation
J'utilise avec succès le Java pour JSON au chemin JQuery ... (@ResponseBody
) par exemple.
@RequestMapping(value={"/fooBar/{id}"}, method=RequestMethod.GET)
public @ResponseBody FooBar getFooBar(
@PathVariable String id,
HttpServletResponse response , ModelMap model) {
response.setContentType("application/json");
...
}
et dans JQuery j'utilise
$.getJSON('fooBar/1', function(data) {
//do something
});
cela fonctionne bien (par exemple, les annotations fonctionnent déjà, merci à tous les répondants)
Cependant, comment puis-je utiliser le chemin inverse: JSON doit-il être sérialisé avec un objet Java en utilisant RequestBody?)?
peu importe ce que j'essaie, je ne peux pas faire fonctionner quelque chose comme ça:
@RequestMapping(value={"/fooBar/save"}, method=RequestMethod.POST)
public String saveFooBar(@RequestBody FooBar fooBar,
HttpServletResponse response , ModelMap model) {
//This method is never called. (it does when I remove the RequestBody...)
}
J'ai configuré Jackson correctement (il se sérialise à la sortie) et MVC est défini comme annotations bien sûr
Comment puis-je le faire fonctionner? est-ce possible? ou Spring/JSON/JQuery est-il en marche?
Mise à jour:
J'ai changé ce réglage de Jackson
<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" />
<!-- <ref bean="xmlMessageConverter" /> -->
</util:list>
</property>
</bean>
Au (presque semblable) suggéré
<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>
Et ça a l'air de marcher! Je ne sais pas ce qui s'est exactement passé, mais ça marche ...
Je suis à peu près sûr que vous n'avez qu'à vous enregistrer MappingJacksonHttpMessageConverter
(Le moyen le plus simple de le faire est par <mvc:annotation-driven />
en XML ou @EnableWebMvc
en Java )
Voir:
Voici un exemple de travail:
Maven POM
<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>test</groupId><artifactId>json</artifactId><packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version><name>json test</name>
<dependencies>
<dependency><!-- spring mvc -->
<groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>3.0.5.RELEASE</version>
</dependency>
<dependency><!-- jackson -->
<groupId>org.codehaus.jackson</groupId><artifactId>jackson-mapper-asl</artifactId><version>1.4.2</version>
</dependency>
</dependencies>
<build><plugins>
<!-- javac --><plugin><groupId>org.Apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version><configuration><source>1.6</source><target>1.6</target></configuration></plugin>
<!-- jetty --><plugin><groupId>org.mortbay.jetty</groupId><artifactId>jetty-maven-plugin</artifactId>
<version>7.4.0.v20110414</version></plugin>
</plugins></build>
</project>
dans le dossier src/main/webapp/WEB-INF
web.xml
<web-app xmlns="http://Java.Sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://Java.Sun.com/xml/ns/j2ee http://Java.Sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet><servlet-name>json</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>json</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
json-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<import resource="classpath:mvc-context.xml" />
</beans>
dans le dossier src/main/resources:
mvc-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
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">
<mvc:annotation-driven />
<context:component-scan base-package="test.json" />
</beans>
Dans le dossier src/main/Java/test/json
TestController.Java
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(method = RequestMethod.POST, value = "math")
@ResponseBody
public Result math(@RequestBody final Request request) {
final Result result = new Result();
result.setAddition(request.getLeft() + request.getRight());
result.setSubtraction(request.getLeft() - request.getRight());
result.setMultiplication(request.getLeft() * request.getRight());
return result;
}
}
Request.Java
public class Request implements Serializable {
private static final long serialVersionUID = 1513207428686438208L;
private int left;
private int right;
public int getLeft() {return left;}
public void setLeft(int left) {this.left = left;}
public int getRight() {return right;}
public void setRight(int right) {this.right = right;}
}
Result.Java
public class Result implements Serializable {
private static final long serialVersionUID = -5054749880960511861L;
private int addition;
private int subtraction;
private int multiplication;
public int getAddition() { return addition; }
public void setAddition(int addition) { this.addition = addition; }
public int getSubtraction() { return subtraction; }
public void setSubtraction(int subtraction) { this.subtraction = subtraction; }
public int getMultiplication() { return multiplication; }
public void setMultiplication(int multiplication) { this.multiplication = multiplication; }
}
Vous pouvez tester cette configuration en exécutant mvn jetty:run
sur la ligne de commande, puis en envoyant une requête POST:
URL: http://localhost:8080/test/math
mime type: application/json
post body: { "left": 13 , "right" : 7 }
J'ai utilisé le plugin Poster Firefox pour le faire.
Voici à quoi ressemble la réponse:
{"addition":20,"subtraction":6,"multiplication":91}
De plus, vous devez également vous assurer que vous avez
<context:annotation-config/>
dans votre configuration SPring xml.
Je vous recommande également de lire ce blog. Cela m'a beaucoup aidé. Blog de printemps - Ajax Simplifications in Spring 3.
Mise à jour:
viens de vérifier mon code de travail où j'ai @RequestBody
fonctionne correctement. J'ai aussi ce haricot dans ma config:
<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>
Peut-être serait-il agréable de voir ce que Log4j
Est en train de dire. cela donne généralement plus d'informations et d'après mon expérience, le @RequestBody
échouera si le type de contenu de votre demande n’est pas Application/JSON
. Vous pouvez exécuter Fiddler 2 pour le tester, ou même le plug-in d'en-têtes HTTP de Mozilla Live HTTP peut vous aider.
En plus des réponses ici ...
si vous utilisez jquery côté client, cela a fonctionné pour moi:
Java:
@RequestMapping(value = "/ajax/search/sync")
public String sync(@RequestBody Foo json) {
Jquery (vous devez inclure le fichier json2.js de Douglas Crockford pour pouvoir utiliser la fonction JSON.stringify):
$.ajax({
type: "post",
url: "sync", //your valid url
contentType: "application/json", //this is required for spring 3 - ajax to work (at least for me)
data: JSON.stringify(jsonobject), //json object or array of json objects
success: function(result) {
//do nothing
},
error: function(){
alert('failure');
}
});
Si vous ne voulez pas configurer vous-même les convertisseurs de messages, vous pouvez utiliser soit @ EnableWebMvc ou <mvc: annotation-driven /> , ajoutez Jackson au chemin de classe et Spring vous donnera les deux formats JSON, XML ( et quelques autres convertisseurs) par défaut. En outre, vous obtiendrez d'autres fonctionnalités couramment utilisées pour la conversion, le formatage et la validation.
Si vous souhaitez utiliser Curl pour les appels avec JSON 2 et Spring 3.2.0 en main, consultez la FAQ ici . Comme AnnotationMethodHandlerAdapter est obsolète et remplacé par RequestMappingHandlerAdapter .