Spring RestTemplate uses interceptors to configure HTTP request headers

Keywords: Programming Spring

Spring RestTemplate is often used as a client to send various requests to the Restful API, and you may have encountered this requirement. Many requests require similar or identical Http headers. If the Header is filled in HttpEntity/RequestEntity before each request, the code would be very redundant.

Spring provides the ClientHttpRequest Interceptor interface, which can intercept requests and modify them or enhance the corresponding information before they are sent to the server. Here is a simple example:

Implementing ClientHttpRequest Interceptor Interface

// Not necessary
@Component
public class ActionTrackInterceptor implements ClientHttpRequestInterceptor {
  @Autowired
  ActionIdGenerator actionIdGenerator;

  @Override
  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
      throws IOException {
    HttpHeaders headers = request.getHeaders();

    // Add custom fields
    headers.add("actionId", actionIdGenerator.generate());

    // Ensure that requests continue to be executed
    return execution.execute(request, body);
  }
}

Add a custom interceptor to the RestTemplate instance

@Configuration
public class ClientConfig {

  // Injection interceptor. The interceptor can also create new instances here without being declared Bean.
  @Autowired
  ActionTrackInterceptor actionTrackInterceptor;

  // Declare as Bean to facilitate the use of the same instance within the application
  @Bean
  public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();

    // Adding a custom Client HttpRequest Interceptor to RestTemplate adds more than one
    restTemplate.setInterceptors(Collections.singletonList(actionTrackInterceptor));
    return restTemplate;
  }
}

Previous work has been completed, now using this RestTemplate instance to send requests will bring the field "actionId" in the Header, of course, you can configure more general fields such as Accept, Content-Type.

// Client Code
restTemplate.getForObject(SERVER_URL, Example.class);

// Server-side code
// If the server is also implemented in Spring RestController/MVC, using the @RequestHeader annotation, you can get the previously added actionId field.
@RequestMapping(value = "/example")
public Example example(@RequestHeader("actionId") String actionId) {
    //Business logic
}

Posted by Welling on Sun, 06 Oct 2019 06:47:48 -0700