对请求进行处理的元素主要有interceptors、Action以及Result。下面分别对其进行讲述。java
1.拦截器配置(interceptors)apache
经过使用拦截器,咱们能够在action中的方法执行以前先执行一些咱们事先定义好了的方法,也能够在action中的方法执行以后当即执行一些咱们事先定义好了的方法。在开发的过程当中,拦截器将是一个强有力的工具。拦截器有不少不少的功能,如校验、属性封装、安全、日志等等,以下表所示:安全
表1:拦截器功能表app
校验(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还能够定义它本身的本地(局部)栈,以下面例子所示:jsp
<action name="VelocityCounter" class="org.apache.struts2.example.counter.SimpleCounter">
<result name="success">...</result>
<interceptor-ref name="defaultComponentStack"/>
</action>ide
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属性来实现,以下所示:url
<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也不一样。