How do I implement a PATCH executed via RestTemplate?

LitterWalker picture LitterWalker · Jan 9, 2017 · Viewed 9.4k times · Source

I am coding JUnit tests, calling my application via RestTemplate. I have successfully implemented GETs, POSTs, and PUTs, but can not get a PATCH to run (though it works when a client sends in the URL). A POST, for example, runs with this code:

    RestTemplate restTemplate = new RestTemplate(); 
    ProductModel postModel = restTemplate.postForObject(TestBase.URL + URL, pModel, ProductModel.class);            

but when I tried to call restTemplate.patchForObject() - which I found online - STS returns an error saying that function is not defined. I thus used this:

    RestTemplate restTemplate = new RestTemplate(); 
    ResponseEntity<MessageModel> retval = restTemplate.exchange("http://localhost:8080/products/batchUpdateProductPositions", 
            HttpMethod.PATCH, new HttpEntity<ProductPositionListModel>(pps), MessageModel.class);   

which compiles, but gives me an error:

I/O Error on PATCH request for "http://localhost:8080/products/batchUpdateProductPositions": Invalid HTTP method: PATCH

In the application, I have the operation defined in a Controller class:

@RequestMapping(value = "/batchUpdateProductPositions", method = RequestMethod.PATCH)
public MessageModel batchUpdatePosition(
        @RequestBody ProductPositionListModel productPositionList)
        throws Exception {
    try {
        return productService.batchUpdatePosition(productPositionList);
    } catch (Exception e) {

I put a breakpoint on the return statement inside the 'try' block, but it never tripped when I ran it under debug.

Can anyone tell me where I tripped up?

Answer

Alexander Yanyshin picture Alexander Yanyshin · Jan 10, 2017

By default RestTemplate uses standard JDK HttpURLConnection HTTP client to make requests. This client does not support PATCH method. You can configure RestTemplate to use some other HTTP client via client factory, like HttpComponentsClientHttpRequestFactory or OkHttpClientHttpRequestFactory.

HttpClient client = HttpClients.createDefault();
RestTemplate template= new RestTemplate();
template.setRequestFactory(new HttpComponentsClientHttpRequestFactory(client)); 

You will also need to add proper dependencies, something like org.apache.httpcomponents:httpclient:$version in case HTTP Components client.