Struts1与Struts2一起使用时遇到的问题解决方案

本篇记录工作中遇到的问题。

项目用的是Struts1,但因为要用到一个ActiveX插件,(当时用的是Struts2开发,因为涉及到一些文件上传,插件开发者不是本人,所以没办法改成Struts1),因为在项目中额外加入了Sruts2的配置。
只要Struts1和Struts2处理类和请求不一样,还是可以兼容的。

但是遇到了一个问题,就是用Struts1做的功能里,所有的文件上传都报空指针,但用FireBug分析了下上传请求,发现POST里都是有该文件的,但后台就是接收不到。

于是想到,是不是Struts2先拦截了该文件呢?(具体的处理流程当时我并不是很清楚)。
首先检查了下配置:

1、web.xml项目用的是Struts1的配置,如下:
<!-- 配置ActionServlet,加载Struts配置文件 -->
<servlet>
	<servlet-name>action</servlet-name>
	<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
	<init-param>
		<param-name>config</param-name>
		<param-value>/WEB-INF/struts-config.xml,/WEB-INF/struts-config-permng.xml</param-value>
	</init-param>	
	<init-param>
		<param-name>config/demo</param-name>
		<param-value>/WEB-INF/struts-config-demo.xml</param-value>
	</init-param>	
	<init-param>
		<param-name>debug</param-name>
		<param-value>2</param-value>
	</init-param>
	<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>action</servlet-name>
	<url-pattern>*.ered</url-pattern>
</servlet-mapping>


2、web.xml ---- Struts2的配置如下:
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>
			org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
	</filter-class>
	<init-param>
	    <param-name>config</param-name>
	    <param-value>struts-default.xml,struts-plugin.xml,config/struts.xml</param-value>
	</init-param>
</filter>
	
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>


初步一看,就是最普通的配置,但看了下Struts2的配置,其中url-pattern的属性配了/*,也就是过滤器对所有的Url都有效,初步判断这里过滤了Struts1的文件。

解决办法,
将Struts2的filter-mapping中的url-pattern属性改成*.action,这样只会拦截.action的url,本来也是可以解决的。

但是,如同我上面说的,在Struts2的URL里有放置ActiveX插件,只要将Struts2的配置url-pattern改成*.action的时候,插件里的请求就无效了,直接报错。这说明插件里的URL不是以.action结尾的,但我用FireBug分析了下URL请求,并没有找到插件中的那个请求,(插件的请求方式是在JS中定义了一个Object,并写上属性ID,通过此ID调用插件中的方法)。

-----------------------------
此刻,想到了两个解决办法。
1、是不是将web.xml中的Struts1的配置放到Struts2上面,就可以先执行Struts1的部分(因为Struts1的配置并没有过滤所有,是拦截以*.ered结尾的URL。而此时,我将下面的Struts2配置重新改成/*,这样Struts1部分的文件上传和Struts2部分的插件,是否可以同时被各自的拦截器处理呢?
2、自定义个Filter,将所有的URL都拦截下来,分析下插件中未知的那个请求是什么,再改进Struts2的配置。

于是我先试验了下办法一,发现就算把Struts1的配置放上面,也还是会先运行Struts2的拦截器,后来去网上查了下原因,
是因为 Struts1的配置用的是Servlet,而Struts2的配置用的是Filter,
而两者的运行顺序是:
 Filter-> Servlet 

所以把Struts1的配置放前面,也是没有用的。

于是开始试验办法二,自定义Filter,拦截所有URL,web.xml的配置如下:
<!-- 请求拦截过滤器 -->
<filter>
	<filter-name>requestFilter</filter-name>
	<filter-class>util.RequestFilter</filter-class>
	<init-param>
		<param-name>enabled</param-name>
		<param-value>true</param-value>
	</init-param>
	</filter>
<filter-mapping>
	<filter-name>requestFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>


类里的具体方法如下:
/**
	 * 过滤处理
	 */
	public void doFilter(ServletRequest pRequest, ServletResponse pResponse, FilterChain fc) throws IOException,
			ServletException {
	HttpServletRequest request = (HttpServletRequest) pRequest;
	HttpServletResponse response = (HttpServletResponse) pResponse;
	String ctxPath = request.getContextPath();
	String requestUri = request.getRequestURI();
	String uri = requestUri.substring(ctxPath.length());
	System.out.println(url);
}


运行其结果,发现Url如下:(结构如下)
/rpt/demourl

于是终于知道,该URL是没有后缀的,所以Sturts2在配置的时候,若配置了*.action的话就会使该插件无效了。
但是发现插件的所有URL都是在
项目目录/rpt/
下的,所以找到解决办法是:
更改filter-mapping中的url-pattern属性,将/* 改为/rpt/*

问题解决。

总结:虽然可能对于高手来说不是很困难的问题,但却被我折腾了挺久,究其原因,可能是因为没好好的理解Struts1和Struts2的一些机制,平时应多看看此方面的相关书籍,慢慢积累。

参考资料:
http://www.iteye.com/problems/41978
http://blog.csdn.net/flyrainsky/article/details/7094481

你可能感兴趣的:(struts2)