简体   繁体   English

JQuery,Spring MVC @RequestBody和JSON - 让它协同工作

[英]JQuery, Spring MVC @RequestBody and JSON - making it work together

I would like to have a bidirectional JSON to Java serialization 我想有一个双向JSON到Java序列化

I'm using successfully the Java to JSON to JQuery path... ( @ResponseBody ) eg 我正在成功使用Java到JSON到JQuery路径...( @ResponseBody )例如

@RequestMapping(value={"/fooBar/{id}"}, method=RequestMethod.GET)
     public @ResponseBody FooBar getFooBar(
            @PathVariable String id,
            HttpServletResponse response , ModelMap model) {
        response.setContentType("application/json");
...
}

and In JQuery I use 在我使用的JQuery中

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

this works well (eg annotations work already, thanks to all the answerers) 很有效 (例如注释工作已经完成,感谢所有的回答者)

However, how do I do the reverse path: have JSON be serialized to a Java Object back using RequestBody? 但是,如何执行反向路径:使用RequestBody将JSON序列化为Java对象?

no matter what I try, I can't get something like this to work: 无论我尝试什么,我都无法得到这样的东西:

@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...)
}

I have Jackson configured correctly (it serializes on the way out) and I have MVC set as annotations driven of course 我已经正确配置了Jackson(它在出路时序列化)并且当然我将MVC设置为注释驱动

How do I make it work? 我如何使其工作? is it possible at all? 它有可能吗? or is Spring / JSON / JQuery is oneway (out)? 或者Spring / JSON / JQuery是单向的(out)?


Update: 更新:

I changed this Jackson setting 我改变了杰克逊的设定

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

To the (almost similiar one) suggested 建议(几乎相似)

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

And it seems to work! 它似乎工作! I don't know what exactly did the trick, but it works... 我不知道究竟是什么伎俩,但它有效......

I'm pretty sure you only have to register MappingJacksonHttpMessageConverter 我很确定你只需要注册MappingJacksonHttpMessageConverter

(the easiest way to do that is through <mvc:annotation-driven /> in XML or @EnableWebMvc in Java ) (最简单的方法是通过XML中的<mvc:annotation-driven />或Java中的@EnableWebMvc

See: 看到:


Here's a working example: 这是一个有效的例子:

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

in folder src/main/webapp/WEB-INF 在文件夹src / main / webapp / WEB-INF中

web.xml 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 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>

in folder src/main/resources: 在文件夹src / main / resources中:

mvc-context.xml 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>

In folder src/main/java/test/json 在文件夹src / main / java / test / json中

TestController.java 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 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 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; }
}

You can test this setup by executing mvn jetty:run on the command line, and then sending a POST request: 您可以通过执行mvn jetty:run来测试此设置mvn jetty:run在命令行上mvn jetty:run ,然后发送POST请求:

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

I used the Poster Firefox plugin to do this. 我使用Poster Firefox插件来执行此操作。

Here's what the response looks like: 这是响应的样子:

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

In Addition you also need to be sure that you have 此外,您还需要确保自己拥有

 <context:annotation-config/> 

in your SPring configuration xml. 在您的SPring配置xml中。

I also would recommend you to read this blog post. 我也建议你阅读这篇博文。 It helped me alot. 这对我帮助很大。 Spring blog - Ajax Simplifications in Spring 3.0 Spring博客 - Spring 3.0中的Ajax简化

Update: 更新:

just checked my working code where I have @RequestBody working correctly. 刚检查了我的工作代码,我的@RequestBody工作正常。 I also have this bean in my config: 我的配置中也有这个bean:

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

May be it would be nice to see what Log4j is saying. 可能会很高兴看到Log4j在说什么。 it usually gives more information and from my experience the @RequestBody will fail if your request's content type is not Application/JSON . 它通常会提供更多信息,根据我的经验,如果您的请求的内容类型不是Application/JSON@RequestBody将失败。 You can run Fiddler 2 to test it, or even Mozilla Live HTTP headers plugin can help. 您可以运行Fiddler 2来测试它,甚至Mozilla Live HTTP头插件也可以提供帮助。

In addition to the answers here... 除了这里的答案......

if you are using jquery on the client side, this worked for me: 如果你在客户端使用jquery,这对我有用:

Java: Java的:

@RequestMapping(value = "/ajax/search/sync") 
public String sync(@RequestBody Foo json) {

Jquery (you need to include Douglas Crockford's json2.js to have the JSON.stringify function): Jquery(你需要包含Douglas Crockford的json2.js来获得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');
    }
});

If you do not want to configure the message converters yourself, you can use either @EnableWebMvc or <mvc:annotation-driven /> , add Jackson to the classpath and Spring will give you both JSON, XML (and a few other converters) by default. 如果您不想自己配置消息转换器,可以使用@EnableWebMvc或<mvc:annotation-driven /> ,将Jackson添加到类路径中,Spring将为您提供JSON,XML(以及其他一些转换器)默认。 Additionally, you will get some other commonly used features for conversion, formatting and validation. 此外,您还将获得一些其他常用的转换,格式化和验证功能。

In case you are willing to use Curl for the calls with JSON 2 and Spring 3.2.0 in hand checkout the FAQ here . 如果您愿意使用Curl进行JSON 2和Spring 3.2.0的调用,请在此处查看常见问题解答。 As AnnotationMethodHandlerAdapter is deprecated and replaced by RequestMappingHandlerAdapter. 由于AnnotationMethodHandlerAdapter已弃用并由RequestMappingHandlerAdapter替换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM