pre過濾器——PreDecorationFilter


PreDecorationFilter

PreDecorationFilter屬於pre最重要的過濾器,基本的路由轉發配置,請求修飾都在這里完成。

執行條件:

RequestContext的實例中不包含"forward.to"並且不包含“serviceId”時執行

實際上這2個值都是此過濾器執行后才會添加到RequestContext的實例中;一般情況下正常請求中是不帶這2個參數的

所以此過濾器的執行條件是:已經被此過濾器處理過的請求不會再次處理

/***/
public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return !ctx.containsKey("forward.to") && !ctx.containsKey("serviceId");
    }

 接下來我們進入run方法了解具體的執行邏輯。

/***/
public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        /**使用UrlPathHelper處理請求參數中的url*/
        String requestURI = this.urlPathHelper.getPathWithinApplication(ctx.getRequest());
        /**根據url與配置信息做匹配,找到對應的路由route;路由規則匹配*/
        Route route = this.routeLocator.getMatchingRoute(requestURI);
        String location;
        String xforwardedfor;
        String remoteAddr;
        /**判斷是否配有路由*/
        if (route != null) {
            /**獲取路由的地址:服務名或真實物理地址*/
            location = route.getLocation();
            /**path:配置中表示請求的匹配路徑*/
            if (location != null) {
                ctx.put("requestURI", route.getPath());
                ctx.put("proxy", route.getId());
                /**判斷是否添加敏感頭信息*/
                if (!route.isCustomSensitiveHeaders()) {
                    this.proxyRequestHelper.addIgnoredHeaders((String[])this.properties.getSensitiveHeaders().toArray(new String[0]));
                } else {
                /***/   
            this.proxyRequestHelper.addIgnoredHeaders((String[])route.getSensitiveHeaders().toArray(new String[0])); } /**判斷是否重試*/ if (route.getRetryable() != null) { ctx.put("retryable", route.getRetryable()); } /**判斷路由地址是服務名還是真實物理地址*/ if (!location.startsWith("http:") && !location.startsWith("https:")) { /**是否是轉發*/ if (location.startsWith("forward:")) { ctx.set("forward.to", StringUtils.cleanPath(location.substring("forward:".length()) + route.getPath())); ctx.setRouteHost((URL)null); return null; } /***/ ctx.set("serviceId", location); ctx.setRouteHost((URL)null); ctx.addOriginResponseHeader("X-Zuul-ServiceId", location); } else { ctx.setRouteHost(this.getUrl(location)); ctx.addOriginResponseHeader("X-Zuul-Service", location); } /**是否添加代理的頭信息*/ if (this.properties.isAddProxyHeaders()) { this.addProxyHeaders(ctx, route); xforwardedfor = ctx.getRequest().getHeader("X-Forwarded-For"); remoteAddr = ctx.getRequest().getRemoteAddr(); /***/ if (xforwardedfor == null) { xforwardedfor = remoteAddr; } else if (!xforwardedfor.contains(remoteAddr)) { xforwardedfor = xforwardedfor + ", " + remoteAddr; } ctx.addZuulRequestHeader("X-Forwarded-For", xforwardedfor); } /***/ if (this.properties.isAddHostHeader()) { ctx.addZuulRequestHeader("Host", this.toHostHeader(ctx.getRequest())); } } } else { /**Route為null,進行相應的fallback處理*/ log.warn("No route found for uri: " + requestURI); xforwardedfor = this.dispatcherServletPath; if (RequestUtils.isZuulServletRequest()) { log.debug("zuulServletPath=" + this.properties.getServletPath()); location = requestURI.replaceFirst(this.properties.getServletPath(), ""); log.debug("Replaced Zuul servlet path:" + location); } else { log.debug("dispatcherServletPath=" + this.dispatcherServletPath); location = requestURI.replaceFirst(this.dispatcherServletPath, ""); log.debug("Replaced DispatcherServlet servlet path:" + location); } if (!location.startsWith("/")) { location = "/" + location; } /***/ remoteAddr = xforwardedfor + location; remoteAddr = remoteAddr.replaceAll("//", "/"); ctx.set("forward.to", remoteAddr); } return null; }

從上可以,看出,preDecorationFilter主要是做路由轉發前的配置信息,將配置文件中的信息提取出來添加到請求域RequestContext中。

preDecorationFilter首先做的就是路由規則的匹配Route route = this.routeLocator.getMatchingRoute(requestURI);

然后就是根據配置文件配置的信息進行相應的處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM