Spring Cloud 应用篇 之 Spring Cloud Zuul(二)过滤功能

在上一篇 Spring Cloud 应用篇 之 Spring Cloud Zuul(一)路由功能 中,讲解了 Zuul 的路由功能,这一篇讲解 Zuul 的过滤功能。

(一)简介

Zuul 允许开发者在 API 网关上通过定义过滤器来实现对请求的拦截与过滤,实现的方法非常简单,我们只需继承 ZuulFilter 抽象类并实现它定义的 4 个 抽象函数就可以完成对请求的拦截和过滤了。Zuul 定义了下面四种过滤器

  • 前置(Pre)
  • 路由(Route)
  • 后置(Post)
  • 错误(Error)

(二)实现前置(Pre)过滤器

2.1 创建过滤器

这里我们仅是做案例测试,所以仅在请求被路由之前检查 HttpServletRequest 中是否有 token 参数,若有就进行路由,若没有就拒绝访问,返回 401 Unauthorized 错误。在 spring-cloud-gateway 模块中创建 PreFilter 类并继承 ZuulFilter,具体实现代码如下:


  
  
  1. @Component
  2. public class PreFilter extends ZuulFilter {
  3. private static Logger log = LoggerFactory.getLogger(PreFilter.class);
  4. @Override
  5. public String filterType() {
  6. return PRE_TYPE; //过滤器类型 : pre
  7. }
  8. @Override
  9. public int filterOrder() {
  10. return PRE_DECORATION_FILTER_ORDER - 5; //过滤器执行顺序,数字越小,优先级越高,越靠前,这里设置为 0
  11. }
  12. @Override
  13. public boolean shouldFilter() {
  14. return true; //返回 true,拦截所有 URL
  15. }
  16. @Override
  17. public Object run() throws ZuulException {
  18. RequestContext requestContext = RequestContext.getCurrentContext();
  19. HttpServletRequest request = requestContext.getRequest();
  20. log.info( “send {} request to {}”, request.getMethod(), request.getRequestURL().toString());
  21. String token = request.getParameter( “token”);
  22. if (StringUtils.isEmpty(token)) {
  23. log.warn( “token is empty”);
  24. requestContext.setSendZuulResponse( false);
  25. requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
  26. return null;
  27. }
  28. log.info( “token is ok”);
  29. return null;
  30. }
  31. }

在上面实现的过滤器代码中,我们通过继承 ZuulFilter 抽象类并重写下面 4 个方法来实现自定义的过滤器。这 4 个方法分别定义了如下内容。

  • filterType:过滤器的类型,它决定过滤器在请求的哪个生命周期中执行。这里定义为 pre,代表会在请求被路由之前执行。
  • filterOrder:过滤器的执行顺序。当请求在一个阶段中存在多个过滤器时,需要根据该方法返回值来依次执行。
  • shouldFilter:判断该过滤器是否需要被执行。这里直接返回了 true,因此该过滤器对所有请求都会生效。实际运用中可以利用该函数来指定过滤器的有效范围。
  • run:过滤器的具体逻辑。这里通过 requestContext.setSendZuulResponse(false) 令 Zuul 过滤该请求,不对其进行路由,然后通过 requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()) 设置了其返回的错误码,当然也可以对返回的结果进行优化,比如,通过 requestContext.setResponseBody(body) 对返回的 body 内容进行编辑等。
2.2 验证过滤器

访问 http://localhost:9001/demoService/port,这个请求的 URL 并没有 token 参数,所以请求被拦截,结果如下

 

从后台日志也可以看出,请求被拦截



下面访问 http://localhost:9001/demoService/port?token=123,这个 URL 有 token 参数,所以顺利被 Zuul 路由,结果如下


从后台日志中也可以看出,请求没有被拦截



(三)简单实现后置(Post)过滤器

3.1 创建过滤器

这里简单的对请求的 response 设置一个 header,代码如下,实现逻辑和 Pre 过滤器类似


  
  
  1. @Component
  2. public class PostFilter extends ZuulFilter {
  3. @Override
  4. public String filterType() {
  5. return POST_TYPE;
  6. }
  7. @Override
  8. public int filterOrder() {
  9. return SEND_RESPONSE_FILTER_ORDER - 1;
  10. }
  11. @Override
  12. public boolean shouldFilter() {
  13. return true;
  14. }
  15. @Override
  16. public Object run() throws ZuulException {
  17. RequestContext requestContext = RequestContext.getCurrentContext();
  18. HttpServletResponse response = requestContext.getResponse();
  19. response.setHeader( "geny", "shmily");
  20. return null;
  21. }
  22. }
3.2 验证过滤器

访问 http://localhost:9001/demoService/port?token=123,可以看到,对 response 设置的 header 已经成功返回。


源码下载:https://github.com/shmilyah/spring-cloud-componets
转载自:https://blog.csdn.net/hubo_88/article/details/80862397

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值