Interceptor Configuration:
拦截器允许定义代码在action方法执行之前或者执行完毕以后执行。拦截器对于开发一个应用系统来说是一个非常有用的工具。有类似于验证、对象属性转换和生成、日志、安全等很多种应用案例。
很多个拦截器可以通过组成一个拦截器“栈”,串联在一起执行。组成拦截器栈的时候,其中的拦截器可以安装任意的顺序进行定义,但是执行的时候,框架安装拦截器栈中的拦截器定义的先后顺序执行
定义拦截器或者定义拦截器栈举例:
<interceptors> <interceptor name="security" class="com.company.security.SecurityInterceptor"/> <interceptor-stack name="secureStack"> <interceptor-ref name="security"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors>
绝大多数应用都会定义一个默认的拦截器栈,例如:
<default-interceptor-ref name="secureStack"/>
任何一个ACTION都可以定义自己的拦截器栈,例如:
<action name="VelocityCounter" class="org.apache.struts2.example.counter.SimpleCounter"> <result name="success">...</result> <interceptor-ref name="defaultComponentStack"/> </action>
Action Configuration:
action映射是struts框架中的基本工作,它将一个标识映射到一个处理类,当一个请求匹配一个action的名字,框架会通过映射来决定如何处理这个请求。
action mapping:
action映射可以定义一组结果类型,一组异常处理器和一个拦截器栈。在action映射中,只有“name”属性是必须的。
<action name="Logon" class="tutorial.Logon"> <result type="redirectAction">Menu</result> <result name="input">/Logon.jsp</result> </action>
action names:
在web应用中,action name作为浏览器提交的请求地址的一部分被匹配,就是去掉主机名,应用服务名和扩展名的那部分。例如: http://www.planetstruts.org/struts2-mailreader/Welcome.do 将被隐身到 Welcome action。
在应用程序中,一个action链接通常由struts标签生成。标签可以通过名字来定义action,例如:
<s:form action="Hello"> <s:textfield label="Please enter your name" name="name"/> <s:submit/> </s:form>
注意:1)ACTION名字中有斜线的情况:如果action名字中有斜线,需要通过设置<constant name="struts.enable.SlashesInActionNames" value="true"/>来允许action名字中可以有斜线。
2)action名字中有点号或者横线的情况:action名字中有点号或者横线可能造成未知的麻烦,所以要避免这种情况存在。
Aciton method:
默认的Action的入口方法时execute方法。
有时,开发者希望创建多个action的入口点,举例来说,在一个数据访问的action中,开发者希望把增删改查的入口点分开。不同的入口点可以通过“method”属性指定。
<action name="delete" class="example.CrudAction" method="delete">
如果没有execute方法,并且在action配置中没有指定其他的方法,action将抛出一个异常。
Wildcard Method(通配符方法):
很多情况下,一组action映射会公用一个通用的模板。举例来说,所有的edit action都会以“edit”开头,调用action中的edit方法,delete action使用同样的模板,只是调用的是delete方法。
另外一个通用的方法是将方法名作为后缀,并且通过惊叹号,下划线等特殊字符隔离处理。
例如:
"action=Crud_input"
"action=Crud_delete"
使用后缀名通配符,变成:
<action name="Crud_*" class="example.Crud" method="{1}">
动态方法调用不推荐使用,主要因为有两个原因,1、可能导致安全问题,2、与通配符方法可以替换。如果不适用动态方法调用,设置struts.enable.DynamicMethodInvocation=false
在action配置中,如果class属性为空,则默认class类为:com.opensymphony.xwork2.ActionSupport :
1)ActionSupport类有一个execute方法返回“success”,一个input方法返回“input”.
2) 如果要设置另外一个类作为默认的action实现类,则设置package的“default-class-ref”属性
Post-Back Default:(默认的回调)
最佳实践中,链接到一个action,而不是链接到一个页面。链接到action可以确保在页面加载之前完成渲染。
另外一个通常的流程是先使用其他的方法链接到页面,例如input方法等,然后再提交到默认的execute方法。
将以上这两种策略联合起来使用,就产生了post-back 表单,这种表单不定义任何的action,只是提交回产生它的那个action。
Action Default(默认的action):
通常情况下,如果一个request无法映射到相对应的action,就会产生一个通常的"404 - Page not found"错误。可以指定一个默认action,如果没有匹配的action处理request,则由这个默认的action来处理。
<package name="Hello" extends="action-default"> <default-action-ref name="UnderConstruction"/> <action name="UnderConstruction"> <result>/UnderConstruction.jsp</result> </action> ...
对于默认的action没有特殊的要求,每个package都可以有自己的默认action,但是每个namespace只能有一个。
WideCard Default:
默认通配符是另外一个实现默认action的方法,在配置的末尾放一个如下所示的通配符,可以捕获那些未匹配的请求。
<action name="*"> <result>/{1}.jsp</result> </action>
WideCards(通配符):
随着应用系统的规模不断变大,action mapping的数量也不断的变大。通配符可以被用来将多个相似的mapping合并到一个通用的mapping。
举个例子:
<action name="/edit*" class="org.apache.struts.webapp.example.Edit{1}Action"> <result name="failure">/mainMenu.jsp</result> <result>{1}.jsp</result> </action>
上面的例子中,所有以/edit开头的请求都会被匹配到。在“name"属性中的*可以匹配如/eidtSubscription,/editRegistion等类似的URI,但是无法匹配/editSubscription/add这样的请求。URI中被通配符匹配的部分被替换到不同的action mapping和action result。
框架按照配置文件中的顺序对request进行匹配,如果有多个mapping模板都可以匹配一个request,那么将用最后一个进行匹配。然而,如果request地址能匹配一个不带通配符的action,那么顺序将不重要,这个不带通配符的mapping将被匹配。
wildcards only match until the first occurrence of the following string pattern。举个例子来说:
<action name="List*s" class="actions.List{1}s"> <result>list{1}s.jsp</result> </action>
这个mapping能够正确的匹配ListAccounts 但是却无法匹配 ListSponsors,因为对于ListSponsors来说,将被转换为:
<action name="ListSpons" class="actions.ListSpons"> <result>listSpons.jsp</result> </action>
通配符可以包含一个或者多个下面的替代符:
在action mapping和action result中,通配符所匹配的值可以用{N}来代替,N是从1到9的数字。
Parameters In Namespaces(命名空间中的参数) :
通过设置<constant name="struts.patternMatcher" value="namedVariable"/>,可以将命名空间的值分解作为传递到action中的请求参数。例如:
@Namespace{"/users/{userID}"); public class DetailsAction exends ActionSupport { private Long userID; public void setUserID(Long userID) {...} }
如果一个请求是 /users/10/detail, 那么DetailsAction将会被执行,它的 userID 字段被设置为 10.
Action名字中的参数:
To use parameters in the URL, after the action name, make sure this is set:
<constant name="struts.enable.SlashesInActionNames" value="true"/> <constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
Then the action mapping will look like:
<package name="edit" extends="struts-default" namespace="/edit"> <action name="/person/*" class="org.apache.struts.webapp.example.EditAction"> <param name="id">{1}</param> <result>/mainMenu.jsp</result> </action> </package>
When a URL like /edit/person/123 is requested, EditAction will be called, and its "id" field will be set to 123.
Result Cofniguration:
Action方法执行完毕以后,会返回一个字符串。字符串的值用来选择一个Result元素。在ActionSupport中定义了以下几种Result替代符:
除此之外,应用还可以定义其他的Result替代符。
Result Element:
Result element有两个用途:1是提供了一个逻辑名字,action可以传回一个”success“或者”error“的替代符,而不用知道实现的细节。2是提供了一种结果类型。
Dynamic Results:
<action name="fragment" class="FragmentAction"> <result name="next" type="redirectAction">${nextAction}</result> </action>
如果返回”next“,则值就是FragmentAction类中nextAction属性的值。