虽然现在大多数的项目都采用了 sturts2的架构,但是不可避免的有时候要跟旧项目模块的servlet合并共存。
但是我们会发现 当servlet单独存在时,采用<form name="form1" method="post" action="MessagesAction?action=loginRoom">时可以跳转运行的。
加入到sturts2架构后,会报错:
HTTP Status 404 - There is no Action mapped for namespace / and action nameMessagesAction
因为struts2会拦截一切来自浏览器的请求。struts2把servlet当成action了,因为servlet和action都是没有后缀的.
解决方法目前有四种:
index.jsp
<form name="form1" method="post" action="MessagesAction.servlet?action=loginRoom">
package com.cheney.chat; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Random; import java.util.Vector; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; public class MessagesAction extends HttpServlet { /** * Constructor of the object. */ public MessagesAction() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
<servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>MessagesAction</servlet-name> <servlet-class>com.cheney.chat.MessagesAction</servlet-class> </servlet> <servlet-mapping> <servlet-name>MessagesAction</servlet-name> <url-pattern>/MessagesAction.servlet</url-pattern> </servlet-mapping>
(比较通用奥):
在struts.xml中的<struts>的节点下面添加struts2处理的请求后缀 常量:
<!--
该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理。
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。
-->
<constant name="struts.action.extension" value="action" />
jsp页面上 使用到action的地方 比如 login 变成 login.action
在web.xml中修改struts2拦截页面请求的配置:
原:
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/user/*</url-pattern> </filter-mapping>
自定义filter对servlet进行过滤:
##############################################
# 该类是定义了一个过滤器(随便你放在哪个包下面),当既用到struts2有用到servlet时,
# 必须用该过滤器对所有的servlet做一次过滤,否则servlet将无法正常运行。
# 同时在web.xml中,在定义struts的核心控制器的过滤器前面添加该过滤器,添加代码如下:
* <filter>
* <filter-name>redisp</filter-name>
* <filter-class>filters.ReDispatcherFilter(该过滤器的类名)</filter-class>
* <init-param>
* <param-name>includeServlets</param-name>
* <param-value>所配置的servlet,注意是那url-pattern</param-value>
* </init-param>
* </filter>
* <filter-mapping>
* <filter-name>redisp</filter-name>
* <url-pattern>/*</url-pattern>
* </filter-mapping>
*该类也可以直接继承StrutsPrepareAndExecuteFilter的
###########################################################
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 { 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); if(this.includes.contains(target)) { 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(","))); } }
<filter> <filter-name>redisp</filter-name> <filter-class> com.xheditor.servlet.ReDispatcherFilter</filter-class> <init-param> <param-name>includeServlets</param-name> <param-value>UploadFileServlet</param-value> </init-param> </filter> <filter-mapping> <filter-name>redisp</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- struts2拦截页面请求的配置 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- servlet的配置 --> <servlet> <servlet-name>ImageServlet</servlet-name> <servlet-class>com.servlets.ImageServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>ImageServlet</servlet-name> <url-pattern>/myImageServlet/*</url-pattern> </servlet-mapping>