原文鏈接:http://blog.csdn.net/qq_22329521/article/details/74547658
第一步導(dǎo)包瞧省,不多說了
第二步配置struts2文件
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!--
package:將Action配置封裝绒净,就是可以在Package中配置很多action
name:給包起名字潘飘,起到標(biāo)識(shí)作用,隨便起娘荡,不能其包名重復(fù)
namespace屬性:給action的訪問路徑定義一個(gè)命名空間
extends屬性:繼承一個(gè)指定包(struts-default在struts2-core jar包下有struts-default.xml中有package struts-default)
abstract屬性:包是否為抽象的橘沥;標(biāo)識(shí)性屬性。標(biāo)識(shí)該包不能獨(dú)立運(yùn)行苹丸。專門被繼承
-->
<package name="hello" namespace="/hello" extends="struts-default">
<!-- action 元素:配置action類
name屬性:決定了返回Action訪問資源名
class屬性:action的完整類名
method屬性:指定調(diào)用action中的那個(gè)方法來處理請(qǐng)求-->
<action name="HelloAction" class="com.fmt.struct.HelloAction" method="hello">
<!--result 元素:結(jié)果配置
name:標(biāo)識(shí)結(jié)果處理的名稱:與action的返回值對(duì)應(yīng)
type屬性:指定調(diào)用那個(gè)result類來處理結(jié)果默認(rèn)使用轉(zhuǎn)發(fā)(在繼承的struts-default包中有result的配置已經(jīng)設(shè)置好了)(type提供重定向,轉(zhuǎn)發(fā)苇经,重定向action赘理,轉(zhuǎn)發(fā)action)
標(biāo)簽體:填寫頁面的相對(duì)路徑-->
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
</package>
</struts>
web.xml中配置struts2核心過濾器
<!-- struts2 核心過濾器-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
public class HelloAction {
public String hello(){
System.out.println("hello");
return "success";
}
}
訪問http://localhost:8080/structs2/hello/HelloAction,就訪問成功了
默認(rèn)配置
如果 一些必要參數(shù)沒寫扇单,默認(rèn)加載的是struts-default下的配置com.opensymphony.xwork2.ActionSupport 這個(gè)類
<struts>
<package name="default" namespace="/default" extends="struts-default" >
<!-- 找不到包下的action,會(huì)使用Demo2Action作為默認(rèn)action處理請(qǐng)求 -->
<default-action-ref name="Demo2Action"></default-action-ref>
<!-- method屬性:execute -->
<!-- result的name屬性:success -->
<!-- result的type屬性:dispatcher 轉(zhuǎn)發(fā) -->
<!-- class屬性:com.opensymphony.xwork2.ActionSupport -->
<action name="Demo2Action" >
<result >/hello.jsp</result>
</action>
</package>
</struts>
struts常量配置
struts的基本常量是在struts2-corejar中的org.apache.struts2中的default.properties中有基本的常量
外部修改常量的三種方式
- 在之前struts.xml的<struts>標(biāo)簽下填寫
<!--i18:國際化商模,解決post提交亂碼-->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!--指定訪問action時(shí)的后綴名
如果value改為do:http://....../HelloAction.do
-->
<constant name="struts.action.extension" value="action,,"></constant>
<!--是否是開發(fā)模式(更多的好處可以在default.properties文件下看)
1,可以熱加載配置(不需要重啟服務(wù))
2.提供了更多的錯(cuò)誤信息,方便開發(fā)時(shí)的調(diào)試
-->
<constant name="struts.devMode" value="true"></constant>
- 在src目錄下創(chuàng)建strtus.properties蜘澜,然后填寫鍵值對(duì)如
struts.i18n.encoding=UTF-8
- 在web.xml中填寫
<context-param>
<param-name>struts.i18n.encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
加載的順序是依次加載的
如果要引入其他配置
在當(dāng)前struct標(biāo)簽下加入
<include file="com/fmt/struct/struts.xml"/>
動(dòng)態(tài)訪問一個(gè)類
public class Demo1Action {
public String add(){
System.out.println("add");
return "success";
}
public String delete(){
System.out.println("delete");
return "success";
}
public String change(){
System.out.println("change");
return "success";
}
public String find(){
System.out.println("find");
return "success";
}
}
根據(jù)url訪問的話配置
配置一
<package name="dynamic" namespace="/dynamic" extends="struts-default">
<action name="Demo1Action_add" class="com.fmt.b_dynamic.Demo1Action"
method="add">
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
<action name="Demo1Action_delete" class="com.fmt.b_dynamic.Demo1Action"
method="delete">
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
....
</package>
//上訴的配置顯然比較累贅
配置二
<!--配置動(dòng)態(tài)方法調(diào)用常量
默認(rèn)是關(guān)閉的施流,需要重啟
-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<package name="dynamic" namespace="/dynamic" extends="struts-default">
<action name="Demo1Action" class="com.fmt.b_dynamic.Demo1Action"
>
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
</package>
訪問的url 為http://......//Demo1Action!delete
http://......//Demo1Action!add
...
//上面注意點(diǎn)是帶!感嘆號(hào)的 這種也是不怎么用的的,搜索引擎在搜索的時(shí)候可能因?yàn)槟氵@路徑的特點(diǎn)鄙信,不會(huì)收錄下啦
配置3:通配符
<package name="dynamic" namespace="/dynamic" extends="struts-default">
<!--動(dòng)態(tài)調(diào)用方式瞪醋,使用通配符的樣子-->
<action name="Demo1Action_*" class="com.fmt.b_dynamic.Demo1Action"
method="{1}">
<result name="success" type="dispatcher">/hello.jsp</result>
</action>
</package>
為http://......//Demo1Action_delete http://......//Demo1Action_add
ServetApi
獲取request 這些的方式
public class DemoAction extends ActionSupport {
@Override
public String execute() throws Exception {
//session域
Map<String, Object> session = ActionContext.getContext().getSession();
session.put("name","session");
//application
Map<String, Object> application = ActionContext.getContext().getApplication();
application.put("name","application");
/**
* //request域(struct2并不推薦使用原生的request域中)
Map<String, Object> request = (Map<String, Object>) ActionContext.getContext().get("request");
*/
//直接使用,推薦
ActionContext.getContext().put("name","request域");
return super.execute();
}
public String execute1() throws Exception {
//原生的request(這些內(nèi)部實(shí)際還是從ActionContext中獲取)
javax.servlet.http.HttpServletRequest request = ServletActionContext.getRequest();
//原生的Response
HttpServletResponse response = ServletActionContext.getResponse();
//原生的ServletContext
ServletContext servletContext = ServletActionContext.getServletContext();
//獲取session對(duì)象
HttpSession session = request.getSession();
return super.execute();
}
}
如果不希望每個(gè)方法都手動(dòng)調(diào)用獲取request可以采用下面方式
public class DemoAction extends ActionSupport implements ServletRequestAware{
HttpServletRequest request;
@Override
public String execute() throws Exception {
}
@Override
public void setServletRequest(HttpServletRequest httpServletRequest) {
this.request=httpServletRequest;
}
}
直接實(shí)現(xiàn)接口接可以了
原因在于 我們配置了的action 繼承與struts-default
然后在struts-default
其中interceptor-stack是個(gè)攔截棧装诡,我們查看servletConfig 所對(duì)應(yīng)的對(duì)象他的class是 org.apache.struts2.interceptor.ServletConfigInterceptor
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();
ActionContext context = invocation.getInvocationContext();
HttpServletRequest request;
//這里就是攔截器做的操作银受,如果我們當(dāng)前這個(gè)action實(shí)現(xiàn)了這個(gè)接口,默認(rèn)調(diào)用
if(action instanceof ServletRequestAware) {
request = (HttpServletRequest)context.get("com.opensymphony.xwork2.dispatcher.HttpServletRequest");
((ServletRequestAware)action).setServletRequest(request);
}
if(action instanceof ServletResponseAware) {
HttpServletResponse response = (HttpServletResponse)context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse");
((ServletResponseAware)action).setServletResponse(response);
}
.....
獲取參數(shù)
- 通過成員變量獲取
//http://localhost:8080/structs2/api/xxxx?name=tom
public class DemoAction extends ActionSupport{
@Override
public String execute() throws Exception {
System.out.println(name);
return super.execute();
}
public String name;
public String getName(){
return name;
}
public void setName(String name) {
this.name = name;
}
//每次訪問一個(gè)action的時(shí)候會(huì)new一個(gè)action對(duì)象出來
public DemoAction() {
System.out.println("init");
}
}
- 封裝一個(gè)對(duì)象來獲取
//http://localhost:8080/structs2/xxx?mUser.name=tom&mUser.age=123
public class User {
public String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class DemoAction extends ActionSupport{
public User mUser
@Override
public String execute() throws Exception {
System.out.println(mUser.toString());
return super.execute();
}
public User getmUser() {
return mUser;
}
public void setmUser(User mUser) {
this.mUser = mUser;
}
}
但是帶mUser.這種參數(shù)提交方式很奇怪 慎王。
- 模型驅(qū)動(dòng)
//http://localhost:8080/structs2/api/xxx?name=tom&age=123
public class DemoAction extends ActionSupport implements ModelDriven<User>{
public User mUser=new User();
public String execute() throws Exception {
System.out.println(mUser.toString());
return super.execute();
}
@Override
public User getModel() {
return mUser;
}
}
OGNL語法
OGNL是Object-Graph Navigation Language的縮寫蚓土,全稱為對(duì)象圖導(dǎo)航語言宏侍,是一種功能強(qiáng)大的表達(dá)式語言赖淤,它通過簡單一致的語法,可以任意存取對(duì)象的屬性或者調(diào)用對(duì)象的方法谅河,能夠遍歷整個(gè)對(duì)象的結(jié)構(gòu)圖咱旱,實(shí)現(xiàn)對(duì)象屬性類型的轉(zhuǎn)換等功能确丢。
OGNL表達(dá)式的計(jì)算是圍繞OGNL上下文進(jìn)行的。
@Test
public void fun1() throws OgnlException {
User rootUser=new User("root",12);
HashMap<String, User> context = new HashMap<>();
context.put("user1",new User("root1",13));
context.put("user2",new User("root2",14));
OgnlContext ognlContext = new OgnlContext();
ognlContext.setRoot(rootUser);
ognlContext.setValues(context);
//取出root中user對(duì)象的name屬性
String name= (String) Ognl.getValue("name",context,ognlContext.getRoot());
Integer age= (Integer) Ognl.getValue("age",context,ognlContext.getRoot());
System.out.println(name+"age="+age);
//#是從context中取值user1位鍵
String name1= (String) Ognl.getValue("#user1.name",context,ognlContext.getRoot());
Integer age1= (Integer) Ognl.getValue("#user1.age",context,ognlContext.getRoot());
System.out.println(name1+"age="+age1);
//修改Root中的值
String name2= (String) Ognl.getValue("name='jack'",context,ognlContext.getRoot());
Integer age2= (Integer) Ognl.getValue("age",context,ognlContext.getRoot());
System.out.println(name2+"age="+age2);
//修改Root中的值
String name3= (String) Ognl.getValue("#user1.name='tom'",context,ognlContext.getRoot());
Integer age3= (Integer) Ognl.getValue("#user1.age",context,ognlContext.getRoot());
System.out.println(name3+"age="+age3);
//調(diào)用root中的對(duì)象方法
Ognl.getValue("setName('lilei')",context,ognlContext.getRoot());
String name4= (String) Ognl.getValue("getName()",context,ognlContext.getRoot());
System.out.println(name4);
//調(diào)用map中的對(duì)象方法
String name5= (String) Ognl.getValue("#user1.setName('11'),#user1.getName()",context,ognlContext.getRoot());
System.out.println(name5);
//調(diào)用靜態(tài)方法
String name6=(String)Ognl.getValue("@com.fmt.Utils@echo('hello world')",context,ognlContext.getRoot());
System.out.println(name6);
//調(diào)用靜態(tài)方法
Double pi=(Double)Ognl.getValue("@@PI",context,ognlContext.getRoot());
System.out.println(pi);
//創(chuàng)建對(duì)象
Integer size= (Integer) Ognl.getValue("{'1','2','3','4'}.size()",context,ognlContext.getRoot());
System.out.println(size);
Character number= (Character) Ognl.getValue("{'1','2','3','4'}[2]",context,ognlContext.getRoot());
System.out.println(number);
Character number1= (Character) Ognl.getValue("{'1','2','3','4'}.get(2)",context,ognlContext.getRoot());
System.out.println(number1);
//創(chuàng)建map
Integer map_size= (Integer) Ognl.getValue("#{'name':'tom','age':18}.size()",context,ognlContext.getRoot());
System.out.println(map_size);
}
ValueStack
ValueStack是一個(gè)接口吐限,在struts2中使用OGNL(Object-Graph Navigation Language)表達(dá)式實(shí)際上是使用,實(shí)現(xiàn)了ValueStack接口的類OgnlValueStack.它是ValueStack的默認(rèn)實(shí)現(xiàn)類.
public interface ValueStack {
....
Map<String, Object> getContext();
...
CompoundRoot getRoot();
...
}
public class CompoundRoot extends ArrayList {
public CompoundRoot() {
}
public CompoundRoot(List list) {
super(list);
}
public CompoundRoot cutStack(int index) {
return new CompoundRoot(this.subList(index, this.size()));
}
public Object peek() {
return this.get(0);
}
public Object pop() {
return this.remove(0);
}
public void push(Object o) {
this.add(0, o);
}
}
- ValueStack貫穿整個(gè)action的生命周期鲜侥,每一個(gè)action實(shí)例都擁有一個(gè)ValueStack對(duì)象,其中保存了當(dāng)前action對(duì)象和其他相關(guān)對(duì)象.
- struts2把ValueStack對(duì)象保存在名為:struts.valueStack的request域中.即ValueStack作用域?yàn)閞equest.當(dāng)action創(chuàng)建的時(shí)候诸典,ValueStack就創(chuàng)建了描函,action被銷毀的時(shí)候,ValueStack就銷毀了
- ValueStack中的數(shù)據(jù)分兩部分存放:root(棧結(jié)構(gòu)狐粱,CompoundRoot)和context(map形式,OgnlContext)
分析流程
首先是web.xml 中配置了攔截器舀寓,攔截了請(qǐng)求到StrutsPrepareAndExecuteFilter
<!-- struts2 核心過濾器-->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
//StrutsPrepareAndExecuteFilter
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
try {
if(this.excludedPatterns != null && this.prepare.isUrlExcluded(request, this.excludedPatterns)) {
chain.doFilter(request, response);
} else {
//設(shè)置編碼和國際化
this.prepare.setEncodingAndLocale(request, response);
//創(chuàng)建actionContext上下文(ActionContext,其實(shí)通過ThreadlLocal線程內(nèi)部維護(hù)所以不會(huì)出現(xiàn)不同action,共享的問題)
this.prepare.createActionContext(request, response);
this.prepare.assignDispatcherToThread();
//這是request的包裝類StrutsRequestWrapper肌蜻,重寫了getAttribute的方法(先從request取互墓,如果沒有再次value stack的棧取,最后從actioncntext冉选)
request = this.prepare.wrapRequest(request);
//創(chuàng)建ActionMaping對(duì)象(是當(dāng)前請(qǐng)求信息映射為一個(gè)對(duì)象)(ActionMaping的創(chuàng)建是通過ActionMapper的getMapping方法篡撵,而ActionMapper的默認(rèn)實(shí)現(xiàn)是DefaultActionMapper可以從這個(gè)類的getMaping方法中查看,答題是解析url構(gòu)建mappig對(duì)象)
ActionMapping mapping = this.prepare.findActionMapping(request, response, true);
//如果解析出來是null 則不會(huì)調(diào)用action豆挽,直接放行
if(mapping == null) {
boolean handled = this.execute.executeStaticResourceRequest(request, response);
if(!handled) {
chain.doFilter(request, response);
}
} else {
//執(zhí)行action
this.execute.executeAction(request, response, mapping);
}
}
} finally {
this.prepare.cleanupRequest(request);
}
}
public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
Integer counter = Integer.valueOf(1);
Integer oldCounter = (Integer)request.getAttribute("__cleanup_recursion_counter");
if(oldCounter != null) {
counter = Integer.valueOf(oldCounter.intValue() + 1);
}
//從本地的ThreadLocal中獲取
ActionContext oldContext = ActionContext.getContext();
ActionContext ctx;
if(oldContext != null) {
ctx = new ActionContext(new HashMap(oldContext.getContextMap()));
} else {
// 創(chuàng)建了ValueStack
ValueStack stack = ((ValueStackFactory)this.dispatcher.getContainer().getInstance(ValueStackFactory.class)).createValueStack();
//ValueStack 中context放置了一地參數(shù) 進(jìn)入createContextMap內(nèi)部一對(duì)map育谬,有application,params帮哈,session等
stack.getContext().putAll(this.dispatcher.createContextMap(request, response, (ActionMapping)null));
//返回ActionContext實(shí)際還是ValuesStack中的context的
ctx = new ActionContext(stack.getContext());
}
request.setAttribute("__cleanup_recursion_counter", counter);
ActionContext.setContext(ctx);
return ctx;
}
//執(zhí)行 this.execute.executeAction(request, response, mapping); 最終進(jìn)入
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
Map<String, Object> extraContext = this.createContextMap(request, response, mapping);
ValueStack stack = (ValueStack)request.getAttribute("struts.valueStack");
boolean nullStack = stack == null;
if(nullStack) {
ActionContext ctx = ActionContext.getContext();
if(ctx != null) {
stack = ctx.getValueStack();
}
}
if(stack != null) {
extraContext.put("com.opensymphony.xwork2.util.ValueStack.ValueStack", this.valueStackFactory.createValueStack(stack));
}
String timerKey = "Handling request from Dispatcher";
try {
UtilTimerStack.push(timerKey);
String namespace = mapping.getNamespace();
String name = mapping.getName();
String method = mapping.getMethod();
//此次根據(jù)actinMapping的action信息構(gòu)建action的代理
ActionProxy proxy = ((ActionProxyFactory)this.getContainer().getInstance(ActionProxyFactory.class)).createActionProxy(namespace, name, method, extraContext, true, false);
request.setAttribute("struts.valueStack", proxy.getInvocation().getStack());
if(mapping.getResult() != null) {
Result result = mapping.getResult();
result.execute(proxy.getInvocation());
} else {
//代理執(zhí)行(ActionProxy實(shí)現(xiàn)類StrutsActionProxy)
proxy.execute();
}
if(!nullStack) {
request.setAttribute("struts.valueStack", stack);
}
} catch (ConfigurationException var17) {
this.logConfigurationException(request, var17);
this.sendError(request, response, 404, var17);
} catch (Exception var18) {
if(!this.handleException && !this.devMode) {
throw new ServletException(var18);
}
this.sendError(request, response, 500, var18);
} finally {
UtilTimerStack.pop(timerKey);
}
}
//StrutsActionProxy
public String execute() throws Exception {
ActionContext previous = ActionContext.getContext();
ActionContext.setContext(this.invocation.getInvocationContext());
String var2;
try {
//當(dāng)前的invocation 實(shí)現(xiàn)類為DefaultActionInvocation
var2 = this.invocation.invoke();
} finally {
if(this.cleanupContext) {
ActionContext.setContext(previous);
}
}
return var2;
}
//DefaultActionInvocation
public String invoke() throws Exception {
String profileKey = "invoke: ";
String var21;
try {
UtilTimerStack.push(profileKey);
if(this.executed) {
throw new IllegalStateException("Action has already executed");
}
//攔截器組這里使用if 和 interceptor.getInterceptor().intercept(this);是遞歸的操作
if(this.interceptors.hasNext()) {
//依次獲取攔截器 然后執(zhí)行攔截器的intercept方法 然后我們看下struts-default.xml文件中的 <interceptor-stack name="defaultStack"> 下的攔截器
InterceptorMapping interceptor = (InterceptorMapping)this.interceptors.next();
String interceptorMsg = "interceptor: " + interceptor.getName();
UtilTimerStack.push(interceptorMsg);
try {
this.resultCode = interceptor.getInterceptor().intercept(this);
} finally {
UtilTimerStack.pop(interceptorMsg);
}
} else {
//之前的攔截器完成斑司,進(jìn)入我們的action
this.resultCode = this.invokeActionOnly();
}
//同上根據(jù)返回走返回的一對(duì)攔截器
if(!this.executed) {
if(this.preResultListeners != null) {
Iterator i$ = this.preResultListeners.iterator();
while(i$.hasNext()) {
Object preResultListener = (PreResultListener)i$.next();
PreResultListener listener = (PreResultListener)preResultListener;
String _profileKey = "preResultListener: ";
try {
UtilTimerStack.push(_profileKey);
listener.beforeResult(this, this.resultCode);
} finally {
UtilTimerStack.pop(_profileKey);
}
}
}
if(this.proxy.getExecuteResult()) {
this.executeResult();
}
this.executed = true;
}
var21 = this.resultCode;
} finally {
UtilTimerStack.pop(profileKey);
}
return var21;
}
protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {
String methodName = this.proxy.getMethod();
。但汞。宿刮。
//ognl表達(dá)式直接掉方法
methodResult = this.ognlUtil.getValue(methodName + "()", this.getStack().getContext(), action);
。私蕾。僵缺。
String var22 = this.saveResult(actionConfig, methodResult);
return var22;
}
已exception 是 defaultStack攔截器組下第一個(gè)攔截器 對(duì)應(yīng)的class是com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor
public String intercept(ActionInvocation invocation) throws Exception {
String result;
try {
//這里的invocation.invoke();就是上面過來的this,形成遞歸
result = invocation.invoke();
} catch (Exception var7) {
if(this.isLogEnabled()) {
this.handleLogging(var7);
}
....
攔截器使用
//使用攔截器的方式 實(shí)現(xiàn)Interceptor踩叭,繼承AbstractInterceptor 以及繼承MethodFilterInterceptor磕潮,三種這邊直接使用第三種
public class MyIntercept3 extends MethodFilterInterceptor{
@Override
protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
System.out.println("處理前");
//放行
actionInvocation.invoke();
System.out.println("處理后");
// return 的意義在于如果你不放行直接返回給result如果放行成功,這個(gè)return就沒有意義
return "success";
}
}
xml中配置
<package name="hello" namespace="/hello" extends="struts-default">
<interceptors>
<!--注冊(cè)攔截器-->
<interceptor name="MyInter3" class="com.fmt.intercept.MyIntercept3"></interceptor>
<!--注冊(cè)攔截棧-->
<interceptor-stack name="mystack" >
<!-- 自定義攔截器-->
<interceptor-ref name="MyInter3">
<!--指定那些方法不攔截-->
<param name="excludeMethods">add,delete</param>
<!--指定那些方法 攔截-->
<param name="includeMethods">change</param>
</interceptor-ref>
<!--引用默認(rèn)的20個(gè)攔截器-->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="mystack">
</default-interceptor-ref>
<action name="HelloAction" class="com.fmt.struct.HelloAction" method="hello">
<interceptor-ref name="mystack"></interceptor-ref>
<result name="success">/showjs.jsp</result>
</action>
</package>
參考文章
http://blog.csdn.net/tjcyjd/article/details/6850203
http://501565246-qq-com.iteye.com/blog/1748513