6

I'm really getting started with controllers for my small application, and i have this for now:

@RequestMapping("/users/{id}")
public ModelAndView showMemeber(@PathVariable Integer id) {

    ModelAndView mav = new ModelAndView("user/show");

    mav.addObject("title", "Show User");
    mav.addObject("user", userService.findById(id));
    return mav;

}

@RequestMapping(value="/users/{id}", method=RequestMethod.DELETE)
public String deleteMemeber(@PathVariable Integer id) {

    userService.delete(id);

    return "redirect:users";

}

the first one, is working properly, but the second doesn't, i have the following view for the first controller:

<div class="panel-heading">Personal information</div>
<div class="panel-body">

  <form method="post">

    ...

    <button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-pencil"></span> Edit</button>
    <button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure you want to delete {{ user.username }}?')"><span class="glyphicon glyphicon-remove"></span> Delete</button>
  </form> 
</div>

like you see, i have two buttons here, one for edit the object and one for delete it. Once deleted it, must redirect to https://<my domain>/users.

The problem is, when i click on Delete it just refresh the page and the object persist on the database, what is wrong here?

  • I try send a DELETE request like curl -X "DELETE" http://localhost:8080/my-app/users/18 but this didn't work.
  • How does your request look like when you click delete button? Do you really send DELETE request for a proper URL? – slnowak Dec 28 '14 at 09:39
  • Nothing happens, any change. –  Dec 28 '14 at 09:48
  • 1
    That's not what I'm asking about. Run firebug or any other tool and look what request you are sending and on which URL after clicking the button. I'm pretty sure you're not sending DELETE request for proper resource. – slnowak Dec 28 '14 at 09:52
  • Request URL: http://localhost:8080/my-app/users/18 Request method: POST Status code: 200 –  Dec 28 '14 at 09:57
  • And now try to send a DELETE request for that resource, for example using curl and see if it works. – slnowak Dec 28 '14 at 10:07
  • No man, that didn't work. –  Dec 28 '14 at 10:13
  • And by 'didn't work' you mean what? – slnowak Dec 28 '14 at 10:23
  • 1
    First of all - you are sending POST, not DELETE, when using your HTML form. Give it up and perform the test using curl. Invoke curl (like in your example, just add -v flag to force verbose mode) and tell us what curl returned. – Michal Wilkowski Dec 28 '14 at 10:29
  • `karim@Karim:~/Workspace/my-app$ curl -X "DELETE" http://localhost:8080/my-app/users/18 karim@Karim:~/Workspace/my-app$ ` I mean, the user with id 18 still persists in database. –  Dec 28 '14 at 10:30
  • As Michal asked you, show us curl's verbose result. – slnowak Dec 28 '14 at 10:33
  • This has been returned `curl: (6) Couldn't resolve host 'DELETE'` –  Dec 28 '14 at 10:36
  • You clearly have a syntax error trying to invoke curl. – slnowak Dec 28 '14 at 10:38

3 Answers3

8

There are a bunch of methods available when communicating over HTTP. The most common ones are GET, PUT, POST and DELETE.

In your controller you declare that you expect a DELETE-request:

@RequestMapping(value="/users/{id}", method=RequestMethod.DELETE)
public String deleteMemeber(@PathVariable Integer id) {...}

This is not supported by the browser by default - a browser only supports POST and GET. In order to send a DELETE-request from the browser you must use JavaScript.

One alternative is to use e.g. jQuery's ajax-method

$.ajax({
    url: '/users/' + someUserId,
    type: 'DELETE',
    success: function(result) {
        // Do something with the result
    }
});

One way of testing DELETE-requests is to use the command cUrl:

curl -X DELETE "http://myhost:port/users/someUserId"
wassgren
  • 18,651
  • 6
  • 63
  • 77
  • Alternatively, change the `method=RequestMethod.DELETE` to `method=RequestMethod.POST` and it will work. – João Melo Dec 28 '14 at 11:37
  • @JoãoMelo - that is true but the OP had multiple buttons and POST was *already used* by the *edit* button. – wassgren Dec 28 '14 at 11:41
  • @wassgren when i test that request, returns to me `Couldn't resolve host 'DELETE'` –  Dec 28 '14 at 12:16
  • @Vercryger - could you please provide your curl-command here? – wassgren Dec 28 '14 at 12:17
  • Strange behaviour - your error message indicates that the command attempts to resolve 'DELETE' as the host. Are you sure that you don't add anything else to the curl-command? – wassgren Dec 28 '14 at 12:34
  • Yes i though that too, and i didn't add anything else. –  Dec 28 '14 at 12:56
  • @wassgren any idea?, because this still not working. –  Feb 06 '15 at 21:57
  • 2
    Note that `curl` command line options are case-sensitive and that `-X` and `-x` do completely different things. As `-x` is used to specify a HTTP proxy I suspect that you have used that rather than `-X`, leading to the `Couldn't resolve host...` message. – Steve C Feb 09 '15 at 00:20
1

As others have mentioned, you are not actually sending a HTTP DELETE request. Your delete button is part of a form post so when you submit the form it actually sends a HTTP POST request. Others have demonstrated some ways to invoke a DELETE (Ajax, and CURL) but I find the easiest way is to install a plugin on your favourite browser. If you're using Chrome you could try something like the Advanced Rest Client extension etc.

Richard
  • 1,070
  • 9
  • 22
0

as others have stated your html form will send POST as it is your action.

if you want to keep the button and do a delete without javascript (AJAX call) then you should try changing the url pattern in java side and also put the delete button html in a seperate form

@RequestMapping(value="/users/delete/{id}", method=RequestMethod.POST)

learningJava
  • 188
  • 6