当前位置:首页 > 说编程 > 正文内容

ZuulFilter过滤器

2022-02-10说编程878

Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。

1、过滤器

1.1 ZuulFilter

ZuulFilter是过滤器的顶级父类。在这里我们看一下其中定义的4个最重要的方法:

public abstract ZuulFilter implements IZuulFilter{
    abstract public String filterType();
    abstract public int filterOrder();
    boolean shouldFilter();// 来自IZuulFilter
    Object run() throws ZuulException;// IZuulFilter
}

说明:

filterType:返回字符串,代表过滤器的类型。包含以下4种:

  • pre:请求在被路由之前执行

  • route:在路由请求时调用

  • post:在route和errror过滤器之后调用

  • error:处理请求时发生错误调用

filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。

shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。

run:过滤器的具体业务逻辑。

1.2 过滤器执行生命周期

这张是Zuul官网提供的请求生命周期图,清晰的表现了一个请求在各个过滤器的执行顺序。

image.png

正常流程:

请求到达首先会经过pre类型过滤器,而后到达route类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。

异常流程:

整个过程中,pre或者route过滤器出现异常,都会直接进入error过滤器,在error处理完毕后,会将请求交给POST过滤器,最后返回给用户。

如果是error过滤器自己出现异常,最终也会进入POST过滤器,将最终结果返回给请求客户端。

如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和route不同的是,请求不会再到达POST过滤器了。

所有内置过滤器列表:

image.png

1.3 使用场景

场景非常多:

请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了

异常处理:一般会在error类型和post类型过滤器中结合来处理。

服务调用时长统计:pre和post结合使用。

2、自定义过滤器

接下来我们来自定义一个过滤器,模拟一个登录的校验。基本逻辑:如果请求中有access-token参数,则认为请求有效,放行。

2.1 定义过滤器类

image.png

内容:

@Component
public class LoginFilter extends ZuulFilter {
    /**
     * 过滤器类型,前置过滤器
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }
    /**
     * 过滤器的执行顺序
     * @return
     */
    @Override
    public int filterOrder() {
        return 1;
    }
    /**
     * 该过滤器是否生效
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }
    /**
     * 登陆校验逻辑
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        // 获取zuul提供的上下文对象
        RequestContext context = RequestContext.getCurrentContext();
        // 从上下文对象中获取请求对象
        HttpServletRequest request = context.getRequest();
        // 获取token信息
        String token = request.getParameter("access-token");
        // 判断
        if (StringUtils.isBlank(token)) {
            // 过滤该请求,不对其进行路由
            context.setSendZuulResponse(false);
            // 设置响应状态码,401
            context.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
            // 设置响应信息
            context.setResponseBody("{\"status\":\"401\", \"text\":\"request error!\"}");
        }
        // 校验通过,把登陆信息放入上下文信息,继续向后执行
        context.set("token", token);
        return null;
    }
}

2.2 测试

没有token参数时,访问失败:

image.png

添加token参数后:

image.png

扫描二维码推送至手机访问。

本文链接:https://suyu.net/post/69.html

作者:CSDN博主「Jing-Kathy」的原创文章,链接:https://blog.csdn.net/luckystar_99/article/details/105354330

分享给朋友:

发表评论

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。