在MVC中,要有一个控制器来负责浏览器与服务器的通信,实现服务器与用户的交互。Struts2控制器最重要的组成部分是Action。
Action接收来自视图层的请求,并接收请求参数,同时负责调用模型Model层方法来完成业务逻辑的处理,最后控制程序的流程,选择一个合适的视图,将结果显示给用户。
Struts2会为每一个Action创建一个线程,因此是线程安全的。
尽量不要将商业逻辑代码放到Action中,而是放到JavaBean或者 EJB中。
一、Action的实现
有三种方法,最常用的是POJO(Plain Old Java Object).
1.POJO方法,这种方法要编写getter,setter,实现 execute()方法
通过配置拦截器可以找到开发者提供的 Action类,并自动检索execute方法,根据方法返回的结果的不同跳转到不同的页面。
public class HelloWord { private String message ; public String getMessage(){ return message ; } public String execute (){ message ="success" ; return message ; } }
在struts.xml文件中加入
<!--for HelloWord --> <action name="helloword" class ="com.chuiyuan.action.HelloWord"> <result >/helloword.jsp</result> </action>
再写一个helloword.jsp文件就可以了。
2.实现struts2提供的Action接口
略
3.继承ActionSupport类
ActionSupport是编写设计业务逻辑Action强有力的支持,它提供了很强大的功能。有很多成员函数。略。
二、在Action中访问Servlet对象
很多时候,Action会与Web容器进行交互,在web容器中,活动着各种对象 ,这些对象在客户端与容器交互的交互过程中有很重要的作用,如HttpSession,HttpServletResponse,
Cookie等,Strus2有两种方法解决这个问题。
1.通过ActionContext访问Servlet对象
- action文件
public class ServletAction implements Action{ @Override public String execute() throws Exception { ActionContext ac = ActionContext.getContext() ; Map paramMap = ac.getParameters(); String[] ids = (String []) paramMap.get("id") ; String[] names = (String [] )paramMap.get("name"); Map sessionMap=ac.getSession() ; sessionMap.put("id", ids[0]) ; sessionMap.put("name", names[0]) ; return "toSession"; } }
struts.xml文件中加入
<!-- for ServletAction --> <action name="servletAction" class="com.chuiyuan.action.ServletAction"> <result name="toSession">/session.jsp</result> </action>
idname.jsp文件
<%@ page language="java" contentType="text/html; charset=GBK" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <head> <title><s:text name="loginPage"/></title> </head> <body> <!-- 方法1 --> <form action ="servletAction.action" method="post"> ID:<input name="id"><br> Name:<input name="name"><br> <input type="submit" value="提交"> </form> <!-- 方法2 --> <s:form action="servletAction"> <s:textfield name="id" label="ID"/> <s:textfield name="name" label="Name"/> <s:submit value="提交"/> </s:form> </body> </html>
结果显示文件 session.jsp
<%@ page language="java" contentType="text/html; charset=GBK" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <head> <title><s:text name="loginPage"/></title> </head> <body> ${id }<br> ${name } </body> </html>
这里用到了EL表达式显示保存在 Session中的数据.
2.使用Ioc将Servlet对象注入到Action
Ioc就是Inversion of Control,控制反转,将设计好的类交给系统去控制,而不是在类的内部控制。
在Struts2中,要使用Ioc,一定要通过一些特定的接口将Servlet对象注入到Action 中,这一切都是由一组接口决定的,这组接口都以Aware结尾。
为了将相应的Servlet对象注入到Action中,只要让Action实现相应的接口就可以了,Struts2会自动将数据和对象注入到Action中。
例子如下
package com.chuiyuan.action; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.SessionAware; import com.opensymphony.xwork2.Action; public class ServletAction2 implements Action, ServletRequestAware, SessionAware { private Map sessionMap; private HttpServletRequest request; @Override public void setSession(Map<String, Object> session) { this.sessionMap = session ; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request ; } @Override public String execute() throws Exception { String id =this.request.getParameter("id") ; String name = this.request.getParameter("name") ; sessionMap.put("id" , id); sessionMap.put("name", name ); return "toSession"; } }
在struts.xml中加入
<!-- for servletAction1 --> <action name ="servletAction2" class="com.chuiyuan.action.ServletAction2"> <result name="toSession">/session.jsp</result> </action>
然后修改idname.jsp中action为servletAction2。
三、使用OGNL通过Action获取请求参数
四、使用标签调用 Action
有四种标签:Method, Action , Redirect, Redirect-action标签。
struts2定义了一个封装提交按钮的标签 <s:submit/>这个标签有一个name属性,将标签作为这个属性值,struts2就会根据这个值发送相应的请求。
1.Method标签
指定调用 Action的那个方法,格式如下
<s:submit name="method:方法名"/>
可以直接在视图中指定,也可以在配置文件中指定(更好)。
如下
package com.chuiyuan.action; public class MethodPrefixAction { public String execute1(){ System.out.println("prefix method1"); return null ; } public String execute2(){ System.out.println("prefix method2"); return null ; } }
因为不进行跳转,所以返回值设置为null,在配置文件中也不用为action设置<result/>标签。
<!-- for MethodPrefixAction--> <action name="methodPrefixAction" class="com.chuiyuan.action.MethodPrefixAction"> </action>