最近在倒騰struts2框架,在自己打算新建servlet進行處理數據的時候,發現servlet怎麼訪問都訪問不到,看了下路徑和配置都是正確的,沒有問題,報錯如下。
HTTP Status 404 - There is no Action mapped for namespace [/] and action name [Test] associated with context path [/struts2_intercept].
看到報錯的時候有個Action和namespace,這不是struts裏面的嗎,我明明訪問的是servlet啊,怎麼會出現structs的東西呢,看了一下struts.xml也沒問題啊,然後看了下web.xml的配置,忽然恍然大悟。
我們知道,struts其實就是一個攔截器,我在給他配置url-pattern的時候習慣用/*,如下代碼。
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
//這個位置
<url-pattern>/*</url-pattern>
</filter-mapping>
struts會把路徑後面的都會默認爲是個Action行爲,所以,他會去struts.xml去匹配查找Action的name,因爲這個是servlet,肯定找不到匹配的action的name,所以,報錯說no Action。
但是,我們要解決這個問題啊,不然,怎麼訪問servlet?我們知道,我們在執行Action的時候,我們可以忽略後面的擴展名,比如,我有一個配置好Action的Test類,我們訪問的時候無論是 “路徑/Test” 還是 “路徑/Test.action”都是可以訪問的到,你看前面的那個,和我們定義的servlet沒區別,所以,無論servlet怎麼定義,都會和前面那個例子一樣,被當成Action行爲,那麼,如何去解決呢?
解決方法有兩個,既然是servlet和struts的問題,那麼,他們兩個只要有一個做出讓步,問題就可以解決。
更改 struts 配置
我們在給struts配置的時候,常常喜歡用默認配置,在默認的常量配置總有一個設置struts請求的擴展名,就是.action,默認情況有和沒有都是可以的,我們可以強制要求他使用擴展名訪問,如下常量配置,這樣,我們訪問servlet的時候,他就會認爲不是action行爲,當然,如果要訪問action的話,也必須是.action的行爲才能訪問的到。感覺這種方式會比較好一點,對於開發的時候我能很清楚的知道這個類的行爲是幹什麼的
<constant name=”struts.action.extension” value=”action” />
更改servlet配置
上面我們知道,既然是struts的action擴展名導致的出錯,那麼,我們只要設置一個讓struts識別不出來的擴展名不就行嗎?設置如下,這樣,struts在過濾的時候發現,這個帶擴展名我不認識,所以,不是我處理的訪問,過濾器不處理,直接交給服務器處理。
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>servlet.Test</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
//在這裏
<url-pattern>/Test.servlet</url-pattern>
</servlet-mapping>