Zuul
网关过滤器(学习笔记2020.3.16)
前言:
过滤器是
Zuul
的核心组件,Zuul
大部分功能都是通过过滤器来实现的。Zuul
中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期! 学习这些过滤器,我们可以自定义一些过滤器来进行统一过滤功能, 例如: 统一验证token
,统一验证参数等等!
Zuul
中定义了四种标准过滤器类型
过滤器中参数说明:
filterType
:过滤器的类型,它决定过滤器在请求的哪个生命周期中执行。
![8JHaM4.jpg](https://i-blog.csdnimg.cn/blog_migrate/5022901ff5229ac3b134aa73f78737e8.jpeg)
pre
—这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、token验证等。route
—这种过滤器在路由发送请求时候被调用。这种过滤器用于构建发送给微服务的请求,并使用 ApacheHttpClient
或Netfilx Ribbon
请求微服务。post
—在route
和error
过滤器之后被调用, 这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。error
—在其他阶段发生错误时执行该过滤器。
filterOrder
:过滤器的执行顺序。当请求在一个阶段中存在多个过滤器时,需要根据该方法返回的值来依次执行, 数字越大,优先级越低。
shouldFilter
:判断该过滤器是否需要被执行。直接返回了true
,因此该过滤器对所有请求都会生效执行。实际运用中我们可以利用该函数来指定过滤器的有效范围是否执行。
run
:过滤器的具体逻辑。这里通过ctx.setSendZuulResponse(false)
令zuul过滤该请求,不对其进行路由,然后通过ctx.setResponseStatusCode(401)
设置了其返回的错误码,当然我们也可以进一步优化返回,比如,通过ctx.setResponseBody(body)
对返回body内容进行编辑等。
Zuul
中默认实现的 Filter
类型 | 顺序 | 过滤器 | 功能 |
---|---|---|---|
pre | -3 | ServletDetectionFilter | 标记处理 Servlet 的类型 |
pre | -2 | Servlet30WrapperFilter | 包装 HttpServletRequest 请求 |
pre | -1 | FormBodyWrapperFilter | 包装请求体 |
route | 1 | DebugFilter | 标记调试标志 |
route | 5 | PreDecorationFilter | 处理请求上下文供后续使用 |
route | 10 | RibbonRoutingFilter | serviceId 请求转发 |
route | 100 | SimpleHostRoutingFilter | url 请求转发 |
route | 500 | SendForwardFilter | forward 请求转发 |
post | 0 | SendErrorFilter | 处理有错误的请求响应 |
post | 1000 | SendResponseFilter | 处理正常的请求响应 |
如果需要禁用Zuul
过滤器
Spring Cloud的Zuul在代理和服务器模式下默认启用了多个
ZuulFilter
bean。有关启用的可能过滤器,请参阅zuul过滤器包。如果要禁用它,只需设置zuul...disable=true
。按照惯例,filters
之后的包是Zuul
过滤器类型。例如,禁用org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter
设置zuul.SendResponseFilter.post.disable=true
一: 实现一个简单的过滤器!
来过滤器请求头中没有带有
Authorization
的请求
/**
* @Author:
* @Date: 2020/3/16 17:23
* @Description: 网关过滤,没有带有Authorization的请求
* @Versions 1.0
**/
@Component //注意要注册bean到框架才会生效
public class MyZuulFilter extends ZuulFilter {
@Override//什么类型的过滤器
public String filterType() {
return "pre";
}
@Override //过滤器优先级,数字越大,优先级越低。
public int filterOrder() {
return -4;
}
@Override //是否需要执行该过滤器
public boolean shouldFilter() {
return true;
}
@Override //过滤器执行的主要逻辑
public Object run() throws ZuulException {
//获取当前请求上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//获取请求对象
HttpServletRequest request = currentContext.getRequest();
//获取请求头
String authorization = request.getHeader("Authorization");
if (null != authorization){
//有请求头就放行
return null;
}
//为空拦截请求
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("你没有拥有此权限");
//获取响应对象
HttpServletResponse response = currentContext.getResponse();
//设置没有权限码
response.setStatus(404);
//设置响应格式
response.setContentType("text/html;charset=UTF-8");
return null;
}
}
到此就简单实现了个判断是否有请求头的自定义
zuul
过滤器, //注意要注册bean到框架才会生效
RequestContext
zuul提供的请求上下文API
(点击打开查询)
未完待续