前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring RestTemplate进阶:拦截器

Spring RestTemplate进阶:拦截器

作者头像
烟雨平生
发布2023-03-07 16:33:14
2.4K0
发布2023-03-07 16:33:14
举报
文章被收录于专栏:数字化之路数字化之路
原文链接:https://www.baeldung.com/spring-rest-template-interceptor

作者: baeldung

译者:helloworldtang

1. 概览

在这篇文章中,我们将学习如何实现一个Spring RestTemplate 拦截器。

文中将通过一个示例来展示如何创建一个Spring RestTemplate拦截器及如何使用这个拦截器来添加一个自定义HTTP头。

2. 拦截器的使用场景

除了修改HTTP头之外,RestTemplate拦截器还可以用于下面的场景:

  • 打印请求和响应日志
  • 用可配置的回滚策略进行重试
  • 基于某些请求参数来拒绝请求
  • 改变请求的URL

3. 创建拦截器

在大多数编程范例中,拦截器是程序员能够通过拦截来控制程序执行的重要途径。基于不同的场景,Spring框架还支持各式各样的拦截器。

Spring RestTemplate允许我们添加实现了ClientHttpRequestInterceptor接口的拦截器。这个接口的intercept(HttpRequest, byte[], ClientHttpRequestExecution)方法将通过让我们访问requestbodyexecution对象来拦截指定的请求并返回响应。

我们将使用ClientHttpRequestExecution参数来执行实际的操作,并将请求传递给后续的调用链。

首先,让我们创建一个实现了ClientHttpRequestInterceptor接口的拦截器类

代码语言:javascript
复制
public class RestTemplateHeaderModifierInterceptor
  implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(
      HttpRequest request, 
      byte[] body, 
      ClientHttpRequestExecution execution) throws IOException {

        ClientHttpResponse response = execution.execute(request, body);
        response.getHeaders().add("Foo", "bar");
        return response;
    }
}

我们的拦截器将被用于每个传入的请求,并且一旦执行完成,在返回前,这个拦截器将向每个响应添加一个自定义的HTTP头Foo

由于intercept()方法的参数签名包含requestbody,所以还可以根据某些条件对请求进行任何修改,甚至拒绝请求执行。

4. 配置RestTemplate

既然已经创建了拦截器,那么就让我们在创建RestTemplate bean时添加这个拦截器:

代码语言:javascript
复制
@Configuration
public class RestClientConfig {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();

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

在某些情况下,RestTemplate对象可能已经添加了拦截器。因此,为了确保一切正常工作,上面的示例代码只在拦截器列表为空的时候才重新进行初始化。

正如上面的代码所示,我们使用默认的构造函数来创建RestTemplate对象,但在某些情况下,我们需要读取请求/响应流两次。

例如,如果我们希望拦截器用作请求/响应记录器,那么就需要读取两次——第一次由拦截器读取,第二次由客户端读取。

默认的实现只允许我们读取一次响应流。为了满足这些特定的场景,Spring提供了一个名为BufferingClientHttpRequestFactory的特殊类。顾名思义,该类会将请求/响应缓存在JVM内存中,以供多次使用。

下面介绍如何使用BufferingClientHttpRequestFactory来初始化RestTemplate并启用请求/响应流缓存:

代码语言:javascript
复制
RestTemplate restTemplate 
  = new RestTemplate(
    new BufferingClientHttpRequestFactory(
      new SimpleClientHttpRequestFactory()
    )
  );

5. 测试

下面是测试RestTemplate拦截器的JUnit测试用例:

代码语言:javascript
复制
public class RestTemplateItegrationTest {

    @Autowired
    RestTemplate restTemplate;

    @Test
    public void givenRestTemplate_whenRequested_thenLogAndModifyResponse() {
        LoginForm loginForm = new LoginForm("username", "password");
        HttpEntity<LoginForm> requestEntity
          = new HttpEntity<LoginForm>(loginForm);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        ResponseEntity<String> responseEntity
          = restTemplate.postForEntity(
            "http://httpbin.org/post", requestEntity, String.class
          );

        assertThat(
          responseEntity.getStatusCode(),
          is(equalTo(HttpStatus.OK))
        );
        assertThat(
          responseEntity.getHeaders().get("Foo").get(0),
          is(equalTo("bar"))
        );
    }
}

在上面的例子中,我们将请求数据发送到一个免费托管的HTTP服务器http://httpbin.org。这个测试服务器将返回我们的请求体以及一些元数据。

6. 总结

本教程介绍如何设置拦截器并将其配置到RestTemplate对象中。这种拦截器还可以用于过滤、监控和控制传入的请求。 RestTemplate拦截器的一个常用场景是修改HTTP头——我们已经在本文中详细说明了这一点。

和往常一样,文中用到的示例代码可以在Github项目上找到。这是一个基于maven的项目,因此应该很容易导入和运行。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-09-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 的数字化之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 概览
  • 2. 拦截器的使用场景
  • 3. 创建拦截器
  • 4. 配置RestTemplate
  • 5. 测试
  • 6. 总结
相关产品与服务
测试服务
测试服务 WeTest 包括标准兼容测试、专家兼容测试、手游安全测试、远程调试等多款产品,服务于海量腾讯精品游戏,涵盖兼容测试、压力测试、性能测试、安全测试、远程调试等多个方向,立体化安全防护体系,保卫您的信息安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档