restTemplate delete with body
Solution 1
Another way to fix this is to use restTemplate.exchange
, here's an example:
try {
String jsonPayload = GSON.toJson(request);
HttpEntity<String> entity = new HttpEntity<String>(jsonPayload.toString(),headers());
ResponseEntity resp = restTemplate.exchange(url, HttpMethod.DELETE, entity, String.class);
} catch (HttpClientErrorException e) {
/* Handle error */
}
The nice thing about this solution is that you can use it with all HttpMethod types.
Solution 2
Issue exists for Spring version 4.0.x or earlier.
In later version it has been fixed.
This might be a late answer, but in one of my project I solved this issue via a custom ClientHttpRequestFactory
to RestTemplate
If no factory is provided to RestTemplate
, it uses default implementation SimpleClientHttpRequestFactory
In SimpleClientHttpRequestFactory
class, DELETE
method is not allowed with request body.
if ("PUT".equals(httpMethod) || "POST".equals(httpMethod) ||
"PATCH".equals(httpMethod)) {
connection.setDoOutput(true);
}
else {
connection.setDoOutput(false);
}
Just write your own implementation as
import java.io.IOException;
import java.net.HttpURLConnection;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
public class CustomClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
@Override
protected void prepareConnection(HttpURLConnection connection,
String httpMethod) throws IOException {
super.prepareConnection(connection, httpMethod);
if("DELETE".equals(httpMethod)) {
connection.setDoOutput(true);
}
}
}
After that create your RestTemplate
object as
RestTemplate template = new RestTemplate(
new CustomClientHttpRequestFactory());
Fix in later versions of (4.1.x or above) SimpleClientHttpRequestFactory
class
if ("POST".equals(httpMethod) || "PUT".equals(httpMethod) ||
"PATCH".equals(httpMethod) || "DELETE".equals(httpMethod)) {
connection.setDoOutput(true);
}
else {
connection.setDoOutput(false);
}
Related videos on Youtube
Shiva
Updated on June 18, 2022Comments
-
Shiva almost 2 years
I am trying to do DELETE with request body but I keep getting 400 (bad request) error. When I do it in the swagger/postman, it is successfully deleting the record. But from the Java code I can't do that
The external API is designed in a way that it needs body along with URL. It can't be changed. please let me know how can I delete that entry with request body
public Person delete(Person person, String url, Map<String, String> uriVariables) throws JsonProcessingException { RestTemplate restTemplate = new RestTemplate(); CustomObjectMapper mapper = new CustomObjectMapper(); HttpEntity<Person> requestEntity = new HttpEntity<Person>(person); try { ResponseEntity<Person> responseEntity = restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, Person.class, uriVariables); return responseEntity.getBody(); } catch (RestClientException e) { System.out.println(mapper.writeValueAsString(person)); throw e; } }
when it goes to exception, I will get the JSON request in JSON format and the same works fine in Swagger/postman
I did some googling and found that restTemplate have problem deleting when there is request body. this article wasn't helpful https://jira.spring.io/browse/SPR-12361 is there any way to get it work
-
TaylorThe bug you linked to is fairly self-explanatory. Spring on java <1.8 will not be able to send a body with a DELETE. The issue is actually in java, not Spring. I suspect this comes from a rather strict reading of the http spec, regardless, there's no way to get it to work short of moving to jdk 1.8, per the bug.
-