Java Web開發中(zhōng),自定義過濾器(qì)被執行兩次的原因分析及解決辦法 - 新聞資(zī)訊 - 雲南小程序開發|雲南軟件開發|雲南網站(zhàn)建設-西山區知普網絡科技工作室

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不管是網站(zhàn),軟件還是小程序,都要直接或間接能為您産生價值,我們在追求其視覺表現的同時,更側重于功能的便捷,營銷的便利,運營的高效,讓網站(zhàn)成為營銷工具,讓軟件能切實提升企業(yè)内部管理水平和(hé)效率。優秀的程序為後期升級提供便捷的支持!

您當前位置>首頁 » 新聞資(zī)訊 » 網站(zhàn)建設 >

Java Web開發中(zhōng),自定義過濾器(qì)被執行兩次的原因分析及解決辦法

發表時間:2012-6-8

發布人:葵宇科技

浏覽次數:36

本文(wén)出處:http://blog.csdn.net/chaijunkun/article/details/7646338,轉載請注明。由于本人不定期會整理相關(guān)博文(wén),會對相應内容作出完善。因此強烈建議在原始出處查看此文(wén)。
在Java Web開發過程中(zhōng),我們可(kě)以使用過濾器(qì)和(hé)Spring框架提供的攔截器(qì)來對請求進行處理,從而實現對整個(gè)Web應用的權限控制。在這裡我簡單介紹一下(xià)我在使用過濾器(qì)實現權限驗證方面的經驗。
過濾器(qì)作為傳統的Web開發技術(shù),不受使用了第三方框架的束縛,所有符合标準的Servlet容器(qì)都支持這項技術(shù)。URL字符編碼過濾器(qì)是我們經常使用的,而權限控制過濾器(qì)則是過濾器(qì)輕量級應用的常見場景。目前我所開發的一個(gè)項目中(zhōng)就使用了這項技術(shù),然而在開發時遇到了過濾器(qì)被調用了兩次的問(wèn)題,下(xià)面說一下(xià)我的配置:

在web.xml中(zhōng)我指定了過濾器(qì):

<!--權限過濾器(qì) -->
	<filter>
		<filter-name>permissionFilter</filter-name>
		<filter-class>blog.csdn.net.chaijunkun.PermissionFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>permissionFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

下(xià)面是過濾器(qì)的實現代碼:

package blog.csdn.net.chaijunkun;

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 org.apache.log4j.Logger;

public class PermissionFilter implements Filter {

	private Logger logger= Logger.getLogger(PermissionFilter.class);

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain filterChain) throws IOException, ServletException {
		HttpServletRequest request= (HttpServletRequest) req;
		    logger.info("過濾器(qì)被調用");
		    filterChain.doFilter(request, resp);
		}
		
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
	}

}

結果當我訪問(wèn)了一個(gè)接口後,在控制台顯示了兩條“過濾器(qì)被調用”的提示。後來在網上尋找原因,偶然看到了有人問(wèn)同樣的問(wèn)題:http://topic.csdn.net/u/20110930/22/d8741022-53eb-4df1-ace0-357f6edabee1.html
按照“xiaobluesky”說的方法,打印了一下(xià)請求的URL地址:System.out.println(request.getRequestedURI());
發現兩次打印的内容不一樣:
第一次打印的是我請求的Servlet,第二次打印的是/favicon.ico,此時才恍然大悟,很多浏覽器(qì)都支持“站(zhàn)點圖标”的功能。例如(rú)我當前正在編輯這篇文(wén)章,使用的是Chrome浏覽器(qì),标簽頁上就顯示了一個(gè)這樣的CSDN的圖标:

CSDN圖标

根據規範,這個(gè)圖标的位置就是在站(zhàn)點根目錄下(xià),命名也必須為favicon.ico。
過濾器(qì)被執行兩次的情況僅限于使用Servlet容器(qì)既提供靜态訪問(wèn)支持、又提供動(dòng)态訪問(wèn)支持的情況,當采用動(dòng)靜态分離(lí)的場合(例如(rú)apache+tomcat,apache将靜态請求攔截自己處理,tomcat隻處理動(dòng)态内容),這種問(wèn)題自然而然就消失了,因為該請求不會到達Servlet容器(qì)。


既然知道了原理,解決起來就好辦了,寫幾個(gè)正則表達式,按照requestURI的規劃進行合理的分配,不同的訪問(wèn)URL采用不同的權限過濾機制即可(kě)。但是這種方法并不能阻止doFilter方法被調用兩次,隻是代碼在按照我們指定的請求邏輯上運行。也許,這就是過濾器(qì)的不足之處。


也許寫到這裡你(nǐ)會問(wèn),為什麼在web.xml配置文(wén)件中(zhōng)url-pattern一定要寫成"/*"這種形式呢(ne)?寫成“/*.do”這種形式不是更好麼?我又何嘗不想這樣呢(ne),查了資(zī)料并實踐後才知道,這樣寫是不符合JSR-315規範的。有興趣的朋友可(kě)以參閱帖子(zǐ):
http://topic.csdn.net/u/20100525/12/41569c26-350b-45f9-abc0-2019cbb4641b.html
讀一下(xià)JSR 315 12.2 節的原文(wén)

相關(guān)案例查看更多