Zuul
網關過濾器(學習筆記2020.3.16)
前言:
過濾器是
Zuul
的核心組件,Zuul
大部分功能都是通過過濾器來實現的。Zuul
中定義了四種標準過濾器類型,這些過濾器類型對應於請求的典型生命週期! 學習這些過濾器,我們可以自定義一些過濾器來進行統一過濾功能, 例如: 統一驗證token
,統一驗證參數等等!
Zuul
中定義了四種標準過濾器類型
過濾器中參數說明:
filterType
:過濾器的類型,它決定過濾器在請求的哪個生命週期中執行。
pre
—這種過濾器在請求被路由之前調用。我們可利用這種過濾器實現身份驗證、token驗證等。route
—這種過濾器在路由發送請求時候被調用。這種過濾器用於構建發送給微服務的請求,並使用 ApacheHttpClient
或Netfilx Ribbon
請求微服務。post
—在route
和error
過濾器之後被調用, 這種過濾器可用來爲響應添加標準的 HTTP Header、收集統計信息和指標、將響應從微服務發送給客戶端等。error
—在其他階段發生錯誤時執行該過濾器。
filterOrder
:過濾器的執行順序。當請求在一個階段中存在多個過濾器時,需要根據該方法返回的值來依次執行, 數字越大,優先級越低。
shouldFilter
:判斷該過濾器是否需要被執行。直接返回了true
,因此該過濾器對所有請求都會生效執行。實際運用中我們可以利用該函數來指定過濾器的有效範圍是否執行。
run
:過濾器的具體邏輯。這裏通過ctx.setSendZuulResponse(false)
令zuul過濾該請求,不對其進行路由,然後通過ctx.setResponseStatusCode(401)
設置了其返回的錯誤碼,當然我們也可以進一步優化返回,比如,通過ctx.setResponseBody(body)
對返回body內容進行編輯等。
Zuul
中默認實現的 Filter
類型 | 順序 | 過濾器 | 功能 |
---|---|---|---|
pre | -3 | ServletDetectionFilter | 標記處理 Servlet 的類型 |
pre | -2 | Servlet30WrapperFilter | 包裝 HttpServletRequest 請求 |
pre | -1 | FormBodyWrapperFilter | 包裝請求體 |
route | 1 | DebugFilter | 標記調試標誌 |
route | 5 | PreDecorationFilter | 處理請求上下文供後續使用 |
route | 10 | RibbonRoutingFilter | serviceId 請求轉發 |
route | 100 | SimpleHostRoutingFilter | url 請求轉發 |
route | 500 | SendForwardFilter | forward 請求轉發 |
post | 0 | SendErrorFilter | 處理有錯誤的請求響應 |
post | 1000 | SendResponseFilter | 處理正常的請求響應 |
如果需要禁用Zuul
過濾器
Spring Cloud的Zuul在代理和服務器模式下默認啓用了多個
ZuulFilter
bean。有關啓用的可能過濾器,請參閱zuul過濾器包。如果要禁用它,只需設置zuul...disable=true
。按照慣例,filters
之後的包是Zuul
過濾器類型。例如,禁用org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter
設置zuul.SendResponseFilter.post.disable=true
一: 實現一個簡單的過濾器!
來過濾器請求頭中沒有帶有
Authorization
的請求
/**
* @Author:
* @Date: 2020/3/16 17:23
* @Description: 網關過濾,沒有帶有Authorization的請求
* @Versions 1.0
**/
@Component //注意要註冊bean到框架纔會生效
public class MyZuulFilter extends ZuulFilter {
@Override//什麼類型的過濾器
public String filterType() {
return "pre";
}
@Override //過濾器優先級,數字越大,優先級越低。
public int filterOrder() {
return -4;
}
@Override //是否需要執行該過濾器
public boolean shouldFilter() {
return true;
}
@Override //過濾器執行的主要邏輯
public Object run() throws ZuulException {
//獲取當前請求上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//獲取請求對象
HttpServletRequest request = currentContext.getRequest();
//獲取請求頭
String authorization = request.getHeader("Authorization");
if (null != authorization){
//有請求頭就放行
return null;
}
//爲空攔截請求
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("你沒有擁有此權限");
//獲取響應對象
HttpServletResponse response = currentContext.getResponse();
//設置沒有權限碼
response.setStatus(404);
//設置響應格式
response.setContentType("text/html;charset=UTF-8");
return null;
}
}
到此就簡單實現了個判斷是否有請求頭的自定義
zuul
過濾器, //注意要註冊bean到框架纔會生效
RequestContext
zuul提供的請求上下文API
(點擊打開查詢)
未完待續