Spring RestTemplate 利用攔截器配置 HTTP請求 Header

Spring RestTemplate常常被用做客戶端向Restful API發送各類請求,也許你也碰到過這種需求,不少請求都須要用到類似或者相同的Http Header。若是在每次請求以前都把Header填入HttpEntity/RequestEntity,這樣的代碼會顯得十分冗餘。app

Spring提供了ClientHttpRequestInterceptor接口,能夠對請求進行攔截,並在其被髮送至服務端以前修改請求或是加強相應的信息。下面是一個簡單的例子:ide

實現ClientHttpRequestInterceptor接口

// 不是必要的
@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);
  }
}

將自定義攔截器添加到RestTemplate實例

@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) {
    //業務邏輯
}
相關文章
相關標籤/搜索