在同一个项目中间,如果既用到servlet有用了struts2的框架,运行项目时可能无法正常使用servlet,会出现404报错。如下显示:
原因: 是在配置struts2的核心控制器时<url-pattern>/*</url-pattern>所致,需要定义一个过滤器,将servlet过滤,使struts2的核心控制器对servlet不起作用。
PS(重要):在xml文件中定义的servlet过滤器要写在struts2核心控制器前面,否则还是不能使用。
举例来说,定义的过滤器文件是放在filters包下的ReDispatcherFilter.java,只需复制如下代码就可以搞定。
ReDispatcherFilter.java
package filters;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
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 ReDispatcherFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException
{
System.out.println(" filter beginning...........");
HttpServletRequest request = (HttpServletRequest)req;
String target = request.getRequestURI();
target = target.lastIndexOf("?")>0
?target.substring(target.lastIndexOf("/")+1,target.lastIndexOf("?")-target.lastIndexOf("/"))
:target.substring(target.lastIndexOf("/")+1);
System.out.println(target);
for(int i=0;i<this.includes.size();i++)
System.out.println(this.includes.get(i));
if(this.includes.contains(target))
{
System.out.println("includes.contains(target) is true");
RequestDispatcher rdsp = request.getRequestDispatcher(target);
System.out.println("go..............."+rdsp);
rdsp.forward(req, resp);
}
else
chain.doFilter(req, resp);
}
private ArrayList<String> includes = new ArrayList<String>();
public void init(FilterConfig config) throws ServletException {
this.includes.addAll( Arrays.asList(config.getInitParameter("includeServlets").split(",")));
}
}
web.xml中的配置
* 该类ReDispatcherFilter.java是定义了一个过滤器,当既用到struts2又用到servlet时,必须用该过滤器对所有的servlet做一次过滤,否 则servlet将无法正常运行。
* (重要强调)web.xml中配置顺序的问题,正确的顺序是:1 servlet核心控制器 2 所创的过滤器 3 配置struts2的核心控制器
* 在web.xml中,在定义struts的核心控制器前面添加该过滤器,添加的过滤器代码如下:
*用//注释的在配置时候记得删掉,否则会报错
<filter>
<filter-name>redisp</filter-name>
<filter-class>filters.ReDispatcherFilter</filter-class> //(该过滤器的类名,.前面为所创的包)
<init-param>
<param-name>includeServlets</param-name>
<param-value>SendCodeServlet,dengluServlet</param-value>//所有配置的servlet名字(例如SendCodeServlet,dengluServlet等)
</init-param>
</filter>
<filter-mapping>
<filter-name>redisp</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<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></web-app>
完成配置后运行:
希望能够帮到大家