ActionSupport
1). com.opensymphony.xwork2.ActionSupport 类是默认的 Action 类: 若某个 action 节点没有配置 class 属性, 则 ActionSupport 即为待执行的 Action 类. 而 execute 方法即为要默认执行的 action 方法,在编写 Action 类时, 通常会对这个类进行扩展。
<action name="testActionSupport">
<result>/testActionSupport.jsp</result>
</action>
等价于
<action name="testActionSupport"
class="com.opensymphony.xwork2.ActionSuppor"
method="execute" >
<result>/testActionSupport.jsp</result>
</action>
2). 在手工完成字段验证, 显示错误消息, 国际化等情况下, 推荐继承 ActionSupport.
result
1). result 是 action 节点的子节点
2). result 代表 action 方法执行后, 可能去的一个目的地
3). 一个 action 节点可以配置多个 result 子节点.
4). result 的 name 属性值对应着 action 方法可能有的一个返回值.
<result name="index" >/index.jsp</result>
5). result 一共有 2 个属性, 还有一个是 type: 表示结果的响应类型
6). result 的 type 属性值在 struts-default 包的 result-types 节点的 name 属性中定义.
常用的有
> dispatcher(默认的): 转发. 同 Servlet 中的转发.
> redirect: 重定向
> redirectAction: 重定向到一个 Action
> chain:转发到一个 Action
注意: 通过 redirect 的响应类型也可以便捷的实现 redirectAction 的功能!
重定向:
请求转发只能是:
<result name="test" type="chain">
<param name="actionName"> testAction</param>
<param name="namespace">/atguigu</param>
不能是:
<result name="test">/atguigu/testAction.do</result>
通配符映射
struts 通配符映射应用程序越大,它里面action mapping的数量也越多,通过使用通配符,我们可以将一些相似的mapping绑在一起,用一个比较通用的mapping来表示,在前面关于action配置的那章里面也提到了这个通配符的使用,这里再系统的说一下。
如下所示,有一个配置好了的action mapping:
<action name="/edit*" class="org.apache.struts.webapp.example.Edit{1}Action">
<result name="failure"path="/mainMenu.jsp">
<result path="/{1}.jsp">
</action>
这个action mapping可以用匹配所有以/edit开头的对action名称,例如/editSubscription,editRegistration等等,但是/editSubscription/add不会被匹配上。被通配符所匹配的内容将会被替换到action mapping以及result的各个属性中去,去取代{1}。比方说/editSubscription匹配上了,那么其中一个result的path属性就会被框架认为是Subscription.jsp。要注意的是,如果一个请求的url和多个action mapping匹配上了,那么选择最后面的那个执行,也就是说按照从后往前的顺序进行匹配查找,有一个例外就是精确匹配优先,如果有一个action mapping没用通配符和url给匹配上了,那么优先选择精确匹配,折合servlet中的匹配原则是一样的。
通配符中几个特殊的标记,如下所述:
*:可以匹配0个或多个任意字符,但是不包括正斜杠”/”;
**:可以匹配0个或多个任意字符,包括正斜杠’’/”在内
/:反斜杠,转义字符。
因为*不能匹配正斜杠,所以前面/editSubscription/add不会被匹配上。在action mapping中,被通配符所匹配上的值可以用符号{N}来访问,其中N是一个1到9之间的数,用来表示代替第N个被匹配上的值,说通俗点就是第N个*号所表示的内容,比方说通配符表达式是/edit*/add*/confirm*,它匹配上了/editOrder/addItem/confirmResult,那么{1}就代表Order,{2}就代表Item,{3}就代表Result,依此类推
动态方法调用
动态方法调用: 通过 url 动态调用 Action 中的方法,既改变已有的url加载action中的方法。
<!--打开允许动态方法调用的开关, 默认是 false-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
URI:
/struts-app2/Product.action: Struts 调用 Product 类的 execute
/struts-app2/Product!save.action: Struts 调用 Product 类的 save() 方法
默认情况下, Struts 的动态方法调用处于禁用状态
关于值栈
1). helloWorld 时, ${productName} 读取 productName 值, 实际上该属性并不在 request 等域对象中, 而是从值栈中获取的.
2). ValueStack:
I. 可以从 ActionContext 中获取值栈对象
II. 值栈分为两个逻辑部分
> Map 栈: 实际上是 OgnlContext 类型, 是个 Map, 也是对 ActionContext 的一个引用. 里边保存着各种 Map:
requestMap, sessionMap, applicationMap, parametersMap, attr
> 对象栈: 实际上是 CompoundRoot 类型, 是一个使用 ArrayList 定义的栈. 里边保存各种和当前 Action 实例相关的对象.
是一个数据结构意义的栈.
2. Struts2 利用 s:property 标签和 OGNL 表达式来读取值栈中的属性值
1). 值栈中的属性值:
> 对于对象栈: 对象栈中某一个对象的属性值
> Map 栈: request, session, application 的一个属性值 或 一个请求参数的值.
2). 读取对象栈中对象的属性:
> 若想访问 Object Stack 里的某个对象的属性.
可以使用以下几种形式之一: object.propertyName ; object['propertyName'] ; object["propertyName"]
> ObjectStack 里的对象可以通过一个从零开始的下标来引用. ObjectStack 里的栈顶对象可以用 [0] 来引用, 它下面的那个对象可以用 [1] 引用.
[0].message
> [n] 的含义是从第 n 个开始搜索, 而不是只搜索第 n 个对象
> 若从栈顶对象开始搜索, 则可以省略下标部分: message > 结合 s:property 标签:
3). 默认情况下, Action 对象会被 Struts2 自动的放到值栈的栈顶.
4).读取 Context Map 里的对象的属性:
调用字段和方法
1、可以利用 OGNL 调用:
任何一个 Java 类里的静态字段或方法.
被压入到 ValueStack 栈的对象上的公共字段和方法.
2、默认情况下, Struts2 不允许调用任意 Java 类静态方法, 需要重新设置 struts.ognl.allowStaticMethodAccess 标记变量的值为 true.
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<s:property value="@java.lang.Math@cos(0)">
调用对象栈的方法为一个属性赋值
获取对象栈属性
<s:property value=“ProductName”/>==>CPU
为对象栈的方法为一个属性赋值
<s:property value=”setProductName(“atguigu”)”/>
再次获取对象栈属性
<s:property value=“ProductName”/>==>atguigu
访问数组类型的属性
<%
String [] names=new String[]{“aa”,”bb”,”cc”,”dd”}
request.setAttribute(“names”,names);
%>
length:<s:property value=”#attr.names.length”/>==>4
name[2]:<s:property value=”#attr.names[2]”/>==>cc
访问 Map 类型的属性
<% Mapletters = new HashMap();
request.setAttribute(“letters ”,letters );
letters.put(“AA”,”a”);
letters.put(“BB”,”b”);
letters.put(“CC”,”c”);
%>
Size:<s:property value=”#attr.letters .size”/>==>3
AA:<s:property value=”#attr.letters ['AA']”/>==>a
异常处理: exception-mapping 元素
配置局部:<exception-mapping result=”input”exception=”异常全类名”></exception-mapping>
<result name=”input”>/input.jsp</result>
配置全局:
<global-exception-mappings >
<exception-mapping result=”input”exception=”异常全类名”></exception-mapping>
</global-exception-mappings >
<global-results>
<result name=”input”>/input.jsp</result>
</global-results>