TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
1.配置Action.! s& k- V. U0 `7 M& a7 l
在struts.xml文件中,使用包来管理Action,定义一个Action节点时,必须指定name属性,且值为请求url的前半部分.class可以不写,默认为ActionSupport类.' V$ y' t1 q' Q$ u# `
Action只是一个控制器,并不能对客户端产生任何响应,只能将指定的视图资源返回给用户.通过配置其子节点<result>来定义逻辑视图和物理视图的关系.- m9 H D0 J% l; j% ?/ w; O4 e* ]$ H
<action name="add" class="com.action.myAction">0 ?- w* Q6 I& M2 o' s+ f) P
<result name="input" type="redirect">/input.jsp</result>
* T/ D! `2 ~; Q7 B</action># w, y' k: b+ ^$ @' B4 {
$ H( u4 E" X4 C/ W1 p
2.动态方法调用.
( f/ C/ Q3 i+ {2 Y. S# a- W* U要使用此功能,要在struts.properties文件中指定:0 x" K# Q1 v& `
struts.enable.DynamicMethodInvocation=true
' e, F2 {2 _8 M将请求url定义为 actionName!methodName.action 如,FruitAction!add.action.stust.xml配置文件
/ d6 W# ]% R; r; }% m4 v不需要改动,但在Action里必须定义一个add方法.这样就能访问FruitAction的add方法.
" F. [( ]/ y6 F+ t$ p7 l( R# f7 d
4 E/ U4 n0 ?! v: e" _- B8 w3.为action指定method属性.
9 k f+ ]) q0 O- Q同动态方法调用的功能一样,但此种方法,在struts.xml文件中,将一个Action处理类定义成了多个逻辑Action
7 W- K* Y7 Y G2 V<action name="login" class="com.ac.UserAction" method="loginM"/></action>
/ J0 M4 Z" A* @<action name="regist" class="com.ac.UserAction" method="registM"/></action>9 b+ v$ C4 @7 p+ |3 Z; G8 d. k
这样,Action类的每个方法都被映射成一个Action." P( @% m1 N" N% W; k( g7 i- Q+ h
但,这中方法让action的定义相当冗余,所以struts2.0提供了另一种形式的方法调用,即使用通配符.3 Q* f) K) [7 C7 w, V
6 u4 Y' ~8 ~" A _0 J/ X8 e4.使用通配符.
' n5 O& X! \# ]& b4 W2 Z <Action>的name,class,method三个属性都能使用通配符./ |! c$ I: k: |* w/ ^! d* p
<action name="*Action" class="com.ac.UserAction" method="{1}">
! V6 i, E8 h5 R* n0 v! _- p 这种定义方式就好比定义了多个action,method="{1}",表示"*"的值.
. `/ D1 t& c* U6 a! k <action name="*Action" class="com.ac.{1}Action" method="{1}">
- y2 i$ t! j; I* b0 k <action name="*_*" class="com.ac.{1}Action" method="{2}">
& ?* r3 `7 ]/ D5 z: l9 P2 _6 Sstruts2还允许<result>中使用表达式.如<result>/{1}.jsp</result>
, m2 T8 K, }: n$ `# F<action name="*Page">
6 s/ a" |6 {! Q! \, D. v <result>/{1}.jsp</result>5 ]" L/ ^5 f9 ]0 w
</action>- Y9 f# Q, x/ g9 ^
由于没有指定class,则默认有ActionSupport处理,而ActionSupport的execute方法返回success,所以会跳到*.jsp页面.
2 f& A! d6 x+ x6 s# P问题来了,如果有一个这样的请求,aaaAction.action,在Struts.xml文件中定义了三个<action>0 ^9 A3 H& l" Z$ i: w( I
<action name="*">
- C4 V7 g# R# a* G5 f9 @<action name="*Action">
) S3 ?/ V& Q) ~0 k<action name="aaaAction">, B! M$ R7 l$ |9 V' K6 O
那么将会匹配哪个<action>呢.
2 V6 U+ Y( k8 v. n9 G. a& W首先,如果有一个<action>的name与请求完全匹配,那么就一定匹配该<action>,如果没有,则按顺序从上至下查找,如果能匹配,就映射该<action>,
9 x/ S, d# p% D, c( a3 `' |0 m( ]8 j例如,如果有一个aaaAction请求,则会匹配<action name="aaaAction">如果请求是aaAction,则会匹配<action name="*">,因为它在最先匹配.所以,一般将<action name="*">放到最后,范围最小的放前面.
/ i2 b: f, @8 A7 i4 w% T) L
6 l4 j5 l+ U5 Y8 T& ~0 o" R5.默认Action
3 s6 x2 Y8 O# M struts2允许你定义一个默认的Action,当容器找不到与请求Url相匹配的<action>是,将使用此默认action.. i- }/ _5 b! p* W$ X
<default-action-ref name="aAction" >8 U7 [5 G" r: s9 P$ k, ^9 [; {
<action name="aAction" class=......./>
7 n& P0 `# R) a/ A: w& L& b6.属性驱动和模型驱动.0 f( p/ p; f% z
属性驱动,将需要从页面获取的属性和传递给下一个视图的属性定义为action的实例变量,并提供getter和setter方法.
v+ o9 N6 r* l) R& C/ j% G# c模型驱动,则是向struts1.x那样,使用一个Pojo类来封装属性,但此pojo类不需要继承ActionForm,它就是一个普通的Pojo类.在Action中要实现ModelDriven接口,定义Pojo实例变量,并给其赋值(new),然后实现getModel()方法,返回pojo对象.
" m, } P: L* K6 H+ ?3 \# u; v4 N x* I. m
$ b% j" I) B/ m2 l1 ?
7.异常机制
& ]4 q$ U" x5 C$ S0 k5 vStruts2.0提供了一种声明式的异常处理方式.
5 F* X8 M9 o* _+ ]" npublic String execute() throws Exception
! p0 j0 H+ ?8 X' N+ Y' A0 [Action中的execute()能抛出所有Exception,将异常抛给了框架来处理,我们甚至不需要使用繁琐的try{}catch(){},我们只需要在struts.xml中配置<exception-mapping>异常映射,就能方便的处理各类异常.
8 B% l$ M; w2 X# C! m它有两个属性,
2 c: R0 ]# A4 qexception:指定该异常映射所设置的异常类型
9 c0 o$ C" q1 Uresult:出现指定异常后,返回的结果.( i6 Y5 k p- W
全局异常:将<exception-mapping>元素作为<global-exception-mapping>元素的子元素! s- N: y2 ?) s, u8 c! q
局部异常:将<exception-mapping>元素作为<action>的子元素.; }7 Y+ q3 H; j$ ^. j' A2 p
在页面输出异常信息:$ E3 e3 H! c: g; z* |- p
<s:property value="exception"/> 如<s:property value="exception.message"/>
1 k! }" z& V8 @<s:property value="exceptionStack"/>1 b8 S m1 {) b8 f% j9 Q& y) O
|
|