zuul的核心是一系列的filters, 其作用可以类比Servlet框架的Filter,或者AOP,本文我们就来具体介绍下自定义的zuul过滤器
创建一个普通的SpringBoot项目项目
注意添加zuul的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
修改application.properties文件
spring.application.name=zuul-gateway-filter
server.port=9020
# eureka注册中心配置
eureka.client.serviceUrl.defaultZone=http://dpb:123456@eureka1:8761/eureka/,http://dpb:123456@eureka2:8761/eureka/
创建自定义的过滤器,继承自ZuulFilter并重写相关的方法
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
/**
* 自定义网关过滤器
* @author dengp
*
*/
@Component
public class LogFilter extends ZuulFilter{
private Logger logger = LoggerFactory.getLogger(LogFilter.class);
/**
* 过滤方法
*/
@Override
public Object run() {
// 获取Request上下文
RequestContext rc = RequestContext.getCurrentContext();
HttpServletRequest request = rc.getRequest();
logger.info("LogFilter .... 请求的路径是{},请求提交的方式是{}", request.getRequestURL().toString(),request.getMethod());
return null;
}
/**
* 是否开启过滤:默认false
*/
@Override
public boolean shouldFilter() {
// TODO Auto-generated method stub
return true;
}
/**
* 多个过滤器中的执行顺序,数值越小,优先级越高
*/
@Override
public int filterOrder() {
// TODO Auto-generated method stub
return 0;
}
/**
* 过滤器的类型
*/
@Override
public String filterType() {
// TODO Auto-generated method stub
return "pre";
}
}
启动一个provider服务后,启动我们的网关服务,然后请求访问,查询控制台输出.
注意控制台:
日志有输出,说明自定义的网关过滤器执行了。
网关过滤器的自定义方法有四个,过滤器的类型有四个,分别如下:
zuul的生命周期要结合我们上面介绍的过滤器的类型来分析,具体如下图:
网关过滤器是如何拦截不合法的请求的呢?我们来看下具体的代码
/**
* 过滤方法
*/
@Override
public Object run() {
// 获取Request上下文
RequestContext rc = RequestContext.getCurrentContext();
HttpServletRequest request = rc.getRequest();
String token = request.getParameter("token");
if(token == null){
// 拦截请求
////代表请求结束。不在继续向下请求
rc.setSendZuulResponse(false);
//添加一个响应的状态码
rc.setResponseStatusCode(401);
//响应内容
rc.setResponseBody("{\"result\":\"token is null\"}");
//响应类型
rc.getResponse().setContentType("text/json;charset=utf-8");
}
// 放过请求
return null;
}
不加参数访问失败:
添加参数:
过滤器类型相同的会根据filterOrder方法的返回结果的大小来排序,不同类型根据类型的特点执行。
我们需要创建类型为error的网关过滤器
@Component
public class ErrorFilter extends ZuulFilter{
private Logger logger = LoggerFactory.getLogger(ErrorFilter.class);
/**
* 过滤方法
*/
@Override
public Object run() {
// 获取Request上下文
RequestContext rc = RequestContext.getCurrentContext();
HttpServletRequest request = rc.getRequest();
logger.info("LogFilter .... 请求的路径是{},请求提交的方式是{}", request.getRequestURL().toString(),request.getMethod());
return null;
}
/**
* 是否开启过滤:默认false
*/
@Override
public boolean shouldFilter() {
// TODO Auto-generated method stub
return true;
}
/**
* 多个过滤器中的执行顺序,数值越小,优先级越高
*/
@Override
public int filterOrder() {
// TODO Auto-generated method stub
return 0;
}
/**
* 过滤器的类型
*/
@Override
public String filterType() {
// TODO Auto-generated method stub
return "error";
}
}
/**
* 对异常响应内如处理
* @author Administrator
*
*/
@RestController
public class ExceptionHandler implements ErrorController {
@Override
public String getErrorPath() {
return "/error";
}
@RequestMapping(value="/error")
public String error(){
return "{\"result\":\"500 error!!!!\"}";
}
}