前文回顾:
Spring Cloud(一)Eureka Server-单体及集群搭建
Spring Cloud(二) 配置Eureka Client
一.执行流程
Filter是Zuul的核心,用来实现对外服务的控制。Filter的生命周期有4个,分别是“PRE”、“ROUTING”、“POST”、“ERROR”,整个生命周期可以用下图来表示。
Zuul大部分功能都是通过过滤器来实现的。Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。
-
PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
-
ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
-
POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
-
ERROR:在其他阶段发生错误时执行该过滤器。
二.自定义Filter
我们假设有这样一个场景,因为服务网关应对的是外部的所有请求,为了避免产生安全隐患,我们需要对请求做一定的限制,比如请求中含有Token便让请求继续往下走,如果请求不带Token就直接返回并给出提示。
在上一篇博客的Zuul项目中添加如下内容:
1.自定义TokenFilter
public class TokenFilter extends ZuulFilter {
private final Logger logger = LoggerFactory.getLogger(TokenFilter.class);
@Override
public String filterType() {
// 可以在请求路由之前被调用
return "pre";
}
@Override
public int filterOrder() {
// filter执行顺序,通过数字指定 ,优先级为0,数字越大,优先级越低
return 0;
}
@Override
public boolean shouldFilter() {
// 是否执行该过滤器,此处为true,说明需要过滤
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
logger.info("--->>> TokenFilter {},{}", request.getMethod(), request.getRequestURL().toString());
// 获取请求的参数
String token = request.getParameter("token");
if (StringUtils.isNotBlank(token)) {
// 对请求进行路由
ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
ctx.set("isSuccess", true);
return null;
} else {
// 不对其进行路由
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(400);
ctx.setResponseBody("token is empty");
ctx.set("isSuccess", false);
return null;
}
}
}
2.在启动类中添加Bean
@Bean
public TokenFilter tokenFilter() {
return new TokenFilter();
}
3.测试
依次启动 spring-cloud-eureka
、 spring-cloud-producer
、gateway-service-zuul-eureka
访问:http://localhost:8888/producer/hello?name=yfy
返回:token is empty
添加token参数,再次访问:http://localhost:8888/producer/hello?name=yfy&token=test
返回:hello yfy,welcome to Spring Cloud