Spring RestTemplate 经常被用作客户端向 Restful API 发送各种请求,在开发过程中我们会发现很多请求都会有相同的场景,如请求携带认证的 token、验证的签名、打印请求和响应日志等。在请求方法里面添加这些通用的非业务逻辑,代码显得很冗余。
这个时候我们就思考,我们是不是就可以将这些非业务性代码抽取出来进行复用。
Spring 提供了 ClientHttpRequestInterceptor 接口,可以对请求进行拦截,并在其被发送至服务端之前修改请求或是增强相应的信息。
LogInterceptor 代码
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.http.HttpRequest;
- import org.springframework.http.client.ClientHttpRequestExecution;
- import org.springframework.http.client.ClientHttpRequestInterceptor;
- import org.springframework.http.client.ClientHttpResponse;
- import org.springframework.stereotype.Component;
-
- import java.io.IOException;
- import java.util.Optional;
-
- @Slf4j
- @Component
- public class LogInterceptor implements ClientHttpRequestInterceptor {
-
- @Override
- public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
- ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, bytes);
- log.info("request = {}, requestBody = {}, response = {}", httpRequest,
- Optional.of(bytes).map(String::new).orElse(""), response);
- return response;
- }
- }
TokenInterceptor 代码
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpRequest;
- import org.springframework.http.client.ClientHttpRequestExecution;
- import org.springframework.http.client.ClientHttpRequestInterceptor;
- import org.springframework.http.client.ClientHttpResponse;
- import org.springframework.stereotype.Component;
-
- import java.io.IOException;
-
- @Slf4j
- @Component
- public class TokenInterceptor implements ClientHttpRequestInterceptor {
-
- @Override
- public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
- HttpHeaders headers = httpRequest.getHeaders();
- headers.add("Authorization", "token");
- return clientHttpRequestExecution.execute(httpRequest, bytes);
- }
- }
- import com.google.common.collect.Lists;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.http.client.ClientHttpRequestInterceptor;
- import org.springframework.web.client.RestTemplate;
-
- import java.util.List;
-
- @Configuration
- public class RestTemplateConfig {
-
- @Autowired
- private LogInterceptor logInterceptor;
-
- @Autowired
- private TokenInterceptor tokenInterceptor;
-
- @Bean
- public RestTemplate restTemplate() {
- RestTemplate restTemplate = new RestTemplate();
- List
interceptorList = Lists.newArrayList(); - // 增加多个拦截器,多个拦截器按照顺序执行
- interceptorList.add(tokenInterceptor);
- interceptorList.add(logInterceptor);
- restTemplate.setInterceptors(interceptorList);
- return restTemplate;
- }
- }