首先看到Filter的四个方法,FilterType,filterOrder,shouldFilter,run。

filterType代表过滤类型

PRE: 该类型的filters在Request routing到源web-service之前执行。用来实现Authentication、选择源服务地址等
ROUTING:该类型的filters用于把Request routing到源web-service,源web-service是实现业务逻辑的服务。这里使用HttpClient请求web-service。
POST:该类型的filters在ROUTING返回Response后执行。用来实现对Response结果进行修改,收集统计数据以及把Response传输会客户端。
ERROR:上面三个过程中任何一个出现错误都交由ERROR类型的filters进行处理。

主要关注 pre、post和error。分别代表前置过滤,后置过滤和异常过滤。

如果你的filter是pre的,像上一篇那种,就是指请求先进入pre的filter类,你可以进行一些权限认证,日志记录,或者额外给Request增加一些属性供后续的filter使用。pre会优先按照order从小到大执行,然后再去执行请求转发到业务服务。

再说post,如果type为post,那么就会执行完被路由的业务服务后,再进入post的filter,在post的filter里,一般做一些日志记录,或者额外增加response属性什么的。

最后error,如果在上面的任何一个地方出现了异常,就会进入到type为error的filter中。

filterOrder代表过滤器顺序

这个不多说,试一下就知道了。

shouldFilter代表这个过滤器是否生效

true代表生效,false代表不生效。那么什么情况下使用不生效呢,不生效干嘛还要写这个filter类呢?

其实是有用的,有时我们会动态的决定让不让一个filter生效,譬如我们可能根据Request里是否携带某个参数来判断是否需要生效,或者我们需要从上一个filter里接收某个数据来决定,再或者我们希望能手工控制是否生效(使用如Appolo之类的配置中心,来动态设置该字段)。

Run方法

这个是主要的处理逻辑的地方,我们做权限控制、日志等都是在这里。

下图是filter的执行顺序。

直接用一个简单的示例来看看结果

第一个前置过滤器

package com.tianyalei.testzuul;  import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;  import javax.servlet.http.HttpServletRequest;  @Component
public class AccessFilter extends ZuulFilter {  private static Logger log = LoggerFactory.getLogger(AccessFilter.class);  @Override  public String filterType() {  //前置过滤器  return "pre";  }  @Override  public int filterOrder() {  //优先级,数字越大,优先级越低  return 0;  }  @Override  public boolean shouldFilter() {  //是否执行该过滤器,true代表需要过滤  return true;  }  @Override  public Object run() {  RequestContext ctx = RequestContext.getCurrentContext();  HttpServletRequest request = ctx.getRequest();  log.info("send {} request to {}", request.getMethod(), request.getRequestURL().toString());  //获取传来的参数accessToken  Object accessToken = request.getParameter("accessToken");  if(accessToken == null) {  log.warn("access token is empty");  //过滤该请求,不往下级服务去转发请求,到此结束  ctx.setSendZuulResponse(false);  ctx.setResponseStatusCode(401);  ctx.setResponseBody("{\"result\":\"accessToken为空!\"}");  ctx.getResponse().setContentType("text/html;charset=UTF-8");  return null;  }  //如果有token,则进行路由转发  log.info("access token ok");  //这里return的值没有意义,zuul框架没有使用该返回值  return null;  }  }  

第二个前置过滤器

package com.tianyalei.testzuul;  import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;  import javax.servlet.http.HttpServletRequest;  @Component
public class SecondFilter extends ZuulFilter {  private static Logger log = LoggerFactory.getLogger(SecondFilter.class);  @Override  public String filterType() {  //前置过滤器  return "pre";  }  @Override  public int filterOrder() {  //优先级,数字越大,优先级越低  return 1;  }  @Override  public boolean shouldFilter() {  //是否执行该过滤器,true代表需要过滤  return true;  }  @Override  public Object run() {  RequestContext ctx = RequestContext.getCurrentContext();  HttpServletRequest request = ctx.getRequest();  log.info("second过滤器");  return null;  }  }

后置过滤器

package com.tianyalei.testzuul;  import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;  @Component
public class PostFilter extends ZuulFilter {  private static Logger log = LoggerFactory.getLogger(PostFilter.class);  @Override  public String filterType() {  //后置过滤器  return "post";  }  @Override  public int filterOrder() {  //优先级,数字越大,优先级越低  return 0;  }  @Override  public boolean shouldFilter() {  //是否执行该过滤器,true代表需要过滤  return true;  }  @Override  public Object run() {  RequestContext ctx = RequestContext.getCurrentContext();  log.info("进入post过滤器");  System.out.println(ctx.getResponseBody());  ctx.setResponseBody("post后置数据");  int i = 1 / 0;  return null;  }  }

异常过滤器

package com.tianyalei.testzuul;  import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;  @Component
public class ErrorFilter extends ZuulFilter {  private static Logger log = LoggerFactory.getLogger(ErrorFilter.class);  @Override  public String filterType() {  //异常过滤器  return "error";  }  @Override  public int filterOrder() {  //优先级,数字越大,优先级越低  return 0;  }  @Override  public boolean shouldFilter() {  //是否执行该过滤器,true代表需要过滤  return true;  }  @Override  public Object run() {  RequestContext ctx = RequestContext.getCurrentContext();  log.info("进入异常过滤器");  System.out.println(ctx.getResponseBody());  ctx.setResponseBody("出现异常");  return null;  }  }

定义好之后,直接测试看看

可以看到结果就是按照上面说的顺序在执行。

但是最终给用户呈现这样一个界面就不合适的,我们应该去处理这个"/error"映射的问题。

所以我再定义一个Controller

package com.tianyalei.testzuul;  import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
public class ErrorHandlerController implements ErrorController {  /** * 出异常后进入该方法,交由下面的方法处理 */  @Override  public String getErrorPath() {  return "/error";  }  @RequestMapping("/error")  public String error() {  return "出现异常";  }
}  

在"/error"方法里返回你想给客户端返回的值即可。

ZuulFilter介绍相关推荐

  1. 【SpringCloud】ZuulFilter过滤器

    先介绍一下springboot如何集成日志   常用处理java日志的组件有:slf4j.log4j.logback.common-logging等,LogBack是基于Log4j基础上大量改良的一种 ...

  2. Spring Cloud微服务系统架构的一些简单介绍和使用

    Spring Cloud 目录 特征 云原生应用程序 Spring Cloud上下文:应用程序上下文服务 引导应用程序上下文 应用程序上下文层次结构 改变Bootstrap的位置Properties ...

  3. ZuulFilter统一异常处理

    服务网关zuul之三:zuul统一异常处理 我们详细介绍了Spring Cloud Zuul中自己实现的一些核心过滤器,以及这些过滤器在请求生命周期中的不同作用.我们会发现在这些核心过滤器中并没有实现 ...

  4. 咖啡汪日志 —— 一文看懂Spring Cloud 网关ZuulFilter的使用和源码(包括FilterFactory 的讲解)

    作为乐死不疲的汪界翘楚 本汪每天不是在戏精 就是在戏精的路上了 作为一只纯种哈士奇 玩,就要玩得尽兴而归! 今天与大家一起溜溜,看看 Spring Cloud 网关 ZuulFilter ,从使用到源 ...

  5. springcloud中网关zuul的过滤器zuulFilter的使用

    1 介绍 Filter 的生命周期有 4 个,分别是   "PRE(前置过滤器)":该类型的filters在Request routing到源web-service之前执行.用来实 ...

  6. Spring Cloud Zuul之ZuulFilter详解

    简介 Spring Cloud Zuul网关在整个微服务体系中肩负对外开放接口.请求拦截.路由转发等作用,其核心处理则是ZuulFilter ZuulFilter部分源码 Zuul Filter全部继 ...

  7. 简单介绍互联网领域选择与营销方法

    在我看来,互联网领域的选择是"安家",而营销方法的不同则表现了"定家"的方式多种多样,只有选对了,"家"才得以"安定". ...

  8. 常用开源协议介绍以及开源软件规范列表

    1. 开源协议介绍 GPL: General Public License,开源项目最常用的许可证,衍生代码的分发需开源并且也要遵守此协议.该协议也有很多变种,不同变种要求会略微不同. MPL: MP ...

  9. python:Json模块dumps、loads、dump、load介绍

    20210831 https://www.cnblogs.com/bigtreei/p/10466518.html json dump dumps 区别 python:Json模块dumps.load ...

最新文章

  1. 新鲜出炉!年度10篇新颖到出格的 AI 论文(附链接)
  2. oracle 调优3
  3. c语言库函数fgets,C语言 标准I/O库函数 fgets 使用心得
  4. PP视频怎么把输出声音设置成单声道输出
  5. centOS下lnamp安装
  6. keyevent 封装_adb shell input keyevent 控制按键输入的数值(收藏版)
  7. 基于神念TGAM的脑波小车(1)
  8. Atitit 项目高扩展法 目录 1. 提升语言级别 1 1.1. 脚本化 dsl化 免编译 2 1.2. 提升语言级别到4gl 2 1.3. 语言的代际关系 sql 》script 》java 2
  9. STM32CubeMX——固件库下载以及安装
  10. 一篇想要获取积分的博
  11. python基础之排列组合以及正则表达式
  12. java人民币金额大写_[求助]用java实现整数转换为人民币金额大写的功能
  13. 计算机教学说课稿,计算机教学说课稿
  14. 茶颜悦色的“雷”早已埋下
  15. 【装机吧】Win7电脑系统32位和64位区别(详细版)
  16. H5打造属于自己的视频播放器(JS篇1)
  17. java android 打地鼠_android实现打地鼠游戏
  18. java ts_TS与JAVA相互调用(TS篇)
  19. 简单的网页布局实战(表格与HTML框架)
  20. 支付宝小程序编译打包时, 使用tnpm安装依赖可能导致上传时构建失败,请使用 \tnpm i --by=yarn\ 安装依赖

热门文章

  1. ElasticSearch 全文搜索引擎的查询详解①(Ubuntu版 v6.6.2)
  2. MySQL数据库联合索引的命中规则
  3. Android addr2line和 c++filt使用(三十六)
  4. 电话拨号界面 android,仿安卓手机拨号界面按键特效
  5. 使用docker安装部署kibana
  6. Web实现:页面底部栏实例
  7. 【自动控制原理】稳定性分析
  8. 也来总结反省职业生涯
  9. plsql安装与配置
  10. 置顶信息(不仅修改数据库,也完成了前台效果)