Vickie Jack
Vickie Jack

Reputation: 95

Spring MVC 4 send error 400 in response to AJAX POST

i want to send id to server and delete record in DB with id. my ajax is :

var data = {
                id: 500
            };

                $.ajax({
                    url: 'delete',
                    method: 'POST',
                    contentType: 'application/json',
                    cache: false,
                    processData: false,
                    data: JSON.stringify(data),
                    success: function (res) {
                        showAlert(res.type, res.message);
                        if (res.type == 'success') {
                            row.delete();
                        }
                    }
                })

and my controller is :

@ResponseBody
@PostMapping("/delete")
public Alert delete(@RequestParam("id") int id) {
    Alert alert = new Alert(Alert.TYPE_WARNING, Message.get("canNotDelete"));
    if (Service.delete(id)) {
        alert.type = Alert.TYPE_SUCCESS;
        alert.message = Message.get("successDelete");
    }
    return alert;
}

but server send error 400.

Upvotes: 0

Views: 327

Answers (1)

reith
reith

Reputation: 2088

You are mixing query string (which is supposed to be parsed by @RequestParam) with post data (which is mostly supposed to be parsed by @RequestBody). So your client sends something like:

POST /delete
Content-Type: application/json

{
    "id": 500,
}

While server expects requests like:

POST /delete?id=500

They are different and while RequestParam will parse post data of forms in shape of:

POST /delete
Content-Type: application/x-www-urlencoded

id=500

It won't do stuff for JSON data. So There are at-least three solutions:

  1. Get rid of JSON body and pass id as query string or path param. You can then get id by @RequestParam or @PathParam respectively. Can be done with no server code change.
  2. Send request data as url form encoded. No need for server code change. In client do not jsonify data and drop content-type setting.
  3. Define a DTO to get whole request body as an Java object. You would change controller code like:

    @Controller
    class DeleteController {
    
        @ResponseBody
        @PostMapping("/delete")
        public Alert delete(@RequestBody Request request) {
            Alert alert = new Alert(Alert.TYPE_WARNING, Message.get("canNotDelete"));
            if (Service.delete(request.getId())) {
                alert.type = Alert.TYPE_SUCCESS;
                alert.message = Message.get("successDelete");
            }
            return alert;
        }
    
        public static class Request {
            private int id;
            public Request() {}
    
            public int getId() { return id; }
            public void setId(int id) { this.id = id; }
        }
    }
    

Upvotes: 1

Related Questions