Spring Cloud(Dalston.SR5)--Zuul 网关-过滤器
Spring Cloud 为 HTTP 请求的各个阶段提供了多个过滤器,这些过滤器的执行顺序由各自提供的一个 int 值决定,提供的值越小则优先级越高,默认的过滤器及优先级如下:

自定义过滤器
在默认过滤器的基础上,我们可以实现自己的自定义过滤器,自定义过滤器需要继承 com.netflix.zuul.ZuulFilter 类,并实现相关方法,说明如下:
- filterType:该函数需要返回一个字符串来代表过滤器的类型,而这个类型就是在HTTP请求过程中定义的各个阶段。在Zuul中默认定义了四种不同生命周期的过滤器类型,具体如下:
- pre:可以在请求被路由之前调用
- routing:在路由请求时候被调用
- post:在routing和error过滤器之后被调用
- error:处理请求时发生错误时被调用
- filterOrder:通过int值来定义过滤器的执行顺序,数值越小优先级越高
- shouldFilter:返回一个boolean类型来判断该过滤器是否要执行。我们可以通过此方法来指定过滤器的有效范围。
- run:过滤器的具体逻辑。在该函数中,我们可以实现自定义的过滤逻辑,来确定是否要拦截当前的请求,不对其进行后续的路由,或是在请求路由返回结果之后,对处理结果做一些加工等
Zuul 默认定义了四个不同的过滤器类型,它们覆盖了一个外部HTTP请求到达API网关,直到返回请求结果的全部生命周期。下图源自Zuul的官方WIKI中关于请求生命周期的图解,它描述了一个HTTP请求到达API网关之后,如何在各个不同类型的过滤器之间流转的详细过程如下:

我们可以看到,当外部 HTTP 请求到达 API 网关服务的时候,首先它会进入第一个阶段 pre,在这里它会被pre 类型的过滤器进行处理,该类型的过滤器主要目的是在进行请求路由之前做一些前置加工,比如请求的校验等。
在完成了 pre 类型的过滤器处理之后,请求进入第二个阶段 routing,也就是之前说的路由请求转发阶段,请求将会被 routing 类型过滤器处理,这里的具体处理内容就是将外部请求转发到具体服务实例上去的过程,当服务实例将请求结果都返回之后,routing 阶段完成,请求进入第三个阶段 post,此时请求将会被 post 类型的过滤器进行处理,这些过滤器在处理的时候不仅可以获取到请求信息,还能获取到服务实例的返回信息,所以在 post 类型的过滤器中,我们可以对处理结果进行一些加工或转换等内容。
另外,还有一个特殊的阶段error,该阶段只有在上述三个阶段中发生异常的时候才会触发,但是它的最后流向还是post类型的过滤器,因为它需要通过post过滤器将最终结果返回给请求客户端。
过滤器示例
- 验证过滤器
该过滤器会在 pre 阶段执行,并且其优先级为 1 在包装请求体后执行,其 shouldFilter 返回 true 表示任何情况都执行该过滤器,在 run 方法通过获取 HttpServletRequest 示例获取请求参数并进行验证,在验证失败的时候通过设置 HttpServletResponse 示例和 setSendZuulResponse(false) 来直接返回响应信息,而不进行后续过滤器处理。
package org.lixue.zuul;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TokenPreZullFilter extends ZuulFilter{
@Override
public String filterType(){
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder(){
return 1;
}
@Override
public boolean shouldFilter(){
return true;
}
@Override
public Object run(){
RequestContext ctx=RequestContext.getCurrentContext();
HttpServletRequest request=ctx.getRequest();
System.out.println(String.format("%s request to %s",request.getMethod(),request.getRequestURL().toString()));
String token=request.getParameter("token");
System.out.println("token:"+token);
if(token==null||!token.equals("success_token")){
//认证失败
System.out.println("token验证失败");
HttpServletResponse response=ctx.getResponse();
response.setCharacterEncoding("utf-8");//设置字符集
response.setContentType("text/html;charset=utf-8");//设置相应格式
response.setStatus(401);
ctx.setSendZuulResponse(false);//不进行路由
try{
response.getWriter().write("token验证失败");//响应体
}catch(IOExceptione){
System.out.println("responseio异常");
e.printStackTrace();
}
ctx.setResponse(response);
return null;
}
System.out.println("token验证成功");
return null;
}
}
- 过滤器配置类
为了让 Spring 容器知道过滤器的存在,需要对该类进行配置,创建过滤器配置类,使用注解 @Configuration 标注类,并使用 @Bean 注解标注返回过滤器的方法。
package org.lixue.zuul;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ZuulFilterConfiguration{
@Bean
public TokenPreZullFilter tokenPreZullFilter(){
return newTokenPreZullFilter();
}
}
- 测试验证
项目依赖一个 eureka-sserver、service-provider 服务,首先启动 eureka-server 和 service-provider 服务,然后启动 spring-cloud-zuul-microservices 服务,访问 http://localhost:9200/hello/speaks?names=123&token=success_token 地址,可以看到能正常返回,如下:
{"123":"Hello World 123 Port=8080"}
修改访问地址,移除 token 参数或者修改参数值 http://localhost:9200/hello/speaks?names=123&token=success_token999 这时会返回 token 验证失败的错误,并且没有执行后续的路由处理。
Spring Cloud(Dalston.SR5)--Zuul 网关-过滤器的更多相关文章
- Spring Cloud(Dalston.SR5)--Zuul 网关-微服务集群
通过 url 映射的方式来实现 zuul 的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了.实际上在实现微服务架构时,服务名与服务实例地 ...
- Spring Cloud(Dalston.SR5)--Zuul 网关-路由配置
Spring Cloud 在 Zuul 的 routing 阶段实现了几个过滤器,这些过滤器决定如何进行路由工作. 简单路由(SimpleHostRoutingFilter) 该过滤器运行后,会将 H ...
- Spring Cloud(Dalston.SR5)--Zuul 网关
我们使用 Spring Cloud Netflix 中的 Eureka 实现了服务注册中心以及服务注册与发现:而服务间通过 Ribbon 或 Feign 实现服务的消费以及均衡负载:使用Hystrix ...
- Spring Cloud(Dalston.SR5)--Zuul 网关-Hystrix 回退
当我们对网关进行配置让其调用集群的服务时,将会执行 Ribbon 路由过滤器,该过滤器在进行转发时会封装为一个 Hystrix 命令予以执行,Hystrix 命令具有容错的功能,如果"源服务 ...
- Spring Cloud(Dalston.SR5)--Config 集群配置中心
Spring Cloud Config 是一个全新的项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,他分为服务端和客户端两个部分.服务端也称为分布式配置中心,是一个独立的微服务 ...
- Spring Cloud Dalston.SR5 BUG一记
使用Dalston.SR5版本的Zuul时, 发现Ribbon重试不能切换服务实例, 换成Edgware.SR3,同样的配置可以切换实例进行重试 还有个不升级所有Spring Cloud组件的方法,仅 ...
- Spring Cloud(Dalston.SR5)--Config 集群配置中心-刷新配置
远程 SVN 服务器上面的配置修改后,需要通知客户端来改变配置,需要增加 spring-boot-starter-actuator 依赖并将 management.security.enabled 设 ...
- Spring Cloud(Dalston.SR5)--Hystrix 监控
在服务调用者加入 Actuator ,可以对服务调用者的健康情况进行实时监控,例如,断路器是否打开.当前负载情况等. 服务调用者 需要增加 actuator依赖, 修改 POM.xml 中增加以下依赖 ...
- Spring Cloud(Dalston.SR5)--Feign 与 Hystrix 断路器整合
创建项目 要使 Feign 与 Hystrix 进行整合,我们需要增加 Feign 和 Hystrix 的依赖,修改 POM.xml 中增加以下依赖项如下: <?xmlversion=" ...
随机推荐
- Java基础恶补——内存泄露、内存溢出
http://blog.csdn.net/wisgood/article/details/16818243
- react-thunk的使用流程
react-thunk作用:使我们可以在action中返回函数,而不是只能返回一个对象.然后我们可以在函数中做很多事情,比如发送异步的ajax请求. 这就是react-thunk的使用方法.接受一个d ...
- day20_python_1124
01 昨日内容回顾 类的名称空间 对象的空间 class A: def __init__(): pass obj = A() 对象查询属性:对象本身 ----> 类 -----> 父类 类 ...
- 3D打印GCODE文件学习(一)
我家有一个天威的入门级的3D打印机.它有一个配套的软件叫“Rrint-RiteCoLiDo Repetier-Host V1.5.5”,用来连接.控制打印机.同时它可以加载各种切片软件,对各种3D模型 ...
- day37-多进程多线程二-锁
Lock组件 当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,如果两个文件同时进行,肯定是不行的,必须是文件写结束以后,才可以进行读操作.或者是多个进程在共享一些资源的时候,同 ...
- Forth 采用Create,Does>定义新的词(word)& 延迟词技术
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- jsp九大内置对象 ,三大指令,四大作用域,七大动作
九大内置对象: application:应用程序对象 对整个web工程都有效 request:对当前请求的封装 pageConfig:只对当前页面有效,里面封装了基本request和session的对 ...
- top 常用
top -c 查看进程 同时 shift +m 内存倒序
- Java语法基础学习DayEleven(Map)
一.Map接口 1.概述:Map与Collection并列存在,用于保存具有映射关系的数据Key-Value. Map接口 |- - - - -HashMap:Map的主要实现类 |- - - - - ...
- 自动化测试-7.selenium定位一组对象
前言 前面的几篇都是讲如何定位一个元素,有时候一个页面上有多个对象需要操作,如果一个个去定位的话,比较繁琐,这时候就可以定位一组对象. webdriver 提供了定位一组元素的方法,跟前面八种定位方式 ...