Search code examples
javaspring-bootresttemplate

How to configure RestTemplate to be used with different URLs and Response Entities?


I defined a Configuration class like this:

@Configuration
public class RestTemplateConfiguration {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

The bean above is used by different services to perform actions like these:

ResponseEntity<Cars> cars= restTemplate.exchange(
                                                     RequestEntity.get(new URI(url)).headers(headers).build(),
                                                    Cars.class);

or

ResponseEntity<CarDetail> savingAmountConsumed = restTemplate.exchange(
                                                            builder.buildAndExpand(uriVariable).toUri(),
                                                            HttpMethod.PUT,
                                                            requestEntity,
                                                            CarDetail.class);

For each service, I'm defining different URI variable uriVariable and always defining the same header configuration like this:

HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(token);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

Is it possible to reconfigure the RestTemplate in a way that I don't need to set the same header in different services multiple times? (same question applies to the URI)


Solution

  • In order to set the Accept header you can use an Interceptor as follows:

    public class AcceptHeaderSetterInterceptor implements ClientHttpRequestInterceptor {
    
      @Override
      public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        HttpHeaders headers = request.getHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        return execution.execute(request, body);
      }
    }
    

    Then you need to register this Interceptor:

    @Configuration
    public class Config {
    
      @Bean
      public RestTemplate restTemplate() {
          RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
          restTemplate.setInterceptors(Collections.singletonList(new AcceptHeaderSetterInterceptor()));
          return restTemplate;
      }
    }
    

    Regarding the URI I wouldn't suggest you do that because it is pretty common to use the same RestTemplate to call different URLs. The same goes for the Bearer Token because I guess it really depends on the URL you are calling.