多个ajax数据发送到Spring MVC控制器

3

我需要通过Ajax将数据发送到Spring MVC控制器。但是,如果我发送超过一个参数,控制器就无法正常工作。

控制器方法:

@Timed
@RequestMapping(value = "saveee", method = RequestMethod.POST)
@ResponseBody
public JsonResultBean saveTicketTemplate(@RequestBody TicketTemplateFieldBean fieldBean, Long id) throws IOException {
    //TODO smth
    return JsonResultBean.success();
}

使用这个Ajax代码,一切都可以完美地运行:

$.ajax({
            type: 'POST',
            dataType: 'json',
            contentType: 'application/json',
            url: '/organizer/api/saveee',
            data: JSON.stringify(fieldBean.data),
            success: function(result) {
                //TODO
            }
        })

但如果我更改数据参数,控制器也不会收到请求。

data: ({'fieldBean': JSON.stringify(fieldBean.data), 'id': id})

我做错了什么?

在控制器方法的第二个参数前添加 @RequestParam("id")。 - Shaheer
不好意思,它没有起到帮助的作用。 - Kadzhaev Marat
3个回答

6

这样行不通。首先让我们澄清一下@RequestBody和@RequestParam之间的区别。

@RequestBody方法参数注释应该通过使用HttpMessageConverter将HTTP请求体中的JSON值绑定到Java对象。 HttpMessageConverter负责将HTTP请求消息转换为相关联的Java对象。 来源

并使用@RequestParam注释将请求参数绑定到控制器中的方法参数。 来源

回答你的问题...... 使用第一个ajax请求时,您正在向控制器发送JSON而不是请求参数,因此@RequestBody是可以的。

在第二个ajax请求中,您也发送了JSON,但有两个字段(fieldBean和id)。由于@RequestBody注释的参数预计将保存请求的整个主体并绑定到一个对象上。您应该修改Java对象(即TicketTemplateFieldBean)以保存id字段。如果控制器中只有一个参数,则这将起作用。
那么,如何有第二个参数?
您不能使用两个@RequestBody,例如:
public JsonResultBean saveTicketTemplate(@RequestBody TicketTemplateFieldBean fieldBean, @RequestBody Long id).

由于它只能绑定到一个对象(body 只能被消耗一次),您不能将多个独立的 JSON 对象传递给 Spring 控制器。相反,您必须将其包装在单个对象中。
因此,您的解决方案是将其作为请求参数 - @RequestParam 或路径变量 - @PathVariable 进行传递。由于 @RequestParam 和 @ModelAttribute 仅在数据作为请求参数提交时才起作用,因此您应该像这样更改代码:
@Timed
@RequestMapping(value = "saveee", method = RequestMethod.POST)
@ResponseBody
public JsonResultBean saveTicketTemplate(@RequestBody TicketTemplateFieldBean fieldBean, @RequestParam("id") Long id) throws IOException {
    //TODO smth
    return JsonResultBean.success();
}

并将您的请求URL更改如下:

$.ajax({
            type: 'POST',
            dataType: 'json',
            contentType: 'application/json',
            url: '/organizer/api/saveee?id=10',
            data: JSON.stringify(fieldBean.data),
            success: function(result) {
                //TODO
            }
        })

您可以像这样使用@PathVariable:
@Timed
@RequestMapping(value = "saveee/{id}", method = RequestMethod.POST)
@ResponseBody
public JsonResultBean saveTicketTemplate(@RequestBody TicketTemplateFieldBean fieldBean, @PathVariable("id") Long id) throws IOException {
    //TODO smth
    return JsonResultBean.success();
}

并将您的请求URL更改如下:

$.ajax({
            type: 'POST',
            dataType: 'json',
            contentType: 'application/json',
            url: '/organizer/api/saveee/10',
            data: JSON.stringify(fieldBean.data),
            success: function(result) {
                //TODO
            }
        })

我遇到了同样的问题。 @Shaheer,你的解决方案很好,但我想像这样传递数据:data: ({'fieldBean': JSON.stringify(fieldBean.data), 'id': id}),我不想在URL中传递数据。 那么你有什么想法吗? - Parth Patel

0

要将参数转换为方法参数,您必须使用@RequestParam,因此代码应该像这样修改:

控制器:

@Timed
@RequestMapping(value = "saveee", method = RequestMethod.POST)
@ResponseBody
public JsonResultBean saveTicketTemplate(@RequestParam TicketTemplateFieldBean fieldBean, @RequestParam Long id) throws IOException {
    //TODO smth
    return JsonResultBean.success();
}

0
您没有将有效数据传递给控制器。请尝试类似以下的内容。
$.ajax({
    type: 'POST',
    dataType: 'json',
    contentType: 'application/json',
    url: '/organizer/api/saveee',
    data: JSON.stringify({
            fieldBean: JSON.stringify(fieldBean.data),
            id: id
    }),
    success: function(result) {
        //TODO
    }
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接