實際業務中,如果要自定義filter過濾器,只需集成ZuulFIlter類即可,該類是個抽象類,它實現了IZuulFIlter接口,我們需要實現幾個方法,如下示例:
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; import javax.servlet.http.HttpServletRequest; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException;
public class ThirdPreFilter extends ZuulFilter { /** * 設置filter的類型,支持4種類型 * {@link org.springframework.cloud.netflix.zuul.filters.support.FilterConstants} * <pre> * ERROR_TYPE = "error";//這種過濾器是在整個生命周期內,如果發生異常,就執行該filter,可以做全局異常處理。 * POST_TYPE = "post";//這種過濾器是在端點請求完畢,返回結果或者發生異常后執行的filter。如果需要對返回的結果進行再次處理,可以在這種過濾中處理邏輯。 * PRE_TYPE = "pre"; //在zuul網關按照規則路由到下級服務之前執行,如果需要對請求進行預處理,可以使用這種類型的過濾器。如:認證鑒權,限流等。 * ROUTE_TYPE = "route";//這種過濾器是zuul路由動作的執行者,是Apache HttpClient或Ribbon構建和發送原始HTTP請求的地方,現在也支持OKHTTP。 * </pre> * * @return */ @Override public String filterType() { return PRE_TYPE; } /** * 設置filter的執行順序,數字越小,優先級越高,反之越低 * * @return */ @Override public int filterOrder() { return 3; } /** * 是否執行該過濾器,可以作為一個開關,如果一直都被執行,直接返回true即可 * * @return */ @Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); //從上下文獲取logic-is-success值,用於判斷此Filter是否執行 return (boolean) ctx.get("logic-is-success"); } /** * 該自定義filter的業務邏輯 * * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { System.out.println("這是ThirdPreFilter!"); //從RequestContext獲取上下文 RequestContext ctx = RequestContext.getCurrentContext(); //從上下文獲取HttpServletRequest HttpServletRequest request = ctx.getRequest(); //從request嘗試獲取b參數值 String b = request.getParameter("b"); //如果b參數值為空則進入此邏輯 if (null == b) { //對該請求禁止路由,也就是禁止訪問下游服務 ctx.setSendZuulResponse(false); //設定responseBody供PostFilter使用 ctx.setResponseBody("{\"status\":500,\"message\":\"b參數為空!\"}"); //logic-is-success保存於上下文,作為同類型下游Filter的執行開關,假定后續還有自定義Filter當設置此值 ctx.set("logic-is-success", false); //到這里此Filter邏輯結束 return null; } //設置避免報空指針異常 ctx.set("logic-is-success", true); return null; } }
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.*; public class PostFilter extends ZuulFilter { @Override public String filterType() { return POST_TYPE; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { System.out.println("這是PostFilter!"); //從RequestContext獲取上下文 RequestContext ctx = RequestContext.getCurrentContext(); //處理返回中文亂碼 ctx.getResponse().setCharacterEncoding("UTF-8"); //獲取上下文中保存的responseBody String responseBody = ctx.getResponseBody(); //如果responseBody不為空,則說明流程有異常發生 if (null != responseBody) { //設定返回狀態碼 ctx.setResponseStatusCode(500); //替換響應報文 ctx.setResponseBody(responseBody); } return null; } }