70 votes

JQuery, Spring MVC @RequestBody et JSON - pour que cela fonctionne ensemble

Je voudrais avoir une bidirectionnel JSON pour la sérialisation Java

Je suis en utilisant avec succès le Java en JSON pour JQuery chemin... (@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-je utiliser

$.getJSON('fooBar/1', function(data) {
    //do something
});

cela fonctionne bien (par exemple, les annotations de travail déjà, merci à tous les answerers)

Cependant, comment dois-je faire l' inverse chemin d'accès: avoir JSON être sérialisé à un Objet Java en arrière en utilisant RequestBody?

peu importe ce que j'essaie, je ne peux pas obtenir quelque chose comme ceci fonctionne:

@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 Jackson configuré correctement (il sérialise sur le moyen de sortir) et j'ai MVC définir comme des annotations poussé bien sûr

Comment puis-je le faire fonctionner? est-il possible? ou est le Printemps / JSON / JQuery est unidirectionnelle (out)?


Mise à jour:

J'ai changé ce réglage 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>

À la (presque similaire, on) a 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 il semble fonctionner! Je ne sais pas ce que fait exactement le truc, mais ça marche...

100voto

Sean Patrick Floyd Points 109428

Je suis sûr que vous n'avez qu'à vous inscrire MappingJacksonHttpMessageConverter

(la meilleure façon de le faire est par le biais <mvc:annotation-driven /> en XML ou @EnableWebMvc en Java)

Voir:


Voici un exemple:

POM Maven

<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 l'envoi d'une requête POST:

URL:        http://localhost:8080/test/math
mime type:  application/json
post body:  { "left": 13 , "right" : 7 }

J'ai utilisé l' Affiche plugin Firefox pour faire cela.

Voici ce que la réponse ressemble à:

{"addition":20,"subtraction":6,"multiplication":91}

12voto

danny.lesnik Points 9526

En Outre, vous devez également vous assurer que vous avez

 <context:annotation-config/> 

au Printemps de configuration xml.

Je voudrais également vous conseillons de lire cet article de blog. Il m'a beaucoup aidé. http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/

Mise à jour:

viens de vérifier mon code de travail où j'ai @RequestBody travail correctement. J'ai aussi ce bean 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 qu'il serait agréable de voir ce que Log4j est en train de dire. on donne en général plus d'informations et de mon expérience, l' @RequestBody échouera si votre demande de type de contenu n'est pas d'Application/JSON. Vous pouvez exécuter Fiddler 2 pour le tester, ou encore Mozilla Live HTTP headers plugin peut vous aider.

9voto

rafael lean ansay Points 101

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');
    }
});
 

5voto

matsev Points 6761

Si vous ne souhaitez pas configurer vous-même les convertisseurs de messages, vous pouvez utiliser soit @EnableWebMvc, soit <mvc: annotation-driven /> , ajoutez Jackson au chemin de classe et Spring vous donnera les formats JSON, XML (et quelques autres convertisseurs) en: défaut. En outre, vous obtiendrez d'autres fonctionnalités couramment utilisées pour la conversion, le formatage et la validation.

0voto

AmirHd Points 1004

Si vous souhaitez utiliser Curl pour les appels avec JSON 2 et Spring 3.2.0, consultez la FAQ ici . Comme AnnotationMethodHandlerAdapter est obsolète et remplacé par RequestMappingHandlerAdapter.

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