Zuul過濾器介紹和自定義過濾器

1、zuul的大部分功能都是通過過濾器進行。zuul定義四種標準的過濾器類型,這四種過濾器應用在請求生命週期的不同時期。

pre過濾器,它在請求被zuul路由之前調用。一般用來實現身份驗證、在集羣中的選擇請求的微服務、記錄調試信息等

routing過濾器,它將請求路由到微服務。一般用於構建發送請求到微服務,並使用apache的httpclient或者ribbon進行請求微服務。

post過濾器,這種過濾器是路由到微服務之後執行,相當於後置過濾器。這種過濾器可爲請求響應的時候添加標準的http header,收集統計信息、將響應從微服務發給客戶端等,簡單地說,就是請求處理後,響應給客戶端的時候,會調用這個過濾器。

error過濾器,在其他過濾器階段,發生錯誤的時候,會執行該過濾器,相當於在執行其他過濾器的時候,出現error會被error過濾器捕獲。

當然也可以自定義過濾器,後續再寫個自定義過濾器進行學習。

查看源碼,zuul過濾器定義在org.springframework.cloud.netflix.zuul.filters包下,這些過濾器默認包含了三種不同的生命週期,pre、routing、post。

自定義過濾器,需要繼承ZuulFilter,重寫filterType、filterOrder、shouldFilter、run方法

filterType:代表自定義過濾器的類型,值有pre、route、post、error

pre:可以在請求被路由之前調用
route:在路由請求時候被調用
post:在route和error過濾器之後被調用
error:處理請求時發生錯誤時被調用

filterOrder:用來代表過濾器的執行順序,越小越先被執行,int值

shouldFilter:返回boolean值來判斷該過濾器是否被執行,true表示該過濾器生效,false反之

run:過濾器的具體處理邏輯,根據shouldFilter的返回值判斷是否執行,true則會執行run方法,false則不會

這裏自定義RouteFilter

package com.etc.zuul.filter;

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 java.util.Enumeration;
import java.util.Map;

/**
 * 過濾器
 */
@Component
public class RouteFilter extends ZuulFilter {

    /**
     * 設置過濾器類型爲前置過濾器
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 設置過濾器順序,越小越先執行
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 設置過濾器是否生效,返回true則需要權限校驗,
     * 返回false則不需要權限校驗
     * @return
     */
    @Override
    public boolean shouldFilter() {
        //獲取上下文對象
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        Map<String, String[]> map = request.getParameterMap();
        String contentType = request.getContentType();
        int contentLength = request.getContentLength();
        //獲取請求uri,對uri進行訪問判斷
        String uri = request.getRequestURI();
        if("/webreq/error/htp".equalsIgnoreCase(uri)){
            return true;
        }
        return false;
    }

    /**
     * 業務邏輯,只有shouldFilter返回true,
     * 纔會進入該方法
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {

        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        //jwt的token,可以用請求頭傳過來,也可以用參數傳過來,一般是用請求頭傳遞
        String token = request.getHeader("token");
        System.out.println("=================請求頭信息=================");
        //請求頭信息
        Enumeration<String> headersMap = request.getHeaderNames();
        while (headersMap.hasMoreElements()){
            String headerName = (String)headersMap.nextElement();
            String headerVal =request.getHeader(headerName);
            System.out.println(headerName+":"+headerVal);
        }
        if(StringUtils.isEmpty(token)){
            //過濾掉該路由,不對它進行路由
            requestContext.setSendZuulResponse(false);
            //返回錯誤代碼
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

發佈了238 篇原創文章 · 獲贊 30 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章