org.apache.struts.action.Action类是Struts的心脏,也是客户请求和业务操作间的桥梁。每个Action类通常设计为代替客户完成某种操作。
一旦正确的Action实例确定,就会调用RequestProcessor类的execute()方法。该方法的结构如下: //摘自org.apache.struts.action.Action类 public ActionForward execute(ActionMapping mapping, ActionForm form,ServletRequest request,ServletResponse response) throws Exception { try { return execute(mapping, form,(HttpServletRequest) (Object) request,(HttpServletResponse) (Object) response); } catch (ClassCastException e) { return null; } } public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,HttpServletResponse response) throws Exception { return null; }
在Struts应用程序中,具体的Action子类需要扩展Action类,以提供execute()方法的实现。execute()方法有四个参数:ActionMapping对象,ActionForm对象,HttpServletRequest对象和HttpServletResponse对象。ActionForm对象封装了表单数据,因此Action类可以通过getter方法从该对象中获得表单数据,然后调用模型组件处理这些数据。Action类又通过ActionMapping对象的findForward()方法获得一个ActionForward对象,然后把处理结果转发到ActionForward对象所指的目标。
Action示例: package struts.action; import java.util.ArrayList; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import model.LoginHandler; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.DynaActionForm; import struts.form.LoginHandlerForm; public class LoginHandlerAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { LoginHandlerForm loginHandlerForm = (LoginHandlerForm) form; //从Form中取得表单数据 String userName = loginHandlerForm.getUserName(); String userPwd = loginHandlerForm.getUserPwd(); //生成一个Session对象 HttpSession session = request.getSession(true); session.removeAttribute("userName"); session.setAttribute("userName", userName); //生成一个ArrayList ArrayList arr = new ArrayList(); arr.add(userName); arr.add(userPwd); String forward; //调用模型组件 LoginHandler login = new LoginHandler(); boolean flag = login.checkLogin(arr); if(flag) forward = "success"; else forward = "fail"; //转向 return mapping.findForward(forward); }}
ActionMapping存储了与特定用户请求对应的特定Action的相关信息,例如输入页面,转发页面等。ActionServlet将ActionMapping传送到Action类的execute()方法,然后Action将调用ActionMapping的findForward()方法,此方法返回一个指定名称的ActionForward,这样Action就完成了本地转发。若没有找到具体的ActionForward,就返回一个null。ActionMapping类的源代码如下:
package org.apache.struts.action; import java.util.ArrayList; import org.apache.struts.config.ActionConfig; import org.apache.struts.config.ForwardConfig; public class ActionMapping extends ActionConfig { public ActionForward findForward(String name) { ForwardConfig config = this.findForwardConfig(name); if (config == null) config = this.getModuleConfig().findForwardConfig(name); return (ActionForward) config; } public String[] findForwards() { ArrayList results = new ArrayList(); ForwardConfig[] fcs = this.findForwardConfigs(); for (int i = 0; i < fcs.length; i++) results.add(fcs[i].getName()); return (String[]) results.toArray(new String[results.size()]); } public ActionForward getInputForward() { if (this.getModuleConfig().getControllerConfig().getInputForward()) return findForward(this.getInput()); return new ActionForward(this.getInput()); }}
ActionForward类从以上的Action类的讨论中可知,execute()方法返回一个ActionForward对象。ActionForward对象代表一个Web资源的逻辑抽象表示形式。这里的Web资源通常就是JSP页面或Java Servlet。ActionForward是该资源包的包装类,所以应用程序和实际资源之间并无多少瓜葛。实际的Web资源只在配置文件struts-config.xml中指定,并非在程度代码中写入。RequestDispatcher会根据redirect属性的值,来决定ActionForward实例要进行转发还是重定向。要从一个Action实例返回一个ActionForward实例,可以在Action类内动态地创建一个ActionForward实例,或者更常见的做法是使用ActionMapping的findForward()方法找出配置文件中预先配置的一个ActionForward实例,如下所示:return mapping.findForward("Success");其中,mapping是一个ActionMapping实例。该程序片断能够返回一个参数"Success"对应的ActionForward实例。以下代码是在配置文件struts-config.xml中定义的forward元素:
<action attribute="studentForm" input="/register.jsp" name="studentForm" path="/student" scope="request" validate="true" type="struts.action.StudentAction" > <forward name="Success" path="/registerOK.jsp" /> </action>
ActionMapping类的findForward()方法首先会调用findForwardConfig()方法,以查看在<action>元素中是否包含<forward>子元素。如果有,就会检查<global-forwards>元素片断。一旦找到匹配的ActionForward实例,就会从execute()方法将其返回给RequestProcessor。下面是ActionMapping类的findForward()方法:
public ActionForward findForward(String name) { ForwardConfig config = this.findForwardConfig(name); if (config == null) config = this.getModuleConfig().findForwardConfig(name); return (ActionForward) config; }