其实这个问题自己以前就遇到过了但当时没有深入解决就下了定论:Servlet是不能转发到Action的。今天看到他人也有这个问题,所以特意的深入了一下也看了他人的资料。
这个问题的原因是filter默认拦截的是request,而forwardfilter是不会拦截的,所以想要想struts2拦截forward就需要配置:
<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>
<dispatcher>request</dispatcher>
<dispatcher>forward</dispatcher>
</filter-mapping>
另一个问题就是struts2的核心filter配置的是"/*"所以他会拦截所有的请求,如果你配有servlet,你的请求是会先被filter拦截的也就是会进入struts2的流程而不是servlet的,但有时你又真的需要使用的servlet(就像你要整合DWR),为了解决这种情况也有两种解决方案:
1,在struts2 core包org.apache.struts2下的default.properties:修改这个键值对struts.action.extension=action,当然我们不希望直接在这个文件里改,可以通过在struts.xml中增加常量的方式来配置
2,在web.xml里添加一个拦截器,过滤我们的Servlet。web.xml文件内容:
<!-- 自定义过滤器,过滤servlet请求。解决struts和servlet冲突问题 -->
<filter>
<filter-name>ServletFilter</filter-name>
<filter-class>org.bts.base.filter.ServletFilters</filter-class>
<init-param>
<param-name>includeServlets</param-name>
<param-value>proxool_admin</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ServletFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 定义Struts2的FilterDispathcer的Filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- FilterDispatcher用来初始化struts2并且处理所有的WEB请求 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 用于初始化Spring容器的Listener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置proxool管理工具 -->
<servlet>
<servlet-name>proxool_admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet </servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>proxool_admin</servlet-name>
<url-pattern>/proxool_admin</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>proxool</web-resource-name>
<url-pattern>/proxool_admin</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name> proxool manager Application</realm-name>
</login-config>
<security-role>
<description>
The role that is required to log in to the Manager Application
</description>
<role-name>manager</role-name>
</security-role>
<error-page>
<error-code>401</error-code>
<location>/jsp/error/401.jsp</location>
</error-page>
过滤器的实现
package org.bts.base.filter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class ServletFilters implements Filter {
private List<String> initParameters = new ArrayList<String>();
@Override
public void destroy() {
System.out.println("ServletFilters destroied!");
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String target = request.getRequestURI();
System.out.println("1: "+target);
target = target.lastIndexOf("?") > 0 ? target.substring(target
.lastIndexOf("/") + 1, target.lastIndexOf("?")
- target.lastIndexOf("/")) : target.substring(target
.lastIndexOf("/") + 1);
System.out.println("2:"+target);
if (this.initParameters.contains(target)) {
RequestDispatcher rdsp = request.getRequestDispatcher(target);
rdsp.forward(req, resp);//转发我们的请求,跳出FilterChain
} else
chain.doFilter(req, resp);
}
@Override
public void init(FilterConfig config) throws ServletException {
String parameters = config.getInitParameter("includeServlets");
System.out.println("************"+config.getFilterName()+" initing with value "+parameters+"********************");
this.initParameters.addAll(Arrays.asList(parameters.split(",")));
}
}
我个人比较倾向于第一种方法,第二种方案我没有自己测试,来源与他人的文章,使用第一种就是每次要用到action时要在请求url后面加“.action”,当然你如果使用的是struts2的标签那么他会自动加的,而且我认为有.action用来区分其他处理请求和struts的处理请求是需要的。