Action是什么
应用程序可以完成的每一个操作都可以称之为动作。例如,显示一个登录表单是一个动作,将用户信息保存起来也是一个动作。
动作类其实就是普通的java类,他们可以有属性和方法,但是需要遵循一些规则:
(1)每个属性必须有一个get和一个set方法,属性命名遵循JavaBean命名规则。
(2)动作类必须有一个不带任何参数的构造器。如果Action中没有定义构造器,那么编译器会自动增加一个不带参数的构造器,但是如果我们定义了一个构造器,那么我们必须保证要有一个不带参数的构造器
(3) 每个动作类至少有一个方法供Struts2在执行该动作时调用。
(4) 动作类并不是非得扩展某个特定的父类或是实现某个特定的接口。但是一般情况下动作类都将继承ActionSupport基类。并且如果我们在struts.xml中配置action时,如果没有指定class属性,那么默认就是ActionSupport。
(5)Struts2会为每个http请求创建一个新的Action实例,因此不用考虑多线程的问题。
Action的作用:
1) 动作最重要的作用是为给定请求封装需要做的实际工作
2) 在请求到视图的框架自动数据传输中作为数据的携带者
3) 动作必须决定哪个结果视图应该呈现请求响应中返回的视图
Action的配置
要想使我们的Java类被Struts2识别为Action,那么我们还需要在struts.xml中做一些配置。来看一下先前的hello world例子中对Action的配置:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD StrutsConfiguration 2.0//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.devMode" value="true" /> <package name="default" namespace="/" extends="struts-default"> <action name="hello" class="action.HelloWorld"> <result name="success">/success.jsp</result> </action> </package> </struts>
我们需要将我们的Action放在某个特定包中,通过包来组织我们的Action,在同一个包中Action的名字不能重复,但是在不同的包中可以出现名字相同的Action。Struts2中的包跟Java中的包有些相似,但是Struts2中的支持Abstract和extends。Struts2中内建了struts-default包,里面预先配置许多更框架功能相关的拦截器。我们的包只需要继承struts-default包,那么我就能够使用框架提供的一些功能了。那么我们先了解一下Struts2中的包(package):
在struts.xml中使用<package>标签来定义包,其中的name属性为必须属性。
name主要用于标识这个包,其中的extends属性可选,表示继承某个包。namespace属性用于指定这个包的命名空间,在访问包中的Action时需要包含namespace。
需要注意,Struts2加载时会顺序的读取struts.xml文件,因此需要注意各个package之间的依赖关系。
在package标签中通过使用action标签来定义Action,name属性为必须属性,用于指定action的名字,class属性为可选,Action所对应的动作类。在action标签中使用result标签来为该action定义一个结果。Action中被执行的方法总是会返回一个字符串对象,来告诉struts2执行那个结果,result标签中的name属性正是用于匹配动作方法的返回值的。
Action的实现
(1) POJO实现
Action可以不继承任何类或实现任何接口,普通的java类即可,但是需要需一个无参数构造器,还需需一个execute方法,其定义如下:
public String execute()throws Exception {
//….
}
抛出异常是可选的,如果Action中的方法名不是execution,那么就需要通过在struts.xml中action标签的method属性指定:
<actionname="hello"class="action.HelloWorld"method="save">
<resultname="success">/success.jsp</result>
</action>
(2) 实现com.opensymphony.xwork2.Action接口
在该接口中定义了一个execute方法和一些常量:
public static final java.lang.String SUCCESS = "success";
public static final java.lang.String NONE = "none";
public static final java.lang.String ERROR = "error";
public static final java.lang.String INPUT = "input";
public static final java.lang.String LOGIN = "login";
这些常量可以返回一些预定的result。
SUCCESS:表示动作执行成功并应该把结果视图显示给用户
NONE:表示动作执行成功但不应该把任何结果类型显示给用户
ERROR:表示动作执行不成功并应该把一个报错视图显示给用户
INPUT:表示输入验证失败并应该把刚才用来获取用户输入的那个表单重新显示给用户
LOGIN:动作未执行,因为用户没有登录,应将登录视图显示给用户
(3) 继承ActionSupport类
ActionSupport类本身实现了Actin接口,因此继承ActionSupport类相当于实现了Action接口。除了Action接口之外,ActionSupport还实现了其他几个接口:
com.opensymphony.xwork2.Validateable:提供validate()方法来为Action增加验证的功能
com.opensymphony.xwork2.Validateaware:提供方法来保存和恢复action或field级的错误信息
com.opensymphony.xwork2.TextProvider:提供获取本地信息文本的功能
com.opensymphony.xwork2.LocaleProvider:提供getLocale()方法来获取本地消息
在Action中访问资源
在Action中,可以通过ServletActionContext对象或者Aware接口去访问ServletContext、HttpServletRequest、HttpServletResponse和HttpSession等资源。使用Aware接口访问资源是依赖注入(DI)的一种实现方式。
通过ServletActionContext或者ActionContext可以访问刚才说到的资源,前者包含后者。ServletActionContext提供了一些静态方法:
static HttpServletRequest |
|
static HttpServletResponse |
|
static ServletContext |
使用Aware方式访问资源时需要我们在动作类中定义一个相应资源类型的成员变量,并且实现Aware接口中的方法。
org.apache.struts2.util.ServletContextAware
void |
setServletContext(ServletContext context) |
org.apache.struts2.interceptor. ServletRequestAware
void |
setServletRequest(HttpServletRequest request) |
org.apache.struts2.interceptor. ServletResponseAware
void |
setServletResponse(HttpServletResponse response) |
org.apache.struts2.interceptor. SessionAware
void |
setSession(Map<String,Object> session) |
注意SessionAware中setSession的参数是Map类型,而不是HttpSession类型。
使用Aware的Action示例:
package action; import java.util.Map; import org.apache.struts2.interceptor.SessionAware; import com.opensymphony.xwork2.ActionSupport; public class HelloWorld extends ActionSupport implements SessionAware { private String userName; private Map<String, Object> session; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String execute1() throws Exception { session.put("userName",userName); return "success"; } public void setSession(Map<String, Object> session) { this.session = session; } }
暂时先写到这里了,休息一下。