最近在倒腾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>