通过拦截器或HttpEntity将HTTP标头添加到RestTemplate?

时间:2019-04-03 14:23:52

标签: java spring resttemplate spring-web

如果我有一些静态标头应应用于以RestTemplate发送的任何请求:应如何添加这些标头?

在此示例中,我始终希望发送http标头accept=applicaton/json。 (也可以是其他任何标头,也可以是多个标头)。

1)HttpEntity,然后发送:

HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);

ResponseEntity<Rsp> http = restTemplate.postForEntity(host, new HttpEntity<>(req, headers), type);

2)ClientHttpRequestInterceptor

class MyInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        request.getHeaders().set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
        return execution.execute(request, body);
    }
}

@Bean
public RestTemplateCustomizer customizer() {
    return restTemplate -> restTemplate.getInterceptors().add(new MyInterceptor());
}

然后发布:

restTemplate.postForEntity(host, req, type);

哪个人比另一个人有优势,因此应该优先考虑?

3 个答案:

答案 0 :(得分:2)

选项1似乎很难维护,因为开发人员每次都需要记住要这样做。选项2会更好,我只会做以下更改:

你在哪里

restTemplate.getInterceptors().add(new MyInterceptor())

我会

List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
if (CollectionUtils.isEmpty(interceptors)) {
    interceptors = new ArrayList<>();
}
interceptors.add(new MyInterceptor());
restTemplate.setInterceptors(interceptors);

这样,您可以在列表为空的情况下对其进行初始化。

另外,请小心,因为有人可以为bean设置新的拦截器列表并丢失您的。

答案 1 :(得分:0)

1)HttpEntity直接在发送之前:对restTemplate的细粒度控制。它可以工作,但是您必须在各处重复执行代码,而开发人员可能会忘记(DRY)

2)ClientHttpRequestInterceptorRestTemplateCustomizer:从restTemplateBuilder bean创建的每个restTemplate都将具有此拦截器,适用于一般行为。

答案 2 :(得分:-1)

Java 8 Lambda 使用拦截器的方式

new RestTemplateBuilder().interceptors(
   (HttpRequest request, byte[] body, ClientHttpRequestExecution execution) -> {
      request.getHeaders().set(AUTHORIZATION, token);
      return execution.execute(request, body);
   }
).build()