Tuesday 13 August 2013

Spring RestTemplate calling the Delete method with a request body (Delete With Request Body)

  Spring Framework RestTemplate class defines some of our services through java code calls Rest often need to use the method, so we call the rest through java services more convenient and simple. But RestTemplate delete method does not support the incoming request body (Request Body). Tested by calling RestTemplate class exchange (String url, HttpMethod method, HttpEntity <?> requestEntity, Class <ResponseResult> responseType, Object ... uriVariables)  method, the method is specified as org.springframework.http.HttpMethod.DELETE, and pass requestEntity (request body) object, in the service side of the Request Body still get to null. Visible RestTemplate default DELETE method does not support the right to use the request body.
        Through access to information found RestTemplate default is to use spring itself SimpleClientHttpRequestFactory create a request object and its related settings (such as request headers, request body, etc.), it only supports PUT and POST method with a request body, RestTemplate the DELETE method does not support incoming request body is because the JDK HttpURLConnection object delete method does not support the incoming request body (if the delete method HttpURLConnection object incoming request body, at runtime will throw IOException).
        We canmodify RestTemplate through the RequestFactory delete method to achieve the support of the request body , such as into Apache HTTPClient's HttpComponents of ClientHttpRequestFactory, because ClientHttpRequestFactory default DELETE method does not support the request body, so we in addition to modifying RestTemplate the RequestFactory, they also need define a transfer request support a DELETE request model, complete code is as follows:

RestTemplate restTemplate = new RestTemplate();

public static class HttpEntityEnclosingDeleteRequest extends HttpEntityEnclosingRequestBase {

    public HttpEntityEnclosingDeleteRequest(final URI uri) {
        super();
        setURI(uri);
    }

    @Override
    public String getMethod() {
        return "DELETE";
    }
}

@Test
public void bodyWithDeleteRequest() throws Exception {
    restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory() {
        @Override
        protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
            if (HttpMethod.DELETE == httpMethod) {
                return new HttpEntityEnclosingDeleteRequest(uri);
            }
            return super.createHttpUriRequest(httpMethod, uri);
        }
    });

    ResponseEntity<String> exchange = restTemplate.exchange(
            "http://example.com/file";,
            HttpMethod.DELETE,
            new HttpEntity<String>("some sample body sent along the DELETE request"),
            String.class);
    assertEquals("Got body: some sample body sent along the DELETE request", exchange.getBody());
}

2 comments:

  1. It's working perfectly. Please tell how to mock it. It's pointing to actual server rather than mock

    ReplyDelete