1. Action类的创建方式
我们知道action类能够配合struts2框架进行工作。那么如何创建action类呢?action类的创建方式有三种:
<1>创建一个POJO(Plain Old Java Object)类,简单是java对象。POJO类是指没有实现任何借口以及除了Object类以外,没有继承任何父类。
struts2通过获取struts.xml获取到完全的类名,然后底层通过反射,进行执行方法。
<2>创建一个类,实现com.opensymphony.xwork2.Action接口。在这个Action接口中,定义了默认五中视图名称,视图名的修饰都为 public static final String:
视图名称 | 名称对应的值 | 作用 |
---|---|---|
SUCCESS | “success” | 数据处理成功时(成功页面) |
NONE | “none” | 页面不跳转,和return null一样。 |
ERROR | “error” | 数据处理发送错误(错误页面) |
INPUT | “input” | 用户输入数据有误,通常用于表单校验(输入页面) |
LOGIN | “login” | 主要权限认证(登录页面) |
<3>创建一个类,继承com.opensymphony.xwork2.ActionSupport类。这个ActionSupport类继承了Action类。
这个方法是开发中最常用的方法,因为支持表单校验、信息读取的国际化、错误信息设置都支持。
2. Action类的访问方式
<1>在配置<action>元素时,没有指定method属性时,会默认执行Action类中的execute方法。
<2>配置<action>元素时,如果有配置method属性,那么就会执行method中属性的那个方法。(推荐使用)
因此可以将多个请求业务方法写在一个Action类中。
例如:
<action name="Demo_add" class="com.struts2.Demo" method="add"></action>
<action name="Demo_update" class="com.struts2.Demo" method="update"></action>
<3>使用通配符*来进行简化struts.xml配置
例如:
<a href="${pageContext.request.contextPath}/struts2/demo_add.action" >添加</action>
<a href="${pageContext.request.contextPath}/struts2/demo_update.action">修改</action>
//那么在struts.xml中就可以这样配置action标签
<action name="demo_*" class="com.struts.Demo" method="${1}"></action>
//上面的${1}代表的是第一个通配符。配置的时候可以使用多个通配符,但是会造成阅读麻烦,不建议使用多个通配符,一个就应该足够用了。并且如果要使用,命名就必须符合一个规范。
<4>使用动态调用的方法
前提:在default.properties中常量struts.enable.DynamicMethodInvocation的值必须为true。
使用释义:
//注意,在这没有配method方法。
<action name="demo" class="com.struts2.Demo"></action>
使用时在页面上配上路径:
<a href=”${pageContext.request.contextPath }/struts2/demo!add”>添加</a>
对于demo!add 这就是动态方法调用,会调用demo中的add方法。
3. 在struts2框架中获取servlet api的方式
对于Struts2框架,不建议直接使用servlet api,但是还是能够获取。
<1>通过ActionContext来获取。
//1.首先要获取一个ActionContext对象。
ActionContext context = ActionContext.getContext();
//2.通过ActionContext对象获取的Servlet API不是真正的API,而是一个Map集合。
//获取Application域中的内容。
Map<String,Object> appMap = context.getApplication();
//获取Session域中的内容。
Map<String,Object> sessionMap = context.getSession();
//获取参数中的内容。相当于request.getParameterMap()
Map<String,Object> paramMap = context.getParameters();
//向request域中存值,相当于request.setAttribute(str,str)
context.put(String,Object);
//向request域中取值,相当于request.getAttribute(str)
context.get(String);
<2>通过注入的方式来获取
这个方式获取到的是真正的API,不是一个Map对象。
前提要求:
(1)action类必须实现其提定接口。
ServletContextAware : 注入ServletContext对象
ServletRequestAware : 注入Request对象
ServletResponseAware : 注入Response对象
(2)重定接口中的方法。
(3)声明一个web对象,使用接口中的方法的参数对声明的web对象赋值。
拿request举例:
//(3)声明web对象。
private HttpServletRequest request;
@Override//(2)重定接口中的方法。
public String execute() throws Exception {
//在这当中,使用了request对象了。
System.out.println(request.getParameter("param"));
return null;
}
//(3)使用接口中的方法参数对声明的web对象赋值。
public void setServletRequest(HttpServletRequest request) {
this.request=request;
}
实现原理:其实在这过程中用到了struts2的一个interceptor完成的。
<interceptor name=”servletConfig”
class=”org.apache.struts2.interceptor.ServletConfigInterceptor”/>
在这个方法底层用到实现的源代码的一部分为:
if (action instanceof ServletRequestAware) { //判断action是否实现了ServletRequestAware接口
HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST); //得到request对象.
((ServletRequestAware) action).setServletRequest(request);
//将request对象通过action中重写的方法注入。action一开始是Object类型的,要强转是为了实现子类中的功能,父类中没有这个功能。
}
<3>通过ServletActionContext来获取。
在ServletActionContext中的方法都是静态的,能够直接获取到需要的对象。
获取request对象: ServletActionContext.getRequest();
获取response对象: ServletActionContext.getResponse();
获取pageContext对象: ServletActionContext.getpageContext();