1

I am using REST client for testing. I use exact same query, just changing method from POST to DELETE. I have same method in Spring Boot 2.0.1 - just changing annotation from @PostMapping to @DeleteMapping.

@DeleteMapping(value = "/receiver") public ResponseEntity<Response> doOperation(@RequestParam(value = "name") String name) { return new ResponseEntity<>(HttpStatus.OK); } 

As soon as I change to DELETE I am getting error:

"Required String parameter 'name' is not present" 

I have tested it with @PutMapping - works as well.

I am doing something wrong??

UPDATE 1

DELETE request:

DELETE /api/v1/wud/receiver?action=something HTTP/1.1 Cookie: PHPSESSID=e6b750be296f28174196817f126b367a Content-Type: application/x-www-form-urlencoded; charset=utf-8 Host: somehost:9443 Connection: close User-Agent: Paw/3.1.7 (Macintosh; OS X/10.13.4) GCDHTTPRequest Content-Length: 10 name=ASDEF 

response is mentioned error

POST request:

POST /api/v1/wud/receiver?action=something HTTP/1.1 Cookie: PHPSESSID=e6b750be296f28174196817f126b367a Content-Type: application/x-www-form-urlencoded; charset=utf-8 Host: somehost:9443 Connection: close User-Agent: Paw/3.1.7 (Macintosh; OS X/10.13.4) GCDHTTPRequest Content-Length: 10 name=ASDEF 

Response is 200

UPDATE 2

I was able to reproduce it in really simple setup using original spring example gs-rest-service. I have forked it on github HERE It's interesting that MockMvc test passes, but it doesn't work in reality.

I will fill a bug with Spring boot

6
  • export the request as a curl and post it here if you could Commented May 24, 2018 at 14:59
  • not in curl, but I posted requests Commented May 24, 2018 at 15:15
  • I think the embedded tomcat is not reading the request body of the delete Request. it seems logical because a DELETE operation should happen only on back of an URI. Commented May 24, 2018 at 15:19
  • Try hacking the TomcatEmbeddedServletContainerFactory to create a connector with setParseBodyMethods("POST,PUT,DELETE"); Commented May 24, 2018 at 15:20
  • but that's just bad design. Anyways let me add this as an answer. Commented May 24, 2018 at 15:21

3 Answers 3

3

One should not send payload with DELETE requests. DELETE request is like rm command where you ask server to remove the resource.

Sending a payload is undefined and may differ from server to server

From RFC:

A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request. 

Source: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.5

Sign up to request clarification or add additional context in comments.

Comments

2

This is not a problem with Spring but the embedded tomcat itself as the body of DELETE requests are usually ignored.

Here is a way around it.

For spring-boot 2.0+,

@Configuration public class TomcatConfig implements TomcatConnectorCustomizer { @Override public void customize(Connector connector) { connector.setParseBodyMethods("POST,PUT,DELETE"); } } 

same can be done in spring-boot 1.5+ as shown below.

@Bean public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() { return new TomcatEmbeddedServletContainerFactory(){ @Override protected void customizeConnector(Connector connector) { super.customizeConnector(connector); connector.setParseBodyMethods("POST,PUT,DELETE"); } }; } 

But this is a bad practice. Because you ended up performing a POST but calling it a DELETE api.

Comments

1

From your question, it looks like you are using @RequestBody for your @PostMapping but on your @DeleteMapping you are using @RequestParam.

Also you are invoking your DELETE api with request body instead of a url parameter. From your request info, I see:

DELETE /api/v1/wud/receiver?action=something HTTP/1.1 

But you have to invoke your delete API like this:

DELETE /api/v1/wud/receiver?action=something&name=something Here ---------^^^^^ 

With curl you can use:

curl -X DELETE '{{url}}/api/v1/wud/receiver?action=something&name=something' 

On the other hand, if name param is not mandatory, then you can use:

@RequestParam(value = "name", required = false) String name 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.