在struts2框架中有一些它所需要的公共的靜態(tài)內(nèi)容,比如說js文件和一些css文件。當(dāng)框架需要這些靜態(tài)內(nèi)容的時候,F(xiàn)ilterDidpatcher會自動提供給我們。那么FilterDidpatcher是如何知道我們在請求靜態(tài)內(nèi)容的呢?任何請求只要以“/struts/”開頭,那么FilterDidpatcher就會認(rèn)為它是在請求靜態(tài)內(nèi)容。在識別出請求是請求靜態(tài)資源后FilterDidpatcher如何去匹配尋找靜態(tài)資源呢?這里有兩個關(guān)鍵點(diǎn):
1.確定所要請求的資源路徑。FilterDidpatcher會截取/struts/后面的內(nèi)容作為所要請求的資源。比如說現(xiàn)在請求是/struts/xhtml/styles.css,那么FilterDidpatcher就會把xhtml/styles.css作為我們所要請求的資源的路徑:xhtml目錄下面的styles.css文件。
2.到哪兒去尋找所請求的靜態(tài)內(nèi)容。默認(rèn)情況下FilterDidpatcher會隨意的org.apache.struts2.static和template這兩個包中去尋找。如果我們還想在別的其它包中尋找靜態(tài)內(nèi)容的話,那就需要在web.xml配置中FilterDidpatcher時,給它添加一個參數(shù)”packages”,然后把它的值設(shè)置為一系列以逗號或者空格分隔的包名,如下面所示:
1
2
3
4
5
6
7
8
9
10
11
12
|
< filter > < filter-name >Struts2</ filter-name > < filter-class >org.apache.struts2.dispatcher.FilterDispatcher</ filter-class > < init-param > < param-name >packages</ param-name > < param-value >com.mangocity.static,hust.cm</ param-value > </ init-param > </ filter > < filter-mapping > < filter-name >Struts2</ filter-name > < url-pattern >/*</ url-pattern > </ filter-mapping > |
描述:web應(yīng)用下有一個目錄“static”,現(xiàn)在要訪問其中的“top.html”文件,即訪問“localhost:8080/static/top.html”,服務(wù)器總是抱404錯誤。
原因:在struts2的FilterDispatcher類的doFilter方法中,如果請求的是靜態(tài)資源,struts2會判斷該請求是否可以處理,這里的代碼如下:
Java代碼
1
2
3
4
5
6
7
8
9
10
11
12
|
String resourcePath = RequestUtils.getServletPath(request); if ( "" .equals(resourcePath) && null != request.getPathInfo()) { resourcePath = request.getPathInfo(); } if (staticResourceLoader.canHandle(resourcePath)) { staticResourceLoader.findStaticResource(resourcePath, request, response); } else { // this is a normal request, let it pass through chain.doFilter(request, response); } // The framework did its job here return ; |
其中,在DefaultStaticContentLoader類的canHandle方法中會對請求路徑進(jìn)行判斷:
Java代碼
1
2
3
4
|
public boolean canHandle(String resourcePath) { return serveStatic && (resourcePath.startsWith( "/struts" ) || resourcePath.startsWith( "/static" )); } |
這里,serveStatic的值為true,再加上要訪問的資源以“/static”開頭,所以這里返回true。
然后,會進(jìn)入DefaultStaticContentLoader類的findStaticResource方法,該方法的第一行語句是:
Java代碼
1
|
String name = cleanupPath(path); |
這里,cleanupPath方法的定義如下:
Java代碼
1
2
3
4
5
6
7
8
|
/** * @param path requested path * @return path without leading "/struts" or "/static" */ protected String cleanupPath(String path) { //path will start with "/struts" or "/static", remove them return path.substring( 7 ); } |
struts2把“/static”截掉了,這樣,后面再進(jìn)行解析的時候,就變成了解析對“/top.html”的請求,所以會報(bào)404錯誤。
總結(jié)
悲劇的錯誤,還以為是自己程序的bug,改了半天。需要加強(qiáng)對開源程序中具體實(shí)現(xiàn)的了解。 希望本文所述對大家有所幫助,感謝朋友們對服務(wù)器之家網(wǎng)站的支持。
原文鏈接:http://blog.csdn.net/z69183787/article/details/48026019