本文转自:http://blog.csdn.net/liuchuanhong1/article/details/62236793

关于网关的作用,这里就不再次赘述了,我们今天的重点是zuul的Filter。通过Filter,我们可以实现安全控制,比如,只有请求参数中有用户名和密码的客户端才能访问服务端的资源。那么如何来实现Filter了?

要想实现Filter,需要以下几个步骤:

1、继承ZuulFilter类,为了验证Filter的特性,我们这里创建3个Filter

根据用户名来过滤

package com.chhliu.springcloud.zuul;  

import javax.servlet.http.HttpServletRequest;  

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext; public class AccessUserNameFilter extends ZuulFilter {
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest(); System.out.println(String.format("%s AccessUserNameFilter request to %s", request.getMethod(), request.getRequestURL().toString())); String username = request.getParameter("username");// 获取请求的参数
if(null != username && username.equals("chhliu")) {// 如果请求的参数不为空,且值为chhliu时,则通过
ctx.setSendZuulResponse(true);// 对该请求进行路由
ctx.setResponseStatusCode(200);
ctx.set("isSuccess", true);// 设值,让下一个Filter看到上一个Filter的状态
return null;
}else{
ctx.setSendZuulResponse(false);// 过滤该请求,不对其进行路由
ctx.setResponseStatusCode(401);// 返回错误码
ctx.setResponseBody("{\"result\":\"username is not correct!\"}");// 返回错误内容
ctx.set("isSuccess", false);
return null;
}
} @Override
public boolean shouldFilter() {
return true;// 是否执行该过滤器,此处为true,说明需要过滤
} @Override
public int filterOrder() {
return 0;// 优先级为0,数字越大,优先级越低
} @Override
public String filterType() {
return "pre";// 前置过滤器
}
}

通过继承ZuulFilter然后覆写上面的4个方法,就可以实现一个简单的过滤器,下面就相关注意点进行说明

filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:

  • pre:可以在请求被路由之前调用
  • route:在路由请求时候被调用
  • post:在route和error过滤器之后被调用
  • error:处理请求时发生错误时被调用

Zuul的主要请求生命周期包括“pre”,“route”和“post”等阶段。对于每个请求,都会运行具有这些类型的所有过滤器。

filterOrder:通过int值来定义过滤器的执行顺序

shouldFilter:返回一个boolean类型来判断该过滤器是否要执行,所以通过此函数可实现过滤器的开关。在上例中,我们直接返回true,所以该过滤器总是生效

run:过滤器的具体逻辑。需要注意,这里我们通过ctx.setSendZuulResponse(false)令zuul过滤该请求,不对其进行路由,然后通过ctx.setResponseStatusCode(401)设置了其返回的错误码

过滤器间的协调
    过滤器没有直接的方式来访问对方。 它们可以使用RequestContext共享状态,这是一个类似Map的结构,具有一些显式访问器方法用于被认为是Zuul的原语,内部是使用ThreadLocal实现的,有兴趣的同学可以看下源码。

再建一个过滤器,根据密码来过滤:

package com.chhliu.springcloud.zuul;  

import javax.servlet.http.HttpServletRequest;  

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext; public class AccessPasswordFilter extends ZuulFilter { @Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest(); System.out.println(String.format("%s AccessPasswordFilter request to %s", request.getMethod(), request.getRequestURL().toString())); String username = request.getParameter("password");
if(null != username && username.equals("123456")) {
ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
ctx.set("isSuccess", true);
return null;
}else{
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("{\"result\":\"password is not correct!\"}");
ctx.set("isSuccess", false);
return null;
}
} @Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
return (boolean) ctx.get("isSuccess");// 如果前一个过滤器的结果为true,则说明上一个过滤器成功了,需要进入当前的过滤,如果前一个过滤器的结果为false,则说明上一个过滤器没有成功,则无需进行下面的过滤动作了,直接跳过后面的所有过滤器并返回结果
} @Override
public int filterOrder() {
return 1; // 优先级设置为1
} @Override
public String filterType() {
return "pre";
}
}

最后建一个post过滤器

package com.chhliu.springcloud.zuul;  

import javax.servlet.http.HttpServletRequest;  

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext; public class AccessTokenFilter extends ZuulFilter {
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest(); System.out.println(String.format("%s AccessTokenFilter request to %s", request.getMethod(),
request.getRequestURL().toString())); ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
ctx.setResponseBody("{\"name\":\"chhliu\"}");// 输出最终结果
return null;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public int filterOrder() {
return 0;
} @Override
public String filterType() {
return "post";// 在请求被处理之后,会进入该过滤器
}
}

2、在主类中,先开启前面的两个过滤器

3、输入请求,验证

(1)请求为:http://localhost:8768/h2service/user/1?username=chhliu

测试结果为:

{"result":"password is not correct!"}

控制台打印结果

  1. GET AccessUserNameFilter request to http://localhost:8768/h2service/user/1
  2. GET AccessPasswordFilter request to http://localhost:8768/h2service/user/1

通过了AccessUserNameFilter过滤器,在验证AccessPasswordFilter过滤器的时候失败了

后台无sql打印,说明请求没有被路由

(2)请求为:http://localhost:8768/h2service/user/1?password=123456

测试结果为:

{"result":"username is not correct!"}

控制台打印结果:

  1. GET AccessUserNameFilter request to http://localhost:8768/h2service/user/1

说明到了AccessUserNameFilter过滤器,但是没有到AccessPasswordFilter过滤器,因为AccessUserNameFilter过滤器的优先级高一些,会先执行,在执行的时候,发现过滤条件不符合,于是跳过了后面所有的过滤器,并返回结果

后台无sql打印,说明请求没有被路由

(3)请求为:http://localhost:8768/h2service/user/1?password=123456&username=chhliu

测试结果为:

控制台打印的结果:

  1. GET AccessUserNameFilter request to http://localhost:8768/h2service/user/1
  2. GET AccessPasswordFilter request to http://localhost:8768/h2service/user/1

说明是先执行了AccessUserNameFilter然后才执行AccessPasswordFilter这也和我们前面说的order的值越小,优先级越高是吻合的。

同时被请求的服务有sql输出:

Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.balance as balance3_0_0_, user0_.name as name4_0_0_, user0_.username as username5_0_0_ from user user0_ where user0_.id=?  

说明请求被路由了。

4、开启post过滤器,再跑一次

测试结果:发现post过滤器是最后执行的,尽管它的优先级为0

关于zuul的Filter的生命周期,见下图

注:上图有个小错误,routing应该是route

5、拓展

zuul还提供了一类特殊的过滤器,分别为:StaticResponseFilter和SurgicalDebugFilter

StaticResponseFilter:StaticResponseFilter允许从Zuul本身生成响应,而不是将请求转发到源。

SurgicalDebugFilter:SurgicalDebugFilter允许将特定请求路由到分隔的调试集群或主机。

spring cloud-zuul的Filter详解(十一)的更多相关文章

  1. Spring Cloud Zuul 限流详解(附源码)(转)

    在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud中如何实现限流. 在 Zuul 上实现限流是个不错的选择,只需要编写一个过滤器就可以了,关键在于如何实现限流的算法. ...

  2. Spring Cloud(十二):Spring Cloud Zuul 限流详解(附源码)(转)

    前面已经介绍了很多zuul的功能,本篇继续介绍它的另一大功能.在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud中如何实现限流. 在 Zuul 上实现限流是个不错的选 ...

  3. Spring Cloud Zuul之ZuulFilter详解

    简介 Spring Cloud Zuul网关在整个微服务体系中肩负对外开放接口.请求拦截.路由转发等作用,其核心处理则是ZuulFilter ZuulFilter部分源码 Zuul Filter全部继 ...

  4. Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式。

    时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...

  5. Zuul之Filter详解

    Zuul详解 官方文档:https://github.com/Netflix/zuul/wiki/How-it-Works Zuul的中心是一系列过滤器,能够在HTTP请求和响应的路由过程中执行一系列 ...

  6. 笔记:Spring Cloud Ribbon 客户端配置详解

    自动化配置 由于 Ribbon 中定义的每一个接口都有多种不同的策略实现,同时这些接口之间又有一定的依赖关系,Spring Cloud Ribbon 中的自动化配置能够很方便的自动化构建接口的具体实现 ...

  7. Spring Cloud Eureka 常用配置详解,建议收藏!

    前几天,栈长分享了 <Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版!>,今天来分享下 Spring Cloud Eureka 常用的一些参数配置及说 ...

  8. Spring Cloud(十一):Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式

    上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制,但其实Zuul还有更多的应用场景,比如:鉴权.流量转发.请求统计等等,这些功能都可以使用Zuul来实现. Zuul的核心 Filter是Zuu ...

  9. spring cloud深入学习(十二)-----Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式

    Zuul的核心 Filter是Zuul的核心,用来实现对外服务的控制.Filter的生命周期有4个,分别是“PRE”.“ROUTING”.“POST”.“ERROR”,整个生命周期可以用下图来表示. ...

  10. Spring Cloud学习 之 Spring Cloud Hystrix(使用详解)

    文章目录 创建请求命令: 定义服务降级: 异常处理: 异常传播: 异常获取: 命令名称,分组以及线程池划分: 创建请求命令: ​ Hystrix命令就是我们之前说的HystrixCommand,它用来 ...

随机推荐

  1. head和tail命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/amosli/p/3496027.html 当要查看上千行的大文件时,我们可不会用cat命令把整个文件内容给打印出来,相 ...

  2. 插件使用-HighChart

    一.介绍 让数据可视化更简单,兼容 IE6+.完美支持移动端.图表类型丰富.方便快捷的 HTML5 交互性图表库. 官网(英):https://www.highcharts.com/download ...

  3. nodejs的Cannot find module 'body-parser'

    http://blog.csdn.net/u014345860/article/details/77769253

  4. 初学Cocos2dx

    初学cocos2dx Cocos2dx 中的主要概念包括:应用.导演.场景.层.精灵.动画.动作. Cocos2dx里面的主要类 1.CCObject Object Object Object 是co ...

  5. 文件上传到tomcat服务器 commons-fileupload的详细介绍与使用

    三个类:DiskFileUpload.FileItem和FileUploadException.这三个类全部位于org.apache.commons.fileupload包中. 首先需要说明一下for ...

  6. 第二次作业利用java语言编写计算器进行四则运算

    随着第一次作业的完成,助教 牛老师又布置了第二次作业:用java语言编写一个程序然后进行四则运算用户用键盘输入一个字符来结束程序显示统计结果.一开始看到这个题目我也着实吓了一跳 因为不知道如何下手而且 ...

  7. Struts1简单开发流程梳理

    共享数据的4种范围MVC设计模式JSP model1.JSP model2struts实现MVC机制(ActionServlet.Action)struts-config.xml ActionServ ...

  8. [Cnbeta]龙芯处理器性能怎么样

    龙芯处理器性能怎么样?下一代CPU同频性能可达英特尔90% 在高性能处理器领域,英特尔是天花顶一般的存在(先不算地位特殊的IBM公司),国内发展CPU处理器的公司很多,绝大多数实力跟英特尔相比都差很远 ...

  9. PHP开发网站,你是如何提高其网站的安全性的?

    一.网站程序问题 很多网站的安全问题大多是由于网站程序存在漏洞,所以想要提高网站安全性,必须要选择安全的后台cms系统,若有能力可以自己去开发网站后台,这样安全性能得到极大的提高,若是从网上选择一些免 ...

  10. 微信小程序组件 自定义弹出框

    <!-- 点击立即抢拼弹出框 --> <view class='add-rob' bindtap="setModalStatus" data-status=&qu ...