上篇学习了zuul路由,这边继续学习,粗糙的记录zuul过滤器的用法java
如今对请求url作个约定,在请求url上没有带参数key=123的url所有过滤掉redis
①localhost:7000/product/list?key=1234 ---不过滤算法
②localhost:7000/product/list ---过滤,不执行spring
完成以上功能,在gateway服务中,代码以下 : docker
package com.cloud.gateway.filters; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; 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; /** * 常量类 * 过滤器状态 FilterConstants * 请求状态 HttpStatus * 引用其中的属性值便可,无需本身写 */ @Component public class PreFilter extends ZuulFilter { /** * filter类型 * @return */ @Override public String filterType() { return PRE_TYPE; } /** * filter执行顺序,值越小优先级越高 * 官方推荐使用x-1方式优先排序 * @return */ @Override public int filterOrder() { return PRE_DECORATION_FILTER_ORDER - 1; } /** * filter 开启关闭 * @return */ @Override public boolean shouldFilter() { return true; } /** * 实现filter逻辑 * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext requestContext = RequestContext.getCurrentContext(); HttpServletRequest request =requestContext.getRequest(); String key=request.getParameter("key"); //若是不存在,则设置没有权限不经过,状态为401 if (StringUtils.isEmpty(key)){ requestContext.setSendZuulResponse(false); requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); } return null; } }
浏览器访问成功则返回list列表,失败则返回错误页面,错误码:401浏览器
再来实现一个post过滤器,在获得结果以后,实如今post filter阶段,返回response的,给header头部加点信息,代码以下: dom
package com.cloud.gateway.filters; 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.HttpServletResponse; import java.util.UUID; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER; /** * 常量类 * 过滤器状态 FilterConstants * 请求状态 HttpStatus * 引用其中的属性值便可,无需本身写 */ @Component public class PostFilter extends ZuulFilter { /** * filter类型 * * @return */ @Override public String filterType() { return POST_TYPE; } /** * filter执行顺序,值越小优先级越高 * 官方推荐使用x-1方式优先排序 * * @return */ @Override public int filterOrder() { return SEND_RESPONSE_FILTER_ORDER - 1; } /** * filter 开启关闭 * * @return */ @Override public boolean shouldFilter() { return true; } /** * 实现filter逻辑 * * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext requestContext = RequestContext.getCurrentContext(); HttpServletResponse response = requestContext.getResponse(); response.setHeader("POST-UUID", UUID.randomUUID().toString()); return null; } }
浏览器控制台 请求信息 : ide
写了两次, 套路也都摸清了,能写的地方也就这么几个点,后面再作 限流 操做,结合上面学的,限流作在请求filter最靠前的地方,比鉴权pre前执行,否则流量都进去了,这里须要一个算法---令牌桶算法,这个算法不少地方已经实现了,拿来用便可,意思是以必定速率将令牌放入桶中,桶中的令牌满了,就不会再放进去了,外部的请求进入,请求将得到桶中的令牌,得令牌者可通行,没有令牌请求将被拒绝post
下面代码实现 : 学习
package com.cloud.gateway.filters; import com.cloud.gateway.exceptions.RateLimiterException; import com.google.common.util.concurrent.RateLimiter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.exception.ZuulException; import org.springframework.stereotype.Component; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER; /** * 限流 */ @Component public class RateLimiterFilter extends ZuulFilter { //create 每秒放入100个令牌 private static final RateLimiter RATE_LIMITER = RateLimiter.create(100); /** * filter类型 * * @return */ @Override public String filterType() { return PRE_TYPE; } /** * filter执行顺序,值越小优先级越高 * 官方推荐使用x-1方式优先排序 * 选择最高优先级SERVLET_DETECTION_FILTER_ORDER,并-1 * * @return */ @Override public int filterOrder() { return SERVLET_DETECTION_FILTER_ORDER - 1; } /** * filter 开启关闭 * * @return */ @Override public boolean shouldFilter() { return true; } /** * 实现filter逻辑 * * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { //判断--获取通行令牌-->若是没有令牌不等于以前的没有权限401,能够抛出自定义异常或者其余处理 if (!RATE_LIMITER.tryAcquire()) { throw new RateLimiterException(); } return null; } }
自定义异常:
package com.cloud.gateway.exceptions; public class RateLimiterException extends RuntimeException { }
以上是过滤器的简单示例
还有一个Zuul关于鉴权的使用,涉及新建user服务,也会用到docker、redis,刚刚入手mac,上面什么都没有,装好了再继续下面的学习实践
---------------------------------------------------------