介绍
Zuul的路由功能在上一篇博客中已经写过了,这篇主要是写下zuul 的过滤器怎么用
zuul的过滤器功能负责对请求的处理结果进行干预,可实现请求校验等功能,每一个进入Zuul的Http请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。
Zuul实现的过滤器主要包含4个基本特征,过滤类型,执行顺序,执行条件,具体操作。这些其实就是在ZuulFilter接口中定义的4个抽象方法
boolean shouldFilter();
Object run() throws ZuulException;
public abstract String filterType();
public abstract int filterOrder();
他们各自的含义与功能如下:
filterType: 该方法返回一个字符串来代表过滤器的类型,在Zuul中默认定义了4中生命周期的过滤器类型
- pre: 可以在请求被路由之前调用
- routeing: 在路由请求时被调用
- post: 在routeing和error过滤器之后被调用
- error: 处理请求时发生错误时被调用
filterOrder: 通过int值来定义过滤器的执行顺序,数值越小优先级越高
shouldFilter: 返回一个boolean值来判断该过滤器是否要执行
run:过滤器的具体逻辑。在该函数中,我们可以实现自定义的过滤逻辑,来确定是否要拦截当前请求,不对其进行后续的路由,或是在请求路由返回结果之后,对处理结果做一些加工等。
请求的声明周期
外部http请求到达api网关服务的时候,首先它会进入第一个阶段pre,在这里它会被pre类型的过滤器进行处理。该类型过滤器的主要目的是在进行请求路由之前做一些前置加工,比如请求的校验等。在完成了pre类型的过滤器处理之后,请求进入第二个阶段routing,也就是之前说的路由请求转发阶段,请求将会被routing类型的处理器处理。这里的具体处理内容就是将外部请求转发到具体服务实例上去的过程,当服务实例请求结果都返回之后,routing阶段完成,请求进入第三个阶段post。此时请求将会被post类型的过滤器处理,这些过滤器在处理的时候不仅可以获取到请求信息,还能获取到服务实例的返回信息,所以在post类型的过滤器中,我们可以对处理结果进行一些加工或转换等内容。另外,还有一个特殊的阶段error,该阶段只有在上述三个阶段中发生异常的时候才会触发,但是它的最后流向还是post类型的过滤器,因为它需要通过post过滤器将最终结果返回给请求客户端(对于error过滤器的处理,在spring cloud zuul的过滤链中实际上有一些不同)
实现一个简单的请求鉴权过滤器
1.在zuul项目中创建一个Filter:该filter作用是判断请求参数中是否含有accessToken,如果没有,则不对其进行路由,且直接返回错误
public class AccessFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
System.out.println("send " + request.getMethod() + " request to "+ request.getRequestURL().toString());
String accessToken = request.getParameter("accessToken");
if (accessToken == null) {
// 令zuul过滤该请求,不对其进行路由
ctx.setSendZuulResponse(false);
//设置响应状态码
ctx.setResponseStatusCode(401);
//如果返回的有中文,那么一定要设置编码类型,否则会返回???
ctx.getResponse().setCharacterEncoding("UTF-8");
ctx.setResponseBody("access token is empty哈哈");
return null;
}
System.out.println("access token ok");
return null;
}
}
2.添加Bean
@Bean
public AccessFilter accessFilter() {
return new AccessFilter();
}
扩展
通过zuul过滤器,大致可以实现以下功能
1.通过pre类型过滤器,可实现请求鉴权
2.通过post类型过滤器+error过滤器,可实现全局异常处理
3.通过post类型过滤器,可实现返回数据的统一格式处理