javascript 使用 Ajax 发送表单 - Spring MVC

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30133586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 11:46:16  来源:igfitidea点击:

Sending form using Ajax - Spring MVC

javascriptjqueryajaxspringspring-mvc

提问by mateusz

I have problems with sending my form using Ajax.

我在使用 Ajax 发送表单时遇到问题。

Here is form:

这是表格:

<form method="POST" id="add-card-form" action="${pageContext.request.contextPath}/card/add" class="form-horizontal">
 <select name="type" class="form-control">
    <c:forEach items="${cardTypes}" var="cardType">
       <option value="${cardType.id}">${cardType.name}</option>
    </c:forEach>
 </select>
 <select name="category" class="form-control">
    <c:forEach items="${cardCategories}" var="cardCategory">
       <option value="${cardCategory.id}">${cardCategory.name}</option>
    </c:forEach>
 </select>
<textarea type="text" name="description" class="form-control" rows="6"></textarea>
 <input type="submit" id="add-card-submit" value="Add card" class="btn btn-primary"/>

Here is Ajax function:

这是 Ajax 函数:

$(document).on('submit', '#add-card-form', function(e) {
    var frm = $('#add-card-form');
    e.preventDefault();

    var Form = this;
    var data = {};

    $.each(this, function(i, v){
        var input = $(v);
        data[input.attr("name")] = input.val();
        delete data["undefined"];
    });

    //temporary solution
    data["type"] = parseInt(data["type"]);
    data["category"] = parseInt(data["category"]);

    console.log(data);
    if(frm.valid()) {
        $.ajax({
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: JSON.stringify(data),
            success:  reloadBoard,
            error: function (callback) {
                console.log(callback);
            }
        });

        refreshForm(frm);
    }
});

And here is a controller action:

这是一个控制器动作:

@RequestMapping(value="/add", method = RequestMethod.POST)
public @ResponseBody Card addCard(@RequestBody Integer type,
                                  @RequestBody Integer category,
                                  @RequestBody String description) {

    Card card = new Card();

    card.setType(cardTypeService.findById(type));
    card.setCategory(cardCategoryService.findById(category));
    card.setDescription(description);
    card.setOwner(1);

    cardService.saveCard(card);

    System.out.println("Card with id " + card.getId() + " added!");

    return card;
}

Variable data values:

变量数据值:

Object {type: 1, category: 1, description: "New Card"}

When I try to send this form I always get error 400: http://localhost:8080/card/add 400 (Bad Request)

当我尝试发送此表单时,我总是收到错误 400: http://localhost:8080/card/add 400 (Bad Request)

Can you tell me what is wrong with this code? I've ridden few posts, articles about sending data using Spring MVC + Ajax but no one helped.

你能告诉我这段代码有什么问题吗?我写了几篇关于使用 Spring MVC + Ajax 发送数据的文章,但没有人提供帮助。

EDIT:

编辑:

I changed @RequestBody into three @RequestParams:

我把@RequestBody 改成了三个@RequestParams:

 @RequestMapping(value="/add", method = RequestMethod.POST)
public @ResponseBody Card addCard(@RequestParam("type") Integer type,
                                  @RequestParam("description") String description,
                                  @RequestParam("category") Integer category) {

I still get 400 error. Here is raw HTTP request:

我仍然收到 400 错误。这是原始 HTTP 请求:

POST /card/add HTTP/1.1 Host: localhost:8080 Connection: keep-alive Content-Length: 48 Cache-Control: no-cache Pragma: no-cache Origin: http://localhost:8080 X-Requested-With: XMLHttpRequest Content-Type: application/json; charset=UTF-8 Accept: application/json, text/javascript, */*; q=0.01 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 Referer: http://localhost:8080/ Accept-Encoding: gzip,deflate,sdch Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=ABAD895C419A9175EAB4D0833C543724

POST /card/add HTTP/1.1 Host: localhost:8080 Connection: keep-alive Content-Length: 48 Cache-Control: no-cache Pragma: no-cache Origin: http://localhost:8080 X-Requested-With: XMLHttpRequest Content-Type: application/json; charset=UTF-8 Accept: application/json, text/javascript, */*; q=0.01 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 Referer: http://localhost:8080/ Accept-Encoding: gzip,deflate,sdch Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: JSESSIONID=ABAD895C419A9175EAB4D0833C543724

And data object:

和数据对象:

category: 1
description: "New Card"
type: 1

回答by Master Slave

Dmitry Zolotukhin is right when saying that the only reasonable thing is to have only one @RequestBodyas you can consume the request only once, after that it becomes commited and all subsequent read attempts will fail.

Dmitry Zolotukhin 说得对,唯一合理的事情是只有一个,@RequestBody因为您只能使用一次请求,之后它被提交并且所有后续的读取尝试都将失败。

What you should do is have your Cardclass as method argument annotated with @RequestBody, so

你应该做的是让你的Card类作为方法参数用 注释@RequestBody,所以

@RequestMapping(value="/add", method = RequestMethod.POST)
public @ResponseBody Card addCard(@RequestBody Card card) {
    card.setOwner(1);
    cardService.saveCard(card);
    System.out.println("Card with id " + card.getId() + " added!");
    return card;
}

The spring mvc framework will take care of the instantiation of the Cardobject and binding the request values to properties, by matching the keys from JSONbody with properties. Note also that for this to work, the data you're sending must be a valid json, so make sure that to comply to that.

spring mvc 框架将负责Card对象的实例化并将请求值绑定到属性,方法是将JSON主体中的键与属性进行匹配。另请注意,要使其正常工作,您发送的数据必须是有效的 json,因此请确保遵守该要求。

You can consider creating a simply data transfer object, e.g. CardDTOsomething like

您可以考虑创建一个简单的数据传输对象,例如CardDTO

public class CardDTO {
    private Integer category;
    private Integer type;
    private String descrption;

    public Integer getCategory() {
        return category;
    }

    public void setCategory(Integer category) {
        this.category = category;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public String getDescrption() {
        return descrption;
    }

    public void setDescrption(String descrption) {
        this.descrption = descrption;
    }
}

and than bind to it

然后绑定到它

@RequestMapping(value="/add", method = RequestMethod.POST)
public @ResponseBody Card addCard(@RequestBody CardDTO cardDTO) {

回答by Dmitry Zolotukhin

@RequestBodymeans that the contents of the HTTP request body will be mapped to the attribute. Since you can only have one request body, this will almost certainly fail.

@RequestBody意味着 HTTP 请求正文的内容将映射到该属性。由于您只能有一个请求正文,因此这几乎肯定会失败。

You most likely need to specify the request param instead: @RequestParam("type") String type

您很可能需要指定请求参数: @RequestParam("type") String type

If this doesn't help, could you provide the raw HTTP request data and the Spring MVC error stack trace from the web server's log/console?

如果这没有帮助,您能否提供原始 HTTP 请求数据和来自 Web 服务器日志/控制台的 Spring MVC 错误堆栈跟踪?