-Interceptor
Interceptor(拦截器)将在一个action的方法执行之前或之后执行。多个Interceptor可以组成一个Interceptor Stack。
<
interceptors
>
<
interceptor
name="security" class="com.company.security.SecurityInterceptor"/>
<
interceptor-stack
name="secureStack">
<
interceptor-ref
name="security"/>
<
interceptor-ref
name="defaultStack"/>
</
interceptor-stack
>
</
interceptors
>
|
name : interceptor的唯一标识
class : interceptor所对应的java类
定义一个interceptors stack 可以用多个 interceptor、interceptors stack进行不同顺序的组成。
调用一个interceptors stack 时,会根据顺序一个一个调用内部的interceptor。
-Action
Action Mappings
action mapping用于当一个收到请求时,找到处理该请求使用的类。
name(必须) :用于唯一的标识一个action配置 class:指定对应的java类 当没有指定class的时候,则会默认为com.opensymphony.xwork2.ActionSupport,也可以在配置文件中修改默认的class.
还可以为action指定多个result、interceptor
<action name="Logon"
class
="tutorial.Logon">
<result type="redirectAction">Menu</result>
<result name="input">/Logon.jsp</result>
</action>
|
Action Names
在web应用中,name是由一个url中去掉host、application name,根据配置的规则匹配中间的字段如,http://www.planetstruts.org/struts2-mailreader/Welcome.do 将会匹配名为welcome的action。
当需要链接到一个action时,通常使用struts标签,则只需要指定一个action,struts会自动将其转换成对应的url。
<s:form action="Hello">
<s:textfield label="Please enter your name" name="name"/>
<s:submit/>
</s:form>
|
当antion的name中存在“/”时,如:<action name="admin/home" class="tutorial.Admin"/>,你需要在配置文件struts.xml中进行如下设置<constant name="struts.enable.SlashesInActionNames" value="true"/>来允许name中使用“/”。
name中最好不要出现“.”和“-”,可以用其他方式替代如:create.user -> createUser , my-aciton -> my_action.
Action Methods
action的接口定义如下:
public
interface
Action {
public
String execute()
throws
Exception;
}
|
struts不强制要实现action接口,当action不是实现这个接口时会使用反射来找到execute方法。
通常一个action会有多个方法,不止一个execute方法,例如 data_access 这个Action,通常会有 create
, retrieve
, update
, and delete这些方法,可以在action配置中指定要使用的方法
<
action
name="delete" class="example.CrudAction" method="delete">
...
|
Wildcard Method (通配符)
通常一些action的映射方式遵循着特定的模式,如edit开头的action通常会调用其edit方法,delete开头的aciton会调用其delete方法。
这种情况可以使用通配符来避免重复对每个action进行定义。
<
action
name="*Crud" class="example.Crud" method="{1}">
...
|
{1}对应前面通配符*的值,如editCrud对应调用的方法则为edit
Post-Back Default
好的链接做法是指向一个action而不是page。
Another common workflow stategy is to first render a page using an alternate method, like input
and then have it submit back to the default execute
method.
Using these two strategies together creates an opportunity to use a "post-back" form that doesn't specify an action. The form simply submits back to the action that created it.
<s:form>
<s:textfield label="Please enter your name" name="name"/>
<s:submit/>
</s:form>
|
Action Default
当请求一个action找不到对应的映射时,则会报出“404 - page not found”错误。你可以通过指定一个default action,当action无法映射成功的时候会自动调用这个action进行处理。
<
package
name="Hello" extends="action-default">
<
default-action-ref
name="UnderConstruction"/>
<
action
name="UnderConstruction">
<
result
>/UnderConstruction.jsp</
result
>
</
action
>
...
|
对于default action没有任何的要求,每一个package都可以有一个自己的default action。
*每一个namespace都应该只有一个 default action。
-Result
当一个action执行完毕后会返回一个String,其值用于选择一个result。action配置中通常有多个result代表这不同可能的结果。在基本类ActionSupport中定义了几种标准的result类型。
String SUCCESS = "success";
String NONE = "none";
String ERROR = "error";
String INPUT = "input";
String LOGIN = "login";
|
若action执行完毕后返回 ActionSupport.NONE 或者 null 将跳过result处理阶段。这可以用来让一个action独自处理一个请求的返回结果。
Result Elements
result 配置中 name用于与action执行后返回的String匹配来选择result的处理方式, type用于指定结果处理类型,大多数结果处理都是简单的跳转至一个page,使用更多的 resulte types 可以做许多的有趣的事。
每个package 都会设置一个默认的 result type ,在没有指定result type的时默认使用.
<result-types>
<result-type name="dispatcher"
default
="
true
"
class
="org.apache.struts2.dispatcher.ServletDispatcherResult" />
</result-types>
|
type没有指定的时候,struts默认使用的是dispatcher类型,用于跳转至另外一个web资源。
name没有指定的话,默认的name则是“success”。
使用这些默认值,可以使配置代码变得简短。
<
result
name="success" type="dispatcher">
<
param
name="location">/ThankYou.jsp</
param
>
</
result
>
|
<
result
>
<
param
name="location">/ThankYou.jsp</
param
>
</
result
>
|
The param
tag sets a property on the Result object. The most commonly-set property is location
, which usually specifies the path to a web resources. The param
attribute is another intelligent default.
<
result
>/ThankYou.jsp</
result
>
|
name为"*". 表示当匹配不到时,则选择这个resulte进行处理。
<
action
name="Hello">
<
result
>/hello/Result.jsp</
result
>
<
result
name="error">/hello/Error.jsp</
result
>
<
result
name="input">/hello/Input.jsp</
result
>
<
result
name="*">/hello/Other.jsp</
result
>
</
action
>
|
name中的"*" 不是一个通配符
在大多数情况下,如果一个action返回一个未知的result name,则表示程序出错,应该修正。
Global Results
通常result配置在一个action中. 但是有些result出现在多个action中.在一个安全的应用中, 客户端可能会试图访问一个未授权的页面, 则一些action应该返回一个 "logon" result.
当多个action需要共用result,可以在每个package中定义全局的result. Struts会先在action的局部result寻找匹配,匹配不成功的话, 再去全局result中寻找.
<
global-results
>
<
result
name="error">/Error.jsp</
result
>
<
result
name="invalid.token">/Error.jsp</
result
>
<
result
name="login" type="redirectAction">Logon!input</
result
>
</
global-results
>
|
Dynamic Results
result可以在运行期间再确定. Struts2容器是一种基于执行流的状态机; 任何输入,会话属性,用户类型等等的组合都可能决定下一个状态 。换句话说, 在配置的时候不一定能确定下一个action,输入页面等等。
Result 的值可以通过使用EL表达式来访问对应的action的属性来确定,就像struts2的标签库. 例如:
private
String nextAction;
public
String getNextAction() {
return
nextAction;
}
|
你可以这样定义一个result:
<
action
name="fragment" class="FragmentAction">
<
result
name="next" type="redirectAction">${nextAction}</
result
>
</
action
>
|
如果FragmentAction
的方法返回"next",result的真实的值将是FragmentAction中的
nextAction
属性的值. 所以 nextAction
可以根据任意需要的状态信息来确定下一个跳转至的action。
public
interface
Action {
public
String execute()
throws
Exception;
}
|
Implementing the Action interface is optional. If Action is not implemented, the fra
<
action
name="*Crud" class="example.Crud" method="{1}">
...
|
Here, a reference to "editCrud" will call the edit
method on an instance of the Crud Action class. Likewise, a reference to "deleteCrud" will
<
package
name="Hello" extends="action-default">
<
default-action-ref
name="UnderConstruction"/>
<
action
name="UnderConstruction">
<
result
>/UnderConstruction.jsp</
result
>
</
action
>
...
|
There are no special requirements for the default action. Each p