admin管理员组

文章数量:1316974

I have problems with sending my form using 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:

$(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)

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.

EDIT:

I changed @RequestBody into three @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:

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

I have problems with sending my form using 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:

$(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)

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.

EDIT:

I changed @RequestBody into three @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:

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
Share Improve this question edited May 10, 2015 at 7:05 mateusz asked May 8, 2015 at 22:10 mateuszmateusz 1651 gold badge2 silver badges14 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

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

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

@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 Card object and binding the request values to properties, by matching the keys from JSON body with properties. Note also that for this to work, the data you're sending must be a valid json, so make sure that to ply to that.

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

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

@RequestBody means 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.

You most likely need to specify the request param instead: @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?

本文标签: javascriptSending form using AjaxSpring MVCStack Overflow