(六)api网关服务 zuul-过滤器
开启上文服务:
Zuul给我们的第一印象通常是这样:它包含了对请求的路由和过滤两个功能,其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础。过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。然而实际上,路由功能在真正运行时,它的路由映射和请求转发都是由几个不同的过滤器完成的。其中,路由映射主要是通过PRE类型的过滤器完成,它将请求路径与配置的路由规则进行匹配,以找到需要转发的目标地址。而请求转发的部分则是由Route类型的过滤器来完成,对PRE类型过滤器获得的路由地址进行转发。所以,过滤器可以说是Zuul实现API网关功能最重要的核心部件,每一个进入Zuul的请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。
Zuul(ZuulFilter)过滤器的关键特性有:
- Type: 定义在请求执行过程中何时被执行;
- Execution Order: 当存在多个过滤器时,用来指示执行的顺序,值越小就会越早执行;
- Criteria: 执行的条件,即该过滤器何时会被触发;
- Action: 具体的动作。
@Component public class MyZuulFilterPre extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(MyZuulFilterPre.class); //filterType:返回一个字符串代表过滤器的类型 @Override public String filterType() { return FilterConstants.PRE_TYPE; //pre:路由之前 route:路由之时 post: 路由之后 error:发送错误调用 } //filterOrder:过滤的顺序 @Override public int filterOrder() { return 0; } //这里可以写逻辑判断,是否要过滤,本文true,永远过滤 @Override public boolean shouldFilter() { return true; } //过滤器的具体逻辑。判断该请求到底有没有权限访问。 @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString())); Object accessToken = request.getParameter("token"); if (accessToken == null) { log.warn("token is empty"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("token is empty"); } catch (Exception e) { } return null; } log.info("ok"); return null; } }
测试结果:
Zuul中定义了四种标准的过滤器类型,这些过滤器类型对应于请求的典型生命周期。
PRE
过滤器: 在请求被路由之前调用, 可用来实现身份验证、在集群中选择请求的微服务、记录调试信息等;ROUTING
过滤器: 在路由请求时候被调用;POST
过滤器: 在路由到微服务以后执行, 可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等;ERROR
过滤器: 在处理请求过程时发生错误时被调用。
除了上面给出的四种默认的过滤器类型之外,Zuul还允许我们创建自定义的过滤器类型。(暂没尝试)
禁用过滤器
只需要在application.properties(或yml)中配置需要禁用的filter,格式为:zuul.[filter-name].[filter-type].disable=true
zuul.MyZuulFilterPre.pre.disable=true
链接:https://www.jianshu.com/p/f786a11a2def
來源:简书