RestTemplate PATCH request

Solution 1:

I solved this problem just adding a new HttpRequestFactory to my restTemplate instance. Like this

RestTemplate restTemplate = new RestTemplate();

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(TIMEOUT);
requestFactory.setReadTimeout(TIMEOUT);

restTemplate.setRequestFactory(requestFactory);

For TestRestTemplate, add

@Autowired
private TestRestTemplate restTemplate;

@Before
public void setup() {
    restTemplate.getRestTemplate().setRequestFactory(new HttpComponentsClientHttpRequestFactory());
}

PS: You will need add httpClient component in your project

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.4.1</version>
</dependency>

Solution 2:

For cases where RestTemplate is built from a RestTemplateBuilder, constructor for the custom RestClient can be written as,

public PersonRestClient(RestTemplateBuilder restTemplateBuilder) {
  this.restTemplate = restTemplateBuilder.requestFactory(new HttpComponentsClientHttpRequestFactory()).build();
}

Also, the org.apache.httpcomponents.httpclient dependency needs to added to pom.

Solution 3:

I have added the below code in the java file. It worked for me.

String url="Your API URL";
RestTemplate restTemplate = new RestTemplate();
HttpClient httpClient = HttpClientBuilder.create().build();
restTemplate.setRequestFactory(new 
HttpComponentsClientHttpRequestFactory(httpClient));    
HttpHeaders reqHeaders = new HttpHeaders();
reqHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> requestEntity = new HttpEntity<String>(requestJson, reqHeaders);
ResponseEntity<String> responseEntity=restTemplate.exchange(url, HttpMethod.PATCH, 
requestEntity, String.class);

Also, need to add the below dependency in the pom.xml file.

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

Solution 4:

I created a generic method to do this when there are linked resources involved:

public void patch(M theEntity, Integer entityId, String linkName, URI linkUri) {
    ObjectMapper objectMapper = getObjectMapperWithHalModule();
    ObjectNode linkedNode = (ObjectNode) objectMapper.valueToTree(theEntity);
    linkedNode.put(linkName, linkUri.getPath());

    HttpEntity<ObjectNode> requestEntity = new HttpEntity<>(linkedNode);

    restTemplate.exchange(uri + "/" + entityId, HttpMethod.PATCH, requestEntity, Void.class);
}

private ObjectMapper getObjectMapperWithHalModule() {
    if(objectMapperHal == null) {
        objectMapperHal = new ObjectMapper();
        objectMapperHal.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapperHal.registerModule(new Jackson2HalModule());
    }

    return objectMapperHal;
}

Feel free to look at an implementation of this example at my full jal+json implementation