接上篇博客:https://blog.csdn.net/SpringCYB/article/details/90236037
上篇忘说路由器的路径配置了,实现过滤功能之前我们先把路径配置讲解一下:
一:zuul路径配置
1.改造一下zuul项目的yml文件:
2.然后消费者的yml配置文件改成,刚刚创建的api-a他就会找到实例名为下图的 order-consumer1 消费者
3.依次启动eureka项目,然后启动consumer项目。
4.然后我们再次修改zuul项目的yml文件,为了模拟多台消费者启动的情况,记得设置idea项目并行启动,上篇博客有设置方法
5.接下里再次修改consumer项目yml配置文件
然后再次启动consumer项目,最后启动zuul项目
6.打开PostMan测试:
这是指定api-a的消费者:
换成第二个:
注意输出信息的端口号,是不是发生了改变呢,这样就只能通过我们设置的路径才可以访问了。上篇博客的轮循效果也就消失了。
二:服务过滤
zuul他不仅只是路由,并且还能过滤,做一些安全验证。我们继续来改造工程。
我们先在zuul项目创建一个filter包,然后创建OneFilter类实现过滤功能
这个类他需要我们去继承一个 ZuulFilter 类,重写里面的四个方法,具体实现来看代码!
package com.jk.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
// 注意两点:
// 1. 添加注解@Component
// 2. shouldFilter方法,返回值为true
@Component // 标识zuul过滤器配置类
public class OneFilter extends ZuulFilter {
@Override
public String filterType() {
/*
filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:
pre:路由之前
routing:路由之时
post: 路由之后
error:发送错误调用
*/
return "pre";
}
@Override
public int filterOrder() {
return 0; // 过滤的顺序 : 数字越小优先级越高
}
@Override
public boolean shouldFilter() {
// false: 不执行过滤器,默认为false
// true: 执行过滤器
// 此方法可以添加业务逻辑判断是否执行过滤器
return true;
}
@Override
public Object run() throws ZuulException {
//过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问
// 获取RequestContext对象 ,操作request的上下文
RequestContext cxt = RequestContext.getCurrentContext();
// 通过RequestContext获取HttpServletRequest对象
HttpServletRequest request = cxt.getRequest();
System.out.println("执行过滤器。。。。。。。");
System.out.println("请求地址:" + request.getRequestURL());
System.out.println("请求方式:" + request.getMethod());
//逻辑判断,我们不妨设置一下,如果你访问方法的时候没有传入参数
//那我们就给他返回状态400,并提示"name is null"
//如果传入了key那么就让他成功访问!这就是过滤设置!
String name = request.getParameter("name");
if(null == name){
cxt.setSendZuulResponse(false);
cxt.setResponseStatusCode(400);
try {
cxt.getResponse().getWriter().write("name is null");
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
我们重新启动zuul项目,PostMan测试:
由于我们并未传入key,所以他提示我们设置的"name is null";
我们传入key来试试:
访问成功!这就是过滤功能的实现,他会过滤你所有的方法。Filter类可以创建多个,一般是创建四个,根据
@Override
public int filterOrder() {
return 0; // 过滤的顺序 : 数字越小优先级越高
}
重写方法中的filterOrder中return的值来规定优先级顺序。
来吧,我们验证下,在创建一个TwoFilter类
package com.jk.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
@Component
public class TwoFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
System.out.println("这是第二个过滤器。。。");
return null;
}
}
我们把刚刚OneFilter类中的filterOrder方法中return的值改成1
重启zuul项目看看,然后PostMan测试
打印台:
看到了么,首先执行 TwoFilter ,因为他的优先级(filterOrder方法中return的值为0)高于 OneFilter(filterOrder方法中return的值原来是0我们后来改为了1)
这就是过滤功能的实现。