Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的,ZuulFilter是过滤器的顶级父类。其中有四个非常重要的方法,我们自定义过滤器,需要重写他们。
public abstract ZuulFilter implements IZuulFilter{
abstract public String filterType();
abstract public int filterOrder();
boolean shouldFilter();// 来自IZuulFilter
Object run() throws ZuulException;// IZuulFilter
}
解释:
shouldFilter:返回一个`Boolean`值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
run:过滤器的具体业务逻辑。
filterType:返回字符串,代表过滤器的类型。包含以下4种:
pre:请求在被路由之前执行
routing:在路由请求时调用
post:在routing和errror过滤器之后调用
error:处理请求时发生错误调用
filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。
-
error
:处理请求时发生错误调用 -
filterOrder
:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。 -
shouldFilter
:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。 -
run
:过滤器的具体业务逻辑。 -
filterType
:返回字符串,代表过滤器的类型。包含以下4种: -
pre
:请求在被路由之前执行 -
routing
:在路由请求时调用 -
post
:在routing和errror过滤器之后调用 -
error
:处理请求时发生错误调用 -
filterOrder
:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高
示例LoginFilter.java
package com.example.filters;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
public class LoginFilter extends ZuulFilter {
/**
* 指定该Filter的类型
* ERROR_TYPE = "error";
* POST_TYPE = "post";
* PRE_TYPE = "pre";
* ROUTE_TYPE = "route";
*/
@Override
public String filterType() {
return PRE_TYPE;
}
/**
* 指定该Filter执行的顺序(Filter从小到大执行)
* DEBUG_FILTER_ORDER = 1;
* FORM_BODY_WRAPPER_FILTER_ORDER = -1;
* PRE_DECORATION_FILTER_ORDER = 5;
* RIBBON_ROUTING_FILTER_ORDER = 10;
* SEND_ERROR_FILTER_ORDER = 0;
* SEND_FORWARD_FILTER_ORDER = 500;
* SEND_RESPONSE_FILTER_ORDER = 1000;
* SIMPLE_HOST_ROUTING_FILTER_ORDER = 100;
* SERVLET_30_WRAPPER_FILTER_ORDER = -2;
* SERVLET_DETECTION_FILTER_ORDER = -3;
*/
@Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER - 1;
}
/**
* 指定需要执行该Filter的规则
* 返回true则执行run()
* 返回false则不执行run()
*/
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String requestUrl = request.getRequestURL().toString();
// 请求URL内不包含login或join则需要经过该过滤器,即执行run()
return !requestUrl.contains("login") && !requestUrl.contains("join");
}
/**
* 该Filter具体的执行活动
*/
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
HttpSession httpSession = request.getSession();
// 若session中不包含userId,则这次请求视为未登录请求,不给予路由,而提示“请登录”
if (httpSession.getAttribute("userId") == null) {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(200);
// 为使得中文字符不乱码
ctx.getResponse().setCharacterEncoding("UTF-8");
ctx.setResponseBody("请登录");
}
return null;
}
}
SpringcloudZuulApplication.java中需要包含以下代码即可使该Filter生效
@Bean
public LoginFilter loginFilter() {
return new LoginFilter();
}