介紹
Zuul的路由功能在上一篇博客中已經寫過了,這篇主要是寫下zuul 的過濾器怎麼用
zuul的過濾器功能負責對請求的處理結果進行干預,可實現請求校驗等功能,每一個進入Zuul的Http請求都會經過一系列的過濾器處理鏈得到請求響應並返回給客戶端。
Zuul實現的過濾器主要包含4個基本特徵,過濾類型,執行順序,執行條件,具體操作。這些其實就是在ZuulFilter接口中定義的4個抽象方法
boolean shouldFilter();
Object run() throws ZuulException;
public abstract String filterType();
public abstract int filterOrder();
他們各自的含義與功能如下:
filterType: 該方法返回一個字符串來代表過濾器的類型,在Zuul中默認定義了4中生命週期的過濾器類型
- pre: 可以在請求被路由之前調用
- routeing: 在路由請求時被調用
- post: 在routeing和error過濾器之後被調用
- error: 處理請求時發生錯誤時被調用
filterOrder: 通過int值來定義過濾器的執行順序,數值越小優先級越高
shouldFilter: 返回一個boolean值來判斷該過濾器是否要執行
run:過濾器的具體邏輯。在該函數中,我們可以實現自定義的過濾邏輯,來確定是否要攔截當前請求,不對其進行後續的路由,或是在請求路由返回結果之後,對處理結果做一些加工等。
請求的聲明週期
外部http請求到達api網關服務的時候,首先它會進入第一個階段pre,在這裏它會被pre類型的過濾器進行處理。該類型過濾器的主要目的是在進行請求路由之前做一些前置加工,比如請求的校驗等。在完成了pre類型的過濾器處理之後,請求進入第二個階段routing,也就是之前說的路由請求轉發階段,請求將會被routing類型的處理器處理。這裏的具體處理內容就是將外部請求轉發到具體服務實例上去的過程,當服務實例請求結果都返回之後,routing階段完成,請求進入第三個階段post。此時請求將會被post類型的過濾器處理,這些過濾器在處理的時候不僅可以獲取到請求信息,還能獲取到服務實例的返回信息,所以在post類型的過濾器中,我們可以對處理結果進行一些加工或轉換等內容。另外,還有一個特殊的階段error,該階段只有在上述三個階段中發生異常的時候纔會觸發,但是它的最後流向還是post類型的過濾器,因爲它需要通過post過濾器將最終結果返回給請求客戶端(對於error過濾器的處理,在spring cloud zuul的過濾鏈中實際上有一些不同)
實現一個簡單的請求鑑權過濾器
1.在zuul項目中創建一個Filter:該filter作用是判斷請求參數中是否含有accessToken,如果沒有,則不對其進行路由,且直接返回錯誤
public class AccessFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
System.out.println("send " + request.getMethod() + " request to "+ request.getRequestURL().toString());
String accessToken = request.getParameter("accessToken");
if (accessToken == null) {
// 令zuul過濾該請求,不對其進行路由
ctx.setSendZuulResponse(false);
//設置響應狀態碼
ctx.setResponseStatusCode(401);
//如果返回的有中文,那麼一定要設置編碼類型,否則會返回???
ctx.getResponse().setCharacterEncoding("UTF-8");
ctx.setResponseBody("access token is empty哈哈");
return null;
}
System.out.println("access token ok");
return null;
}
}
2.添加Bean
@Bean
public AccessFilter accessFilter() {
return new AccessFilter();
}
擴展
通過zuul過濾器,大致可以實現以下功能
1.通過pre類型過濾器,可實現請求鑑權
2.通過post類型過濾器+error過濾器,可實現全局異常處理
3.通過post類型過濾器,可實現返回數據的統一格式處理