上次講了Zuul的基本使用,這篇講的是綜合使用,好比過濾器,限流,鑑權等應用
這裏繼續使用api-getway這個項目html
1.新建一個類,繼承ZuulFilter,細節方面看下面代碼,還有別忘了在類上加@Component註解,不然不生效git
@Component public class TokenFilter extends ZuulFilter { /** * 過濾器類型 * @return */ @Override public String filterType() { return PRE_TYPE; } /** * 優先級,數字越大,優先級越低 * 只作通常過濾,沒有特殊要求的,能夠放在內置過濾器後面 * @return */ @Override public int filterOrder() { //最後一個內置PRE過濾器後面 return PRE_DECORATION_FILTER_ORDER+1; } /** * 是否執行該過濾器,true表明須要過濾 * 這裏能夠忽略掉一些不須要過濾請求 * @return */ @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String token = request.getParameter("token"); //若是沒有token,則返回401 //這裏就不作校驗了,只判斷有無 if(StringUtils.isEmpty(token)){ ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED); ctx.setResponseBody("未登錄!"); //設置返回體的編碼爲UTF-8 HttpServletResponse response = ctx.getResponse(); response.setHeader("Content-type", "text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); } return null; } }
2.開啓Eureka Server,api-getway,service-hi項目github
3.測試
不帶token http://localhost:8900/myHi/hi算法
帶token http://localhost:8900/myHi/hi?token=123spring
1.新建一個類,繼承ZuulFilterapi
@Component public class AddResponseHeaderFilter extends ZuulFilter { @Override public String filterType() { return POST_TYPE; } @Override public int filterOrder() { //放在返回過濾器前 return SEND_RESPONSE_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { RequestContext context = RequestContext.getCurrentContext(); HttpServletResponse response = context.getResponse(); response.setHeader("my-response","hello"); return null; } }
2.開啓Eureka Server,api-getway,service-hi項目跨域
3.測試
http://localhost:8900/myHi/hi?token=123瀏覽器
限流的功能也是常常會在網關實現,咱們這裏使用令牌桶算法實現,這個算法已經有相關實現了,直接用就行緩存
令牌桶算法:一邊以一個固定的速率發令牌,另外一邊用一個固定大小的桶裝令牌,桶滿了則將令牌該令牌丟棄,不然放進桶裏。進來的請求嘗試從桶裏取令牌,取到令牌的請求放行,沒有令牌的請求則會被拒絕。以下圖cors
1.新建一個類,繼承ZuulFilter
@Component public class RateFilter extends ZuulFilter { /** * 建立令牌桶 容量爲1(爲了方便測試,這裏設置小一點) */ private static final RateLimiter RATE_LIMITER = RateLimiter.create(1); @Override public String filterType() { return PRE_TYPE; } @Override public int filterOrder() { //設置順序 請求轉發過濾器 前 return SERVLET_DETECTION_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { //獲取不到令牌 if(!RATE_LIMITER.tryAcquire()){ //TODO 跳轉到錯誤頁面或友好提示 throw new RuntimeException("訪問人數過多,請稍後再試!"); } return null; } }
2.開啓Eureka Server,api-getway,service-hi項目
3.測試
在過濾器run方法中打個斷點,而後開3個瀏覽器tag訪問http://localhost:8900/myHi/hi?token=123,進入斷點後,點擊忽略斷點,再點擊釋放斷點運行程序
結果:
至少有一個請求會被拒絕,後臺拋出異常
瀏覽器是不容許跨域訪問,一般解決跨域,可在接口類或方法加上@CrossOrigin(allowCredentials = "true"),但這種方法是很繁瑣的,不可能有100個接口就加100次,因此咱們這裏可使用Zuul實現跨域
代碼實現
@Configuration public class CorsConfig { @Bean public CorsFilter corsFilter(){ final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); //是否支持Cookie跨域 config.setAllowCredentials(true); //支持的原始域 *表示全部 config.setAllowedOrigins(Arrays.asList("*")); //容許的頭 *表示全部 config.setAllowedHeaders(Arrays.asList("*")); //容許的請求方法 POST,GET等 *表示全部 config.setAllowedMethods(Arrays.asList("*")); //緩存時間 表示300秒內對相同請求不須要再判斷 config.setMaxAge(300L); //path參數爲對哪些域名進行設置 /**表示全部 source.registerCorsConfiguration("/**",config); return new CorsFilter(source); } }
由於跨域是須要在不一樣域名下,這裏不太好演示,就不測試了。
以上3種是Zuul比較經常使用的一些使用方式,今天就到這裏,下期見~
代碼已更新至gitthub
https://github.com/zhangwenka...
若是以爲不錯,分享給你的朋友!
一個立志成大腿而天天努力奮鬥的年輕人
伴學習伴成長,成長之路你並不孤單!