SpringCloud详解 第五章 API网关服务zuul(三)
本章梳理过滤器
Zuul中提供了过滤器定义,可以用来过滤代理请求,提供额外功能逻辑。如:权限验证,日志记录等。
Zuul提供的过滤器是一个父类。父类是ZuulFilter。通过父类中定义的抽象方法filterType,来决定当前的Filter种类是什么。有前置过滤、路由后过滤、后置过滤、异常过滤。
- 前置过滤:是请求进入Zuul之后,立刻执行的过滤逻辑。
- 路由后过滤:是请求进入Zuul之后,并Zuul实现了请求路由后执行的过滤逻辑,路由后过滤,是在远程服务调用之前过滤的逻辑。
- 后置过滤:远程服务调用结束后执行的过滤逻辑。
- 异常过滤:是任意一个过滤器发生异常或远程服务调用无结果反馈的时候执行的过滤逻辑。无结果反馈,就是远程服务调用超时。
一、过滤器实现方式
继承父类ZuulFilter。在父类中提供了4个抽象方法,分别是:filterType, filterOrder, shouldFilter, run。其功能分别是:
- filterType:方法返回字符串数据,代表当前过滤器的类型。可选值有-pre, route, post, error。
pre - 前置过滤器,在请求被路由前执行,通常用于处理身份认证,日志记录等;
route - 在路由执行后,服务调用前被调用;
error - 任意一个filter发生异常的时候执行或远程服务调用没有反馈的时候执行(超时),通常用于处理异常;
post - 在route或error执行后被调用,一般用于收集服务信息,统计服务性能指标等,也可以对response结果做特殊处理。
- filterOrder:返回int数据,用于为同filterType的多个过滤器定制执行顺序,返回值越小,执行顺序越优先。
- shouldFilter:返回boolean数据,代表当前filter是否生效。
- run:具体的过滤执行逻辑。如pre类型的过滤器,可以通过对请求的验证来决定是否将请求路由到服务上;如post类型的过滤器,可以对服务响应结果做加工处理(如为每个响应增加footer数据)。
二、过滤器的生命周期
三、代码示例
/** * Zuul过滤器,必须继承ZuulFilter父类。 * 当前类型的对象必须交由Spring容器管理。使用@Component注解描述。 * 继承父类后,必须实现父类中定义的4个抽象方法。 * shouldFilter、 run、 filterType、 filterOrder */ @Component public class LoggerFilter extends ZuulFilter { private static final Logger logger = LoggerFactory.getLogger(LoggerFilter.class); /** * 返回boolean类型。代表当前filter是否生效。 * 默认值为false。 * 返回true代表开启filter。 */ @Override public boolean shouldFilter() { return true; } /** * run方法就是过滤器的具体逻辑。 * return 可以返回任意的对象,当前实现忽略。(spring-cloud-zuul官方解释) * 直接返回null即可。 */ @Override public Object run() throws ZuulException { // 通过zuul,获取请求上下文 RequestContext rc = RequestContext.getCurrentContext(); HttpServletRequest request = rc.getRequest(); logger.info("LogFilter1.....method={},url={}", request.getMethod(),request.getRequestURL().toString()); // 可以记录日志、鉴权,给维护人员记录提供定位协助、统计性能 return null; } /** * 过滤器的类型。可选值有: * pre - 前置过滤 * route - 路由后过滤 * error - 异常过滤 * post - 远程服务调用后过滤 */ @Override public String filterType() { return "pre"; } /** * 同种类的过滤器的执行顺序。 * 按照返回值的自然升序执行。 */ @Override public int filterOrder() { return 0; } }
四、核心过滤器
五、禁用过滤器
实际上,在Zuul中特别提供了一个参数来禁用指定的过滤器,该参数的配置格式如下:
zuul.<SimpleClassName>.<filterType>.disable=true