RestTemplate PATCH request

后端 未结 5 1207
旧巷少年郎
旧巷少年郎 2020-12-13 17:48

I have the following definition for PersonDTO:

public class PersonDTO
{
    private String id
    private String firstName;
    private String lastName;
             


        
相关标签:
5条回答
  • 2020-12-13 18:32

    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>
    
    0 讨论(0)
  • 2020-12-13 18:38

    If you have an older spring version than 3.1.0, then you don't have the PATCH method in the HttpMethods. You can still use HttpClient from apache. Here is a short example on how I did it:

        try {
    
            //This is just to avoid ssl hostname verification and to trust all, you can use simple Http client also
            CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
                    .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
    
            HttpPatch request = new HttpPatch(REST_SERVICE_URL);
            StringEntity params = new StringEntity(JSON.toJSONString(payload), ContentType.APPLICATION_JSON);
            request.setEntity(params);
            request.addHeader(org.apache.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
            request.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
            //You can use other authorization method, like user credentials
            request.addHeader(HttpHeaders.AUTHORIZATION, OAuth2AccessToken.BEARER_TYPE + " " + accessToken);
            HttpResponse response =     httpClient.execute(request);            
    
            String statusCode = response.getStatusLine().getStatusCode();
    
        } catch (Exception ex) {
            // handle exception here
        }
    

    The equivalent of this, with RestTemplate would be:

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("Authorization", OAuth2AccessToken.BEARER_TYPE + " " + accessToken);
        final HttpEntity<String> entity = new HttpEntity<String>(JSON.toJSONString(payload), headers);
        RestTemplate restTemplate = new RestTemplate();
        try {
            ResponseEntity<String> response = restTemplate.exchange(REST_SERVICE_URL, HttpMethod.PATCH, entity, String.class);
            String statusCode =  response.getStatusCode();
        } catch (HttpClientErrorException e) {
            // handle exception here
        }
    

    Also, make sure the payload only contains the values you need to change, and make sure you are sending the request to the right URL. (this can be in some cases something ending like /api/guest/{id} )

    0 讨论(0)
  • 2020-12-13 18:40

    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

    0 讨论(0)
  • 2020-12-13 18:46

    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>
    
    0 讨论(0)
  • 2020-12-13 18:46

    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.

    0 讨论(0)
提交回复
热议问题