struts2学习:配置篇值请求处理元素

 

    对请求进行处理的元素主要有interceptorsAction以及Result。下面分别对其进行讲述。

    1.拦截器配置(interceptors)

通过使用拦截器,我们可以在action中的方法执行之前先执行一些我们事先定义好了的方法,也可以在action中的方法执行之后立即执行一些我们事先定义好了的方法。在开发的过程中,拦截器将是一个强有力的工具。拦截器有很多很多的功能,如校验、属性封装、安全、日志等等,如下表所示:

1:拦截器功能表

校验(validation)

检查输入是否正确

属性封装(property population)

将输入传输和转化为对象的属性

日志(logging)

记录关于每个action的详细信息

切面(profiling)

记录action的吞吐量,寻找性能瓶颈(不是很懂)

我们可以将多个拦截器链接在一起形成一个拦截器栈。比方说一个action不仅要对客户端的资格进行审查,还要记录它自己的行为,那么我们可以将实现这两个功能的拦截器放在一起,形成一个拦截器栈(interceptor stack)。拦截器是以java类的形式实现的,因此每一个拦截器都有一个唯一的类名。为了让对拦截器的参考更加容易,我们可以在框架中为每个拦截器注册一个更简单的名字。下面给出了一个注册拦截器的例子:

<interceptors>
    
    
    <interceptor name="security" class="com.company.security.SecurityInterceptor"/>
    
    
    <interceptor-stack name="secureStack">
    
    
        <interceptor-ref name="security"/>
    
    
        <interceptor-ref name="defaultStack"/>
    
    
    </interceptor-stack>
    
    
</interceptors>
    
    

在定义一个拦截器栈的时候,单个的拦截器和拦截器栈可以以任意的顺序混合在一起,struts框架将会按照拦截器在栈里面的顺序调用它们。大多说应用程序都会定义一个默认的拦截器栈,如:<default-interceptor-ref name="defaultStack"/>,默认的拦截器栈会作用于package中的每个action上。当然action还可以定义它自己的本地(局部)栈,如下面例子所示:

<action name="VelocityCounter"  class="org.apache.struts2.example.counter.SimpleCounter">
    
    
    <result name="success">...</result>
    
    
    <interceptor-ref name="defaultComponentStack"/>
    
    
</action>
    
    

2Action配置

action mappings是框架中的基本工作单元,框架通过对请求的request路径进行映射来决定由哪个action来处理请求。action mappings能指定一系列的result、异常处理器以及拦截器。action元素的所有属性中只有name属性是必须的,其它属性都是可选的。关于如何从请求路径映射到actionnamespace那节中已经说过了,这里就不说了。尽管对于action的命名很灵活,但是action的名字中最好不要出现斜线(/)、点号(.)、破折号(/),以免出现一些不可预知的错误。

Action接口中定义了action默认的方法入口,它就是execute方法。但是并不是每个action类都必须实现这个接口,如果action类没有实现这个接口的话,框架将使用反射来寻找一个execute方法。有时候我们的action中可能会包括多个方法入口,并且不同的情况下方法入口不同,例如执行修改操作时我们想进入actionmofify方法,执行增加操作时进入actionadd方法,这个时候怎么办呢?我们可以通过指定action元素的method属性来实现,如下所示:

<action name="modify" class="example.CrudAction" method="modify">
    
    

如果在action类中没有execute方法,也没有在配置文件中指定其它的方法,框架会抛出异常。

很多时候,多个action mapping会共享一个相同的模式,这个时候我们可以使用通配符方法。还是举例来说,如下所示。

<action name=”editCrud” class=”example.CrudAction” method=”edit”/>

<action name=”deleteCrud” class=” example.CrudAction” method=” delete”/>

上述两个action mapping调用的是同一个action类,只是执行的方法不同而已,并且所执行的方法名都是action mapping名字的开头部分,而且action mapping的名字除去方法名之后剩下的部分是一样的。这种情况下我们可以使用一个action mapping来代替上面两个action mapping

<action name=”*Crud” class=”example.CrudAction” method=”{1}”>

匹配过程是这样的 (以请求的action mapping的名字是editCrud为例)

     *可以表示任何内容,因此任何以Crud结尾的action mapping都会匹配上

     editCrud匹配上后,*的内容此时就是edit

     调用名字为第一个*号的内容的方法,此时仅有一个*号,并且此时它的内容为edit,因此action类的edit方法被调用了

     同理,如果请求的actiondeleteCrud,匹配成功后*的内容就是delete,调用的方法就是delete了。

使用通配符匹配方法可以让我们减少配置文件的内容,是配置更加简洁。

如果我们没有给action元素指定class属性的话,框架会默认它的class属性为com.opensymphony.xwork.ActionSupport,如果想指定别的类作为默认的Action类,可以通过packagedefault-action-ref属性来设置。在设置了default-action-ref之后,如果我们在package中没有匹配到所请求的action,那么这个默认的action就会被调用。一般一个命名空间下最好只定义一个默认的action

3Result元素配置

action类处理完一个请求后会返回一个字符串,这个字符串将被用来选择一个result元素。通常一个action mapping会有多个result,代表各个可能不同的结果。ActionSupport中定义了几个标准的result token,如下所示:

String SUCCESS = "success";
   
   
String NONE    = "none";
   
   
String ERROR   = "error";
   
   
String INPUT   = "input";
   
   
String LOGIN   = "login";
   
   

通常我们都会自定义一些result token类匹配特定的情况。

result元素负责完成两个工作:1.提供一个逻辑名用于与action类的返回字符串进行匹配;2.提供一个返回类型(Result Type)。尽管大多数的result只是简单的转向一个页面或模板,但是我们还可以利用其它的返回类型(Result Type)做其它的一些事情。我们可以为每个包设置默认的返回类型(Result Type),如果一个包继承了另外一个包,它可以选择设置自己的默认返回类型或者直接使用父包的。设置默认返回类型的方式如下:

<result-types>
   
   
<result-type name="dispatcher" default="true"      
   
   
 class="org.apache.struts2.dispatcher.ServletDispatcherResult"/>
   
   
</result-types>
   
   

Result元素有两个属性:nametype,它们都是可选的,name属性的默认值是“success”type的属性为我们所设置的默认返回类型,如上例中即为dispatcher

定义在action元素里面的result我们可以称之为局部result,除此之外我们可以还可以全局的result,这些result会被多个action所共享。框架会首先寻找嵌套在action元素中的result,如果没有匹配的就去全局result中去寻找。一个全局result的例子如下:

<global-results>
    
    
  <result name="error">/Error.jsp</result>
    
    
  <result name="invalid.token">/Error.jsp</result>
    
    
  <result name="login" type="redirect-action">Logon!input</result>
    
    
</global-results>
    
    

有时候我们的result在运行前可能是未知的。比方说,一个result它所跳转的页面取决于它所在action类的运行结果或者客户端的输入等等,这时候我们可以使用动态的result,也就是说result的值可以使用表达式语言(EL)来表示,这个表达式的值是动态的,取决于action的运行时状况,下面是一个例子:

private String nextAction;
   
   
public String getNextAction() {
   
   
    return nextAction;
   
   
}
   
   
……………………………………………………………………………………
    
    
<action name="fragment" class="FragmentAction">
    
    
  <result name="next" type="redirect-action">${nextAction}</result>
    
    
</action>
    
    

在上例中result的值将是它所在actionnextAction的属性值,nextAction属性的值不同,当action的方法返回”next”时所跳向的url也不同。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值