一action详解
Struts 2.0 无须继承任何类型或实现任何接口。虽然,理论上Struts 2.0的Action无须实现任何接口或继承任何类型,但是,我们为了方便实现Action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并重载(Override)此类里的String execute()方法,来规范方法声明(必须返回String,并且没有参数)并且可用父类的一些属性比如:success,input,error,LOGIN, NONE,并且提供了输入验证,错误信息存取,以及国际化的支持,选择从ActionSupport继承,可以简化action的定义。
开发好action之后,好需要对action进行配置,以告诉Struts2框架,针对某个URL的请求应该交由哪个action进行处理。
1、Action映射:
action映射是Struts2框架中的基本” 工作单元”,action映射就是将一个请求URL(即action的名字)映射到一个action类,当一个请求匹配某个action的名字时,框架就使用这个映射来确定如何处理请求。
action元素的完整属性表
属性 | 是否必须 | 说明 |
name | 是 | action的名字,用于匹配URL |
class | 否 | Action实现类的完整类名,如果不设置默认会由com.opensymphony.xwork2.ActionSupport进行处理 |
method | 否 | 执行Action类时调用的方法 |
convert | 否 | 应用于action的类型转换的完整类名 |
例如:
<action name="login" class="org.itjob.UserAction" method=”login” >
<result name="success">/index.jsp</result>
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
</action>
2、result配置:
属性 | 是否必须 | 说明 |
name | 否 | Name:默认是success,,表示action返回的字符串 |
Type | 否 | 返回数据的类型(不是必须):默认是dispatcher 常用的有json redirectAction 本体内容:一般就是一个jsp页面的名称或者是一个action的名称 |
3、动态方法调用:
在Struts2中动态方法调用有三种方式,动态方法调用就是为了解决一个Action对应多个请求的处理,以免Action太多
Ø 第一种方式
通过配置action的method属性
Ø 第二种方式
感叹号方式(需要开启),官网不推荐使用这种方式,建议大家不要使用.
用这种方式需要先开启一个开关
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
将此常量设置为true,这种方式才能使用这种方式是在action的名字中使用感叹号(!)来标识要调用的方法名,其语法格式为 actionName!methodName.action
例如,我们配置了如下的action
<action name="user" class="org.lesson05.UserAction">
<result name="success">/Methods/list.jsp</result>
</action>
当请求/user!delete.action时,就会自动调用UserAction中的delete()方法
Ø 第三种方式
首先得关闭开关
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
随着Web应用程序的增加,所需的Action也会更多,从而导致大量的action映射,使用通配符可以减少action配置的数量,使一些具有类似行为的Action或者Action方法可以使用通用的样式来配置。
通配符即星号(*),用于匹配0个或多个字符,在配置action时,可以在action元素的name属性中使用星号(*)来匹配任意的字符。
以下是在action映射中使用通配符:
<action name="news*" class="org.struts2.lesson05.News{1}Action">
<result name="success">/WEB-INF/News/{1}.jsp</result>
</action>
我们在action元素的name属性中使用了通配符(*),允许这个映射匹配所有以/news开始的URL,例如/newsAdd,/newsEdit,/newsDelete,但是,如果请求的是/newsEdit/add,那么这个映射就不会被匹配。
在上面,有一个特殊的记号{1},这是作为占位符使用的,它将被通配符所匹配的值替换,例如访问/newsEdit,通配符(*)匹配的部分是Edit,那么,这个值将替换{1},最终调用的类是org.struts2.lesson05.NewsEditAction,Action执行成功后导向的结果页面是/WEB-INF/News/Edit.jsp。
在action映射和action结果中,通配符匹配的值可以用记号{N}来访问,N是从1到9的数字,指出替换的是哪一个通配符匹配的值。整个请求URL可以用记号{n}来访问。例如如下的action映射:
<action name="*_*" class="org.struts2.lesson05.{1}Action" method="{2}">
<result>/WEB-INF/News/{0}.jsp</result>
</action>
当访问/News_delete时,name属性中的第一个”*”匹配News,第二个”*”匹配delete,class属性中使用的记号是{1},所以被News所替换,method属性中使用的记号是{2},于是被delete所替换。结果映射中使用的记号是{0},于是被整个URL替换,即News_delete所替换。整个替换后的结果是:当请求/News_delete时,框架调用NewsAction实例的delete方法对请求进行处理。执行成功后,请求被导向到/WEB-INF/News/News_delete.jsp页面。
通配符方法设置的另一种常见方式是使用后缀通配符,即将”*”放在action名字的后面,在”*”和名字前缀之间使用一个特殊字符作为分隔,常用的特殊字符是下划线(_),当然也可以使用其他字符。例如:
<action name="News_*" class="org.struts2.lesson05.NewsAction" method="{1}">
<result>/WEB-INF/News/{0}.jsp</result>
</action>
当请求/News_delete时,调用的是NewsAction实例的delete方法,当请求/News_edit的时候,调用的是NewsAction实例的edit方法。
二、常用对象说明
1、ActionContext对象
每次的request请求都会建立一个新的ActionContext对象一般情况,我们的ActionContext都是通过:ActionContext context = ActionContext.getContext();来获取的.
我们再来看看这里的actionContext对象的创建: static ThreadLocal actionContext = new ActionContextThreadLocal();, ActionContextThreadLocal是实现ThreadLocal的一个内部.ThreadLocal可以命名为"线程局部变量",它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本, 而不会和其它线程的副本冲突.这样,我
ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的.
通过actioncontext获取servlet作用域对象
Map session =context.getSession();session作用域
Map application =context.getApplication(); application作用域
Context.get(‘key’)表示从request作用域获取参数
实际struts2是将session,application.request中的值copy到了map中。维护了一个相应对象的副本
------------------------------------------------------------------------------------------------------
request:ActionContext context = ActionContext.getContext();
session:Map session = context.getSession();session作用域
application:Map application = context.getApplication(); application作用域
-------------------------------------------------------------------------------------------------------
2、ServletActionContext
该对象继承自ActionContext类。
1. HttpServletRequest request = ServletActionContext.getRequest();
2. ServletContext servletContext = ServletActionContext.getServletContext();
3. request.setAttribute("req", "请求范围属性");
4. request.getSession().setAttribute("ses", "会话范围属性");
5. servletContext.setAttribute("app", "应用范围属性");
6. HttpServletResponse response = ServletActionContext.getResponse();
三、action前后台传值
1、获取页面传的参数
直接在action中定义全局属性如:private String name;必须提供set方法.前台界面如果要传值到action中必须定义一个表单域的名称为name如:<intput type=”text” name=”name”/>注意红色部分,必须一致。
界面可以通过点运算符传递对象的属性到后台比如后台有个User对象有个uername属性,那么前台传值可以使用user.username的方式。
2、向响应页面传递数据
可以直接通过全局属性进行传值,如action中有个属性为name(必须提供getter方法),那么前台可以使用el表达式直接获取如${name},类似于前台传值的方式,后台也可以直接传递对象到前台如果action中有个属性为user前台可通过点运算符直接获取user对象的属性
如:${user.username}