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

  1. 云栖社区>
  2. 博客>
  3. 正文

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

余二五 2017-11-16 23:42:00 浏览491

对请求进行处理的元素主要有interceptors、Action以及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>

2.Action配置

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

在Action接口中定义了action默认的方法入口,它就是execute方法。但是并不是每个action类都必须实现这个接口,如果action类没有实现这个接口的话,框架将使用反射来寻找一个execute方法。有时候我们的action中可能会包括多个方法入口,并且不同的情况下方法入口不同,例如执行修改操作时我们想进入action的mofify方法,执行增加操作时进入action的add方法,这个时候怎么办呢?我们可以通过指定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方法被调用了

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

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

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

3.Result元素配置

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元素有两个属性:name和type,它们都是可选的,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的值将是它所在action的nextAction的属性值,nextAction属性的值不同,当action的方法返回”next”时所跳向的url也不同。










本文转自 646676684 51CTO博客,原文链接:http://blog.51cto.com/2402766/572440,如需转载请自行联系原作者