Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data in the body of a DELETE request

I have two Spring MVC controller methods. Both receive the same data in the request body (in the format of an HTLM POST form: version=3&name=product1&id=2), but one method handles PUT requests and another DELETE:

@RequestMapping(value = "ajax/products/{id}", method = RequestMethod.PUT) @ResponseBody public MyResponse updateProduct(Product product, @PathVariable("id") int productId) {  //... }  @RequestMapping(value = "ajax/products/{id}", method = RequestMethod.DELETE) @ResponseBody public MyResponse updateProduct(Product product, @PathVariable("id") int productId) {  //... } 

In the first method, all fields of the product argument are correctly initialised. In the second, only the id field is initialised. Other fields are null or 0. (id is, probably, initialised because of the id path variable).

I can see that the HttpServletRequest object contains values for all fields in the request body (version=3&name=product1&id=2). They just are not mapped to the fields of the product parameter.

How can I make the second method work?

I also tried to use the @RequestParam annotated parameters. In the method that handles PUT requests, it works. In the DELETE method, I get an exception: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'version' is not present.

I need to pass data in the body of DELETE requests because the data contain a row version which is used for optimistic locking.

like image 769
Alex Avatar asked Aug 19 '14 02:08

Alex


People also ask

Can I pass body in delete request?

delete() is the Axios options, not the request body. You can't pass the request body as the 2nd parameter like you can with axios.

Can you send data in the body of a GET request?

Requests using GET should only be used to request data (they shouldn't include data). Note: Sending body/payload in a GET request may cause some existing implementations to reject the request — while not prohibited by the specification, the semantics are undefined.

Should delete response have a body?

The short answer is: You should include a response body with an entity describing the deleted item/resource if you return 200. 202 is something like an asynchronous request/response return status.


2 Answers

The problem is not a Spring problem, but a Tomcat problem.

By default, Tomcat will only parse arguments that are in the form style, when the HTTP method is POST (at least for version 7.0.54 that I checked but it's probably the same for all Tomcat 7 versions).

In order to be able to handle DELETE methods as well you need to set the parseBodyMethods attribute of the Tomcat Connector. The connector configuration is done in server.xml.

Your updated connector would most likely look like:

<Connector port="8080" protocol="HTTP/1.1"             connectionTimeout="20000"            redirectPort="8443"            parseBodyMethods="POST,PUT,DELETE"            URIEncoding="UTF-8" /> 

Here is documentation page for configuring Tomcat connectors.

Once you setup Tomcat to parse the parameters, Spring will work just fine (although in your case you will probably need to remove @RequestBody from the controller method)

like image 94
geoand Avatar answered Oct 03 '22 08:10

geoand


You can try adding the annotation @RequestBody to your Product argument.

But if you just need to pass version information, using a request param is more appropriate.

So add a new argument in your delete method @RequestParam("version") int version, and when calling the delete method pass a query param like ..ajax/products/123?version=1

As you said request param is not working for you in delete, can you post the exact url you used and the method signature ?

like image 44
coder Avatar answered Oct 03 '22 08:10

coder