2

I'm trying to understand the behaviour of an HTTP DELETE request.

On my java web application, I defined the following

@DeleteMapping("url/route")
public ResponseEntity<String> route(@RequestParam int param1, @RequestParam long param2, @RequestParam long param3, @RequestParam String param4) {
    System.out.println(param1 + "-" + param2 + "-" + param3 + "-" + param4 );
    return new ResponseEntity<String>(HttpStatus.OK);
}
    
@DeleteMapping("url/route2")
public ResponseEntity<String> route2(@RequestBody String body) {        
    System.out.println(body);
    return new ResponseEntity<String>(HttpStatus.OK);
}

And on a java client, I do the following

public final void myFunction(final int param1, final long param2, final long param3, final String param4) {
    restTemplate.delete("http://localhost:8090/url/route?"
            + "param1=" + param1 + "&"
            + "param2="+ param2 + "&"
            + "param3=" + param3 + "&"
            + "param4=" + param4, String.class);
    
    restTemplate.delete("http://localhost:8090/url/route2", "SomeText", String.class);
}

The first request works fine, the log is well displayed. However, on the second case, i get the following error

HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<java.lang.String> com.thales.atm.thmi.microservice.CanvasController.deleteGraphicObject2(java.lang.String)]

I use the module spring-boot-starter-web of spring boot (v2.7.1 on my project).

Can someone explain me what's wrong in my ussage of body parameters for this delete request ?

Thanks!

Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
Ptiseb
  • 795
  • 1
  • 7
  • 19
  • I don't think the restTemplate has a "delete" which takes a body, that's why the real request is failing (body is not added). I think you'll have to call pure HTTP without passing through Spring's rest template (or use the "exchange" of restTemplate where you build your own RequestHttpEntity with verb DELETE and a body) – Matteo NNZ Aug 03 '22 at 16:19
  • Is there a reason you want to have a method for a DELETE request which takes a body? It's not disallowed to have a body in a DELETE request, but what it should mean is not well specified and some specifications seem to say that the body of a DELETE request should be ignored. See [Is an entity body allowed for an HTTP DELETE request?](https://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request). In other words: Don't design your REST API with a DELETE request that requires a body. – Jesper Aug 03 '22 at 16:50
  • Thanks for your messages. It worked using the exchange method. @Jesper, noted :) i didn't get this point of the spec. – Ptiseb Aug 04 '22 at 11:35

1 Answers1

1

I use the module spring-boot-starter-web of spring boot (v2.7.1 on my project).

According to the most recent version of rest template, it offers only the following delete methods and none of these methods expects an entity as parameter to be sent to request body of http request.

void delete(String url, Map<String,?> uriVariables)

void delete(String url, Object... uriVariables)

void delete(URI url)

Uri variables that the above methods offer are something different. They are passed and then used to modify the URI accordingly. If for example your URI was ./some1/some2/{foo}, you pass a uriVariable like 2 and it makes the URI ./some1/some2/2.

This is not what you need and you currently have no other choice, than to work around this issue, as it remains at your disposal the general exchange method of restTemplate.

<T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> >  responseType, Object... uriVariables)

Execute the HTTP method to the given URI template, writing the given request entity > to the request, and returns the response as ResponseEntity.

This is how it could be used.

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN_VALUE);

HttpEntity<String> entity = new HttpEntity<String>("SomeText", headers);
restTemplate.exchange("http://localhost:8090/url/route2", HttpMethod.DELETE, entity, String.class);
Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
  • Thanks for the explanation ! I actually got confused with this put method of restTemplate : put(String url, @Nullable Object request, Object... uriVariables) I got confused between request & uriVariables. It's clear, thanks :) – Ptiseb Aug 04 '22 at 11:30