Spring RestTemplate常常被用做客戶端向Restful API發送各類請求,也許你也碰到過這種需求,不少請求都須要用到類似或者相同的Http Header。若是在每次請求以前都把Header填入HttpEntity/RequestEntity,這樣的代碼會顯得十分冗餘。app
Spring提供了ClientHttpRequestInterceptor接口,能夠對請求進行攔截,並在其被髮送至服務端以前修改請求或是加強相應的信息。下面是一個簡單的例子:ide
// 不是必要的 @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(); // 加入自定義字段 headers.add("actionId", actionIdGenerator.generate()); // 保證請求繼續被執行 return execution.execute(request, body); } }
@Configuration public class ClientConfig { // 注入攔截器。攔截器也能夠不聲明爲Bean, 直接在這裏新建實例 @Autowired ActionTrackInterceptor actionTrackInterceptor; // 聲明爲Bean,方便應用內使用同一實例 @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); // 把自定義的ClientHttpRequestInterceptor添加到RestTemplate,可添加多個 restTemplate.setInterceptors(Collections.singletonList(actionTrackInterceptor)); return restTemplate; } }
前期的工做已經完成了,如今使用這個RestTemplate實例發送請求,就會在Header中帶上「actionId」這個字段了,固然你能夠配置更多的諸如Accept, Content-Type等通用的字段。spa
// 客戶端代碼 restTemplate.getForObject(SERVER_URL, Example.class); // 服務端代碼 // 若是服務端也是用Spring RestController/MVC 實現,利用@RequestHeader註解,便可獲取以前添加的actionId字段了 @RequestMapping(value = "/example") public Example example(@RequestHeader("actionId") String actionId) { //業務邏輯 }