【问题标题】:Spring 3 MVC - Advanced Data Binding - Form Request with List of Simple ObjectsSpring 3 MVC - 高级数据绑定 - 带有简单对象列表的表单请求
【发布时间】:2010-08-25 13:17:51
【问题描述】:

我已经阅读了所有 Spring 3 Web 文档:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/spring-web.html,但完全找不到任何有趣的文档来绑定更复杂的请求数据,例如,假设我使用 jQuery 发布到控制器,例如所以:

$.ajax({
    url: 'controllerMethod',
    type: "POST",
    data : {
        people : [
        {
            name:"dave", 
            age:"15"
        } ,
{
            name:"pete", 
            age:"12"
        } ,
{
            name:"steve", 
            age:"24"
        } ]
    },
    success: function(data) {
        alert('done');
    }
});

如何通过控制器接受它?最好不必创建自定义对象,我宁愿只能够使用简单的数据类型,但是如果我需要自定义对象来简化事情,我也可以。

让您开始:

@RequestMapping("/controllerMethod", method=RequestMethod.POST)
public String doSomething() {
    System.out.println( wantToSeeListOfPeople );
}

不要担心这个问题的响应,我只关心处理请求,我知道如何处理响应。

编辑:

我有更多示例代码,但我无法让它工作,我在这里缺少什么?

选择javascript:

var person = new Object();
    person.name = "john smith";
    person.age = 27;

    var jsonPerson = JSON.stringify(person);

    $.ajax({
        url: "test/serialize",
        type : "POST",
        processData: false,
        contentType : 'application/json',
        data: jsonPerson,
        success: function(data) {
            alert('success with data : ' + data);
        },
        error : function(data) {
            alert('an error occurred : ' + data);
        }
    });

控制器方法:

public static class Person {

        public Person() {
        }

        public Person(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
        String name;
        Integer age;

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    @RequestMapping(value = "/serialize")
        @ResponseBody
        public String doSerialize(@RequestBody Person body) {
            System.out.println("body : " + body);
            return body.toString();
        }

这会导致以下异常:

org.springframework.web.HttpMediaTypeNotSupportedException: 内容类型“应用程序/json”不是 支持

如果 doSerialize() 方法接受 String 而不是 Person,则请求成功,但 String 为空

【问题讨论】:

    标签: spring spring-mvc


    【解决方案1】:

    您的 jQuery ajax 调用会生成以下 application/x-www-form-urlencoded 请求正文(以 % 解码形式):

    people[0][name]=dave&people[0][age]=15&people[1][name]=pete&people[1][age]=12&people[2][name]=steve&people[2][age]=24
    

    Spring MVC 可以将使用数字索引的属性绑定到Lists,将使用字符串索引的属性绑定到Maps。这里需要自定义对象,因为@RequestParam 不支持复杂类型。所以,你有:

    public class People {
        private List<HashMap<String, String>> people;
    
        ... getters, setters ...
    }
    
    @RequestMapping("/controllerMethod", method=RequestMethod.POST)        
    public String doSomething(People people) {        
        ...
    } 
    

    您还可以在发送数据之前将数据序列化为 JSON,然后按照 Bozho 的建议使用 @RequestBody。您可以在mvc-showcase sample 中找到这种方法的示例。

    【讨论】:

    • 这行得通,看来如果Spring可以处理这个问题,它应该能够直接进入HashMap,跳过那个中间人,但是你的代码完全按照打印的方式工作
    • 我在顶部添加了一个尝试 JSON 解决方案的编辑,但它不起作用,有什么见解吗?
    • @walnutmon:要使其正常工作,您需要在类路径中包含 Jackson JSON Mapper 库 (jackson.codehaus.org)(以及 Spring 的 XML 中的 &lt;mvc:annotation-driven/&gt;)。
    • 我添加了 jackson-rs 和 asl-mapper 和核心,还添加了 ,我仍然看到完全相同的东西,我不知道为什么这完全没有记录(我看到的 spring 示例在我尝试运行时总是遇到同样的问题)
    【解决方案2】:

    如果您启用了&lt;mvc:annotation-driven&gt;,则:

    @RequestMapping("/controllerMethod", method=RequestMethod.POST)
    public String doSomething(@RequestBody List<Person> people) {
        System.out.println( wantToSeeListOfPeople );
    }
    

    (List&lt;Person&gt;可能不是你想要的结构,这里只是一个例子)

    您可以尝试将$.ajax 的Content-Type 设置为application/json,如果不能立即生效。

    【讨论】:

    • 我喜欢这个答案,不幸的是我得到一个异常“org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded' not supported”这是最接近我的'想要,但代码不能按原样工作
    • @Bozho:jQuery 无论如何都不会序列化为 JSON。需要手动序列化,例如JSON.stringify from json.org
    • @axtavt - 他将 JSON 作为他的请求的data 发送。或者我错过了什么..
    • @Bozho:如果他以data 发送对象,jQuery 使用以下序列化:api.jquery.com/jQuery.param。要使用 JSON,他需要手动将对象转换为 JSON 字符串表示并将字符串作为data 传递。
    • @Bozho:我添加了“application/json”作为测试,它仍然显示“不支持的媒体类型”,我需要在 Spring 中配置一个 JSON 解析器来执行此操作吗?我真的很想让事情以这种方式工作,无论我是作为 JSON 还是作为序列化表单发送
    【解决方案3】:

    看看 Jackson 的 spring 集成。它非常易于使用且功能强大。

    关于 SO 的问题/答案可以帮助指导这一点: Spring 3.0 making JSON response using jackson message converter

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 2019-01-16
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多