如何在自定義Filter中優雅的實現靜態資源放行


         在javaweb開發中,過濾器Filter比較常用於類似登錄的攔截等場景。但是,當過濾器的配置不當時就會把所有的請求都攔截,靜態資源也會被攔截掉,導致靜態頁面加載不出來。
一般的解決方案是在過濾器代碼中對所有的靜態資源放行,但這樣硬編碼的方式特別不靈活,代碼復用性也不高。下面說個更優雅點的方案。

一、解決方案

        如果將靜態資源放行的功能做成在web.xml中可以直接配置的話,就比較方便了。因此我們可以采用配置Filter的init-param的方式來配置那些資源不需要過濾器攔截,然后在過濾器Filter中的init方法去取這個配置的init-param。 具體的還是直接上代碼吧。

二、代碼

(1)web.xml中Filter的配置代碼片段如下
        這里的重點是配置了一個init-param
  <!--身份驗證、登錄、權限-->
  <filter>
    <filter-name>authorityFilter</filter-name>
    <filter-class>com.hk.uc.client.filter.RestAuthorizeFilter</filter-class>
    <init-param>
    	<!-- 配置不需要被登錄過濾器攔截的鏈接,只支持配后綴、前綴 及全路徑,多個配置用逗號分隔 -->
    	<param-name>excludedPaths</param-name>
    	<param-value>/pages/*,*.html,*.js,*.ico</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>authorityFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
(2)自定義Filter的代碼如下
         代碼解釋如下:
      • 首先我聲明了excludedPaths用來接收web.xml中配置的init-param
      • init()方法中把init-param的值賦值給excludedPaths
      • 寫一個方法用來判斷是否是直接放行的請求,這里寫了isFilterExcludeRequest()這個方法
      • doFilter()這個方法中,先調用isFilterExcludeRequest()這個方法,判斷是否應該直接放行。如果不是直接放行才走我們的邏輯代碼
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.kangxiinfo.framework.common.util.StringUtils;

/**
 * 身份認證過濾器
 * @author ZENG.XIAO.YAN
 * @time   2018-10-19 14:07:44
 * @version  v1.0
 */
public class RestAuthorizeFilter implements Filter {
	/**
	 * 不需要被過濾器攔截的頁面 ,主要用於靜態資源的放行
	 * 在web.xml中配置filter的init-param
	 */    
	private String excludedPaths; 
	private String [] excludedPathArray;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    	// 初始化時讀取web.xml中配置的init-param
    	excludedPaths = filterConfig.getInitParameter("excludedPaths");
    	if(!StringUtils.isNullOrBlank(excludedPaths)){
    		excludedPathArray = excludedPaths.split(",");
    	}
    }
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 判斷是否是直接放行的請求
		if (!isFilterExcludeRequest(request)) {
			// TODO 這里寫你的過濾器處理邏輯
		}
        filterChain.doFilter(servletRequest, servletResponse);
    }

    
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    /**
     * 判斷是否是 過濾器直接放行的請求
     * <br/>主要用於靜態資源的放行
     * @param url
     * @return
     */
    private boolean isFilterExcludeRequest(HttpServletRequest request) {
    	if(null != excludedPathArray && excludedPathArray.length > 0) {
    		String url = request.getRequestURI();
        	for (String ecludedUrl : excludedPathArray) {
				if (ecludedUrl.startsWith("*.")) {
					// 如果配置的是后綴匹配, 則把前面的*號干掉,然后用endWith來判斷
					if(url.endsWith(ecludedUrl.substring(1))){
						return true;
					}
				} else if (ecludedUrl.endsWith("/*")) {
					if(!ecludedUrl.startsWith("/")) {
						// 前綴匹配,必須要是/開頭
						ecludedUrl = "/" + ecludedUrl;
					}
					// 如果配置是前綴匹配, 則把最后的*號干掉,然后startWith來判斷
					String prffixStr = request.getContextPath() + ecludedUrl.substring(0, ecludedUrl.length() - 1);
					if(url.startsWith(prffixStr)) {
						return true;
					}
				} else {
					// 如果不是前綴匹配也不是后綴匹配,那就是全路徑匹配
					if(!ecludedUrl.startsWith("/")) {
						// 全路徑匹配,也必須要是/開頭
						ecludedUrl = "/" + ecludedUrl;
					}
					String targetUrl = request.getContextPath() + ecludedUrl;
					if(url.equals(targetUrl)) {
						return true;
					}
				}
			}
    	}
    	return false;
    }
}

三、小結

(1)通過解決這個問題,學會了filter的init-param該怎么玩
(2)后續可以直接復用這個代碼了,靜態資源的放行直接在web.xml中配置。


免責聲明!

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



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