??xml version="1.0" encoding="utf-8" standalone="yes"?>精品一区二区三区免费毛片,亚洲国产第一页,在线欧美一区http://www.aygfsteel.com/fantasy/category/38008.htmlWeb 2.0 技术储?...........zh-cnMon, 02 Mar 2009 13:53:32 GMTMon, 02 Mar 2009 13:53:32 GMT60(?拦截器深入实?/title><link>http://www.aygfsteel.com/fantasy/articles/257349.html</link><dc:creator>Web 2.0 技术资?/dc:creator><author>Web 2.0 技术资?/author><pubDate>Mon, 02 Mar 2009 07:24:00 GMT</pubDate><guid>http://www.aygfsteel.com/fantasy/articles/257349.html</guid><wfw:comment>http://www.aygfsteel.com/fantasy/comments/257349.html</wfw:comment><comments>http://www.aygfsteel.com/fantasy/articles/257349.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/fantasy/comments/commentRss/257349.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/fantasy/services/trackbacks/257349.html</trackback:ping><description><![CDATA[<div id="wmqeeuq" class="content"><a >转自Qhttp://www.javaeye.com/wiki/struts2/1397-deep-into-struts2-interceptors#top</a><br /> <br /> 在之前的文章中,我们已经涉及C拦截器(InterceptorQ的概念?<br /> <br /> <div id="wmqeeuq" class="quote_title">downpour 写道</div> <div id="wmqeeuq" class="quote_div">拦截器是AOP中的概念Q它本n是一D代码,可以通过定义“l入?#8221;Q来指定拦截器的代码?#8220;l入?#8221;的前后执行,从而v到拦截的作用。正如上?Struts2的Reference中讲q的QStruts2的InterceptorQ其拦截的对象是Action代码Q可以定义在Action代码之前或者之后执行拦截器的代码?</div> <br /> <br /> 接下来,我们重点讨Z下Struts2中的拦截器的内部l构和执行顺序,q结合源码进行分析?</div> <div class="wmqeeuq" id="wiki_menu"> <h4>??<a title="隐藏/昄目录" onclick="$$('#wiki_menu ol')[0].toggle();return false;" ><small>[ - ]</small></a></h4> <ol> <li><a >Interceptorl构</a> <li><a >Interceptor执行分析</a> <li><a >源码解析</a> </li> </ol> </div> <h2>Interceptorl构 <a name="1678"><img alt="Top" src="http://www.javaeye.com/images/wiki/top.gif?1229402183" /></a> </h2> <div id="wmqeeuq" class="content">让我们再来回一下之前我们曾l用q的一张Action LifeCycle的图Q?<br /> <br /> <img alt="" src="http://www.javaeye.com/upload/attachment/68182/ae963ed3-fae7-3710-bfcf-2fc49942ee90.png" /> <br /> <br /> 图中Q我们可以发玎ͼStruts2的Interceptor一层一层,把Action包裹在最里面。这Ll构Q大概有以下一些特点: <br /> <br /> <strong>1. 整个l构如同一个堆栈,除了Action以外Q堆栈中的其他元素是Interceptor</strong> <br /> <br /> <strong>2. Action位于堆栈的底部。由于堆?先进后出"的特性,如果我们试图把Action拿出来执行,我们必须首先把位于Action上端的Interceptor拿出来执行。这P整个执行Ş成了一个递归调用</strong> <br /> <br /> <strong>3. 每个位于堆栈中的InterceptorQ除了需要完成它自n的逻辑Q还需要完成一个特D的执行职责。这个执行职责有3U选择Q?<br /> <br /> <span style="color: blue">1) 中止整个执行Q直接返回一个字W串作ؓresultCode</span> <br /> <br /> <span style="color: blue">2) 通过递归调用负责调用堆栈中下一个Interceptor的执?/span> <br /> <br /> <span style="color: blue">3) 如果在堆栈内已经不存在Q何的InterceptorQ调用Action</span> <br /> </strong><br /> <br /> Struts2的拦截器l构的设计,实际上是一个典型的<strong>责Q链模?/strong>的应用。首先将整个执行划分成若q相同类型的元素Q每个元素具备不同的逻辑责QQƈ他们纳入到一个链式的数据l构中(我们可以把堆栈结构也看作是一个递归的链式结构)Q而每个元素又有责任负责链式结构中下一个元素的执行调用?<br /> <br /> q样的设计,从代码重构的角度来看Q实际上是将一个复杂的pȝQ分而治之,从而得每个部分的逻辑能够高度重用q具备高度可扩展性。所以,Interceptorl构实在是Struts2/Xwork设计中的_֍之笔?</div> <h2>Interceptor执行分析 <a name="1679"><img alt="Top" src="http://www.javaeye.com/images/wiki/top.gif?1229402183" /></a> </h2> <div id="wmqeeuq" class="content"><strong><span style="color: blue">Interceptor的定?/span></strong> <br /> <br /> 我们来看一下Interceptor的接口的定义Q?<br /> <br /> <div id="wmqeeuq" class="dp-highlighter"> <div id="wmqeeuq" class="bar"> <div id="wmqeeuq" class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">interface</span><span> Interceptor </span><span id="wmqeeuq" class="keyword">extends</span><span> Serializable {   </span></span> <li><span>  </span> <li><span>    </span><span id="wmqeeuq" class="comment">/** </span> </span> <li><span><span id="wmqeeuq" class="comment">     * Called to let an interceptor clean up any resources it has allocated. </span> </span> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span> <li><span>    </span><span id="wmqeeuq" class="keyword">void</span><span> destroy();   </span></span> <li><span>  </span> <li><span>    </span><span id="wmqeeuq" class="comment">/** </span> </span> <li><span><span id="wmqeeuq" class="comment">     * Called after an interceptor is created, but before any requests are processed using </span> </span> <li><span><span id="wmqeeuq" class="comment">     * {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving </span> </span> <li><span><span id="wmqeeuq" class="comment">     * the Interceptor a chance to initialize any needed resources. </span> </span> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span> <li><span>    </span><span id="wmqeeuq" class="keyword">void</span><span> init();   </span></span> <li><span>  </span> <li><span>    </span><span id="wmqeeuq" class="comment">/** </span> </span> <li><span><span id="wmqeeuq" class="comment">     * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the </span> </span> <li><span><span id="wmqeeuq" class="comment">     * request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code. </span> </span> <li><span><span id="wmqeeuq" class="comment">     * </span> </span> <li><span><span id="wmqeeuq" class="comment">     * @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself. </span> </span> <li><span><span id="wmqeeuq" class="comment">     * @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}. </span> </span> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span> <li><span>    String intercept(ActionInvocation invocation) </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception;   </span></span> <li><span>}  </span> </li> </ol> </div> <pre class="java" style="display: none" name="code">public interface Interceptor extends Serializable { /** * Called to let an interceptor clean up any resources it has allocated. */ void destroy(); /** * Called after an interceptor is created, but before any requests are processed using * {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving * the Interceptor a chance to initialize any needed resources. */ void init(); /** * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the * request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code. * * @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself. * @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}. */ String intercept(ActionInvocation invocation) throws Exception; } </pre> <br /> <br /> Interceptor的接口定义没有什么特别的地方Q除了init和destoryҎ以外QinterceptҎ是实现整个拦截器机制的核心方法。而它所依赖的参数ActionInvocation则是我们之前章节中曾l提到过的著名的<strong>Action调度?/strong>?<br /> <br /> 我们再来看看一个典型的Interceptor的抽象实现类Q?<br /> <br /> <div id="wmqeeuq" class="dp-highlighter"> <div id="wmqeeuq" class="bar"> <div id="wmqeeuq" class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">abstract</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> AroundInterceptor </span><span id="wmqeeuq" class="keyword">extends</span><span> AbstractInterceptor {   </span></span> <li><span>       </span> <li><span>    </span><span id="wmqeeuq" class="comment">/* (non-Javadoc) </span> </span> <li><span><span id="wmqeeuq" class="comment">     * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation) </span> </span> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span> <li><span>    </span><span id="wmqeeuq" class="annotation">@Override</span><span>  </span></span> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> String intercept(ActionInvocation invocation) </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span> <li><span>        String result = </span><span id="wmqeeuq" class="keyword">null</span><span>;   </span></span> <li><span>  </span> <li><span>        before(invocation);   </span> <li><span>        </span><span id="wmqeeuq" class="comment">// 调用下一个拦截器Q如果拦截器不存在,则执行Action </span><span>  </span></span> <li><span>        result = invocation.invoke();   </span> <li><span>        after(invocation, result);   </span> <li><span>  </span> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> result;   </span></span> <li><span>    }   </span> <li><span>       </span> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">abstract</span><span> </span><span id="wmqeeuq" class="keyword">void</span><span> before(ActionInvocation invocation) </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception;   </span></span> <li><span>  </span> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">abstract</span><span> </span><span id="wmqeeuq" class="keyword">void</span><span> after(ActionInvocation invocation, String resultCode) </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception;   </span></span> <li><span>  </span> <li><span>}  </span> </li> </ol> </div> <pre class="java" style="display: none" name="code">public abstract class AroundInterceptor extends AbstractInterceptor { /* (non-Javadoc) * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation) */ @Override public String intercept(ActionInvocation invocation) throws Exception { String result = null; before(invocation); // 调用下一个拦截器Q如果拦截器不存在,则执行Action result = invocation.invoke(); after(invocation, result); return result; } public abstract void before(ActionInvocation invocation) throws Exception; public abstract void after(ActionInvocation invocation, String resultCode) throws Exception; }</pre> <br /> <br /> 在这个实现类中,实际上已l实C最单的拦截器的雏Ş。或许大家对q样的代码还比较陌生Q这没有关系。我在这里需要指出的是一个很重要的方法invocation.invoke()。这是ActionInvocation中的ҎQ而ActionInvocation是Action调度者,所以这个方法具备以?层含义: <br /> <br /> <strong>1. 如果拦截器堆栈中q有其他的InterceptorQ那么invocation.invoke()调用堆栈中下一个Interceptor的执行?/strong> <br /> <br /> <strong>2. 如果拦截器堆栈中只有Action了,那么invocation.invoke()调用Action执行?/strong> <br /> <br /> 所以,我们可以发现Qinvocation.invoke()q个Ҏ其实是整个拦截器框架的实现核心。基于这L实现机制Q我们还可以得到下面2个非帔R要的推论Q?<br /> <br /> <strong>1. 如果在拦截器中,我们不用invocation.invoke()来完成堆栈中下一个元素的调用Q而是直接q回一个字W串作ؓ执行l果Q那么整个执行将被中止?/strong> <br /> <br /> <strong>2. 我们可以以invocation.invoke()为界Q将拦截器中的代码分?个部分,在invocation.invoke()之前的代码,会在Action之前被依ơ执行,而在invocation.invoke()之后的代码,会在Action之后被逆序执行?/strong> <br /> <br /> 由此Q我们就可以通过invocation.invoke()作ؓAction代码真正的拦截点Q从而实现AOP?<br /> <br /> <strong><span style="color: blue">Interceptor拦截cd</span></strong> <br /> <br /> 从上面的分析Q我们知道,整个拦截器的核心部分是invocation.invoke()q个函数的调用位|。事实上Q我们也正式Ҏq句代码的调用位|,来进行拦截类型的区分的。在Struts2中,Interceptor的拦截类型,分成以下三类Q?<br /> <br /> <strong>1. before</strong> <br /> <br /> before拦截Q是指在拦截器中定义的代码,它们存在于invocation.invoke()代码执行之前。这些代码,依照拦截器定义的顺序,<strong>序执行</strong>?<br /> <br /> <strong>2. after</strong> <br /> <br /> after拦截Q是指在拦截器中定义的代码,它们存在于invocation.invoke()代码执行之后。这些代码,一招拦截器定义的顺序,<strong>逆序执行</strong>?<br /> <br /> 3. PreResultListener <br /> <br /> 有的时候,before拦截和after拦截Ҏ们来说是不够的,因ؓ我们需要在Action执行完之后,但是q没有回到视囑ֱ之前Q做一些事情。Struts2同样支持q样的拦截,q种拦截方式Q是通过在拦截器中注册一个PreResultListener的接口来实现的?<br /> <br /> <div id="wmqeeuq" class="dp-highlighter"> <div id="wmqeeuq" class="bar"> <div id="wmqeeuq" class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">interface</span><span> PreResultListener {   </span></span> <li><span>  </span> <li><span>    </span><span id="wmqeeuq" class="comment">/** </span> </span> <li><span><span id="wmqeeuq" class="comment">     * This callback method will be called after the Action execution and before the Result execution. </span> </span> <li><span><span id="wmqeeuq" class="comment">     * </span> </span> <li><span><span id="wmqeeuq" class="comment">     * @param invocation </span> </span> <li><span><span id="wmqeeuq" class="comment">     * @param resultCode </span> </span> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span> <li><span>    </span><span id="wmqeeuq" class="keyword">void</span><span> beforeResult(ActionInvocation invocation, String resultCode);   </span></span> <li><span>}  </span> </li> </ol> </div> <pre class="java" style="display: none" name="code">public interface PreResultListener { /** * This callback method will be called after the Action execution and before the Result execution. * * @param invocation * @param resultCode */ void beforeResult(ActionInvocation invocation, String resultCode); } </pre> <br /> <br /> 在这里,我们看到QStruts2能够支持如此多的拦截cdQ与其本w的数据l构和整体设计有很大的关pR正如我在之前的文章中所提到的: <br /> <br /> <div id="wmqeeuq" class="quote_title">downpour 写道</div> <div id="wmqeeuq" class="quote_div">因ؓAction是一个普通的Javac,而不是一个Servletc,完全q于Web容器Q所以我们就能够更加方便地对Control层进行合理的层次设计Q从而抽象出许多公共的逻辑Qƈ这些逻辑q出Action对象本n?/div> <br /> <br /> 我们可以看到QStruts2对于整个执行的划分,从Interceptor到Action一直到ResultQ每一层都职责明确。不仅如此,Struts2qؓ每一个层ơ之前都讄了恰如其分的插入炏V得整个Action层的扩展性得C史无前例的提升?<br /> <br /> <strong><span style="color: blue">Interceptor执行序</span></strong> <br /> <br /> Interceptor的执行顺序或许是我们在整个过E中最最兛_的部分。根据上面所提到的概念,我们实际上已l能够大致明白了Interceptor的执行机理。我们来看看Struts2的Reference对Interceptor执行序的一个Ş象的例子?<br /> <br /> 如果我们有一个interceptor-stack的定义如下: <br /> <br /> <div id="wmqeeuq" class="dp-highlighter"> <div id="wmqeeuq" class="bar"> <div id="wmqeeuq" class="tools">Xml代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-xml"> <li><span><span id="wmqeeuq" class="tag"><</span><span id="wmqeeuq" class="tag-name">interceptor-stack</span><span> </span><span id="wmqeeuq" class="attribute">name</span><span>=</span><span id="wmqeeuq" class="attribute-value">"xaStack"</span><span id="wmqeeuq" class="tag">></span><span>  </span></span> <li><span>  </span><span id="wmqeeuq" class="tag"><</span><span id="wmqeeuq" class="tag-name">interceptor-ref</span><span> </span><span id="wmqeeuq" class="attribute">name</span><span>=</span><span id="wmqeeuq" class="attribute-value">"thisWillRunFirstInterceptor"</span><span id="wmqeeuq" class="tag">/></span><span>  </span></span> <li><span>  </span><span id="wmqeeuq" class="tag"><</span><span id="wmqeeuq" class="tag-name">interceptor-ref</span><span> </span><span id="wmqeeuq" class="attribute">name</span><span>=</span><span id="wmqeeuq" class="attribute-value">"thisWillRunNextInterceptor"</span><span id="wmqeeuq" class="tag">/></span><span>  </span></span> <li><span>  </span><span id="wmqeeuq" class="tag"><</span><span id="wmqeeuq" class="tag-name">interceptor-ref</span><span> </span><span id="wmqeeuq" class="attribute">name</span><span>=</span><span id="wmqeeuq" class="attribute-value">"followedByThisInterceptor"</span><span id="wmqeeuq" class="tag">/></span><span>  </span></span> <li><span>  </span><span id="wmqeeuq" class="tag"><</span><span id="wmqeeuq" class="tag-name">interceptor-ref</span><span> </span><span id="wmqeeuq" class="attribute">name</span><span>=</span><span id="wmqeeuq" class="attribute-value">"thisWillRunLastInterceptor"</span><span id="wmqeeuq" class="tag">/></span><span>  </span></span> <li><span id="wmqeeuq" class="tag"></</span><span id="wmqeeuq" class="tag-name">interceptor-stack</span><span id="wmqeeuq" class="tag">></span><span>  </span></span> </li> </ol> </div> <pre class="xml" style="display: none" name="code"><interceptor-stack name="xaStack"> <interceptor-ref name="thisWillRunFirstInterceptor"/> <interceptor-ref name="thisWillRunNextInterceptor"/> <interceptor-ref name="followedByThisInterceptor"/> <interceptor-ref name="thisWillRunLastInterceptor"/> </interceptor-stack></pre> <br /> <br /> 那么Q整个执行的序大概像这P <br /> <br /> <img alt="" src="http://www.javaeye.com/upload/attachment/71392/23045c94-b72a-3c04-9c6c-06ad4392d743.gif" /> <br /> <br /> 在这里,我稍微改了一下Struts2的Reference中的执行序CZQ得整个执行顺序更加能够被理解。我们可以看刎ͼ递归调用保证了各U各L拦截cd的执行能够井井有条?<br /> <br /> h意在q里Q每个拦截器中的代码的执行顺序,在Action之前Q拦截器的执行顺序与堆栈中定义的一_而在Action和Result之后Q拦截器的执行顺序与堆栈中定义的序相反?<br /> </div> <h2>源码解析 <a name="1680"><img alt="Top" src="http://www.javaeye.com/images/wiki/top.gif?1229402183" /></a> </h2> <div id="wmqeeuq" class="content">接下来我们就来看看源码,看看Struts2是如何保证拦截器、Action与Result三者之间的执行序的?<br /> <br /> 之前我曾l提刎ͼActionInvocation是Struts2中的调度器,所以事实上Q这些代码的调度执行Q是在ActionInvocation的实现类中完成的Q这里,我抽取了DefaultActionInvocation中的invoke()ҎQ它向我们展示一切?<br /> <br /> <div id="wmqeeuq" class="dp-highlighter"> <div id="wmqeeuq" class="bar"> <div id="wmqeeuq" class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="comment">/** </span> </span> <li><span><span id="wmqeeuq" class="comment"> * @throws ConfigurationException If no result can be found with the returned code </span> </span> <li><span><span id="wmqeeuq" class="comment"> */</span><span>  </span></span> <li><span id="wmqeeuq" class="keyword">public</span><span> String invoke() </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span> <li><span>    String profileKey = </span><span id="wmqeeuq" class="string">"invoke: "</span><span>;   </span></span> <li><span>    </span><span id="wmqeeuq" class="keyword">try</span><span> {   </span></span> <li><span>        UtilTimerStack.push(profileKey);   </span> <li><span>               </span> <li><span>        </span><span id="wmqeeuq" class="keyword">if</span><span> (executed) {   </span></span> <li><span>            </span><span id="wmqeeuq" class="keyword">throw</span><span> </span><span id="wmqeeuq" class="keyword">new</span><span> IllegalStateException(</span><span id="wmqeeuq" class="string">"Action has already executed"</span><span>);   </span></span> <li><span>        }   </span> <li><span>        </span><span id="wmqeeuq" class="comment">// 依次调用拦截器堆栈中的拦截器代码执行 </span><span>  </span></span> <li><span>        </span><span id="wmqeeuq" class="keyword">if</span><span> (interceptors.hasNext()) {   </span></span> <li><span>            </span><span id="wmqeeuq" class="keyword">final</span><span> InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();   </span></span> <li><span>            UtilTimerStack.profile(</span><span id="wmqeeuq" class="string">"interceptor: "</span><span>+interceptor.getName(),    </span></span> <li><span>                    </span><span id="wmqeeuq" class="keyword">new</span><span> UtilTimerStack.ProfilingBlock<String>() {   </span></span> <li><span>                        </span><span id="wmqeeuq" class="keyword">public</span><span> String doProfiling() </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span> <li><span>                         </span><span id="wmqeeuq" class="comment">// ActionInvocation作ؓ参数Q调用interceptor中的interceptҎ执行 </span><span>  </span></span> <li><span>                            resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.</span><span id="wmqeeuq" class="keyword">this</span><span>);   </span></span> <li><span>                            </span><span id="wmqeeuq" class="keyword">return</span><span> </span><span id="wmqeeuq" class="keyword">null</span><span>;   </span></span> <li><span>                        }   </span> <li><span>            });   </span> <li><span>        } </span><span id="wmqeeuq" class="keyword">else</span><span> {   </span></span> <li><span>            resultCode = invokeActionOnly();   </span> <li><span>        }   </span> <li><span>  </span> <li><span>        </span><span id="wmqeeuq" class="comment">// this is needed because the result will be executed, then control will return to the Interceptor, which will </span><span>  </span></span> <li><span>        </span><span id="wmqeeuq" class="comment">// return above and flow through again </span><span>  </span></span> <li><span>        </span><span id="wmqeeuq" class="keyword">if</span><span> (!executed) {   </span></span> <li><span>            </span><span id="wmqeeuq" class="comment">// 执行PreResultListener </span><span>  </span></span> <li><span>            </span><span id="wmqeeuq" class="keyword">if</span><span> (preResultListeners != </span><span id="wmqeeuq" class="keyword">null</span><span>) {   </span></span> <li><span>                </span><span id="wmqeeuq" class="keyword">for</span><span> (Iterator iterator = preResultListeners.iterator();   </span></span> <li><span>                    iterator.hasNext();) {   </span> <li><span>                    PreResultListener listener = (PreResultListener) iterator.next();   </span> <li><span>                           </span> <li><span>                    String _profileKey=</span><span id="wmqeeuq" class="string">"preResultListener: "</span><span>;   </span></span> <li><span>                    </span><span id="wmqeeuq" class="keyword">try</span><span> {   </span></span> <li><span>                            UtilTimerStack.push(_profileKey);   </span> <li><span>                            listener.beforeResult(</span><span id="wmqeeuq" class="keyword">this</span><span>, resultCode);   </span></span> <li><span>                    }   </span> <li><span>                    </span><span id="wmqeeuq" class="keyword">finally</span><span> {   </span></span> <li><span>                            UtilTimerStack.pop(_profileKey);   </span> <li><span>                    }   </span> <li><span>                }   </span> <li><span>            }   </span> <li><span>  </span> <li><span>            </span><span id="wmqeeuq" class="comment">// now execute the result, if we're supposed to </span><span>  </span></span> <li><span>            </span><span id="wmqeeuq" class="comment">// action与interceptor执行完毕Q执行Result </span><span>  </span></span> <li><span>            </span><span id="wmqeeuq" class="keyword">if</span><span> (proxy.getExecuteResult()) {   </span></span> <li><span>                executeResult();   </span> <li><span>            }   </span> <li><span>  </span> <li><span>            executed = </span><span id="wmqeeuq" class="keyword">true</span><span>;   </span></span> <li><span>        }   </span> <li><span>  </span> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> resultCode;   </span></span> <li><span>    }   </span> <li><span>    </span><span id="wmqeeuq" class="keyword">finally</span><span> {   </span></span> <li><span>        UtilTimerStack.pop(profileKey);   </span> <li><span>    }   </span> <li><span>}  </span> </li> </ol> </div> <pre class="java" style="display: none" name="code">/** * @throws ConfigurationException If no result can be found with the returned code */ public String invoke() throws Exception { String profileKey = "invoke: "; try { UtilTimerStack.push(profileKey); if (executed) { throw new IllegalStateException("Action has already executed"); } // 依次调用拦截器堆栈中的拦截器代码执行 if (interceptors.hasNext()) { final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); UtilTimerStack.profile("interceptor: "+interceptor.getName(), new UtilTimerStack.ProfilingBlock<String>() { public String doProfiling() throws Exception { // ActionInvocation作ؓ参数Q调用interceptor中的interceptҎ执行 resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); return null; } }); } else { resultCode = invokeActionOnly(); } // this is needed because the result will be executed, then control will return to the Interceptor, which will // return above and flow through again if (!executed) { // 执行PreResultListener if (preResultListeners != null) { for (Iterator iterator = preResultListeners.iterator(); iterator.hasNext();) { PreResultListener listener = (PreResultListener) iterator.next(); String _profileKey="preResultListener: "; try { UtilTimerStack.push(_profileKey); listener.beforeResult(this, resultCode); } finally { UtilTimerStack.pop(_profileKey); } } } // now execute the result, if we're supposed to // action与interceptor执行完毕Q执行Result if (proxy.getExecuteResult()) { executeResult(); } executed = true; } return resultCode; } finally { UtilTimerStack.pop(profileKey); } } </pre> <br /> <br /> 从源码中Q我们可以看刎ͼ我们之前提到的Struts2的Action层的4个不同的层次Q在q个Ҏ中都有体玎ͼ他们分别是:拦截器(InterceptorQ、Action、PreResultListener和Result。在q个Ҏ中,保证了这些层ơ的有序调用和执行。由此我们也可以看出<strong><span style="color: red">Struts2在Action层次设计上的众多考虑Q每个层ơ都具备了高度的扩展性和插入点,使得E序员可以在M喜欢的层ơ加入自q实现机制改变Action的行为?/span></strong> <br /> <br /> 在这里,需要特别强调的Q是其中拦截器部分的执行调用Q?<br /> <br /> <div id="wmqeeuq" class="dp-highlighter"> <div id="wmqeeuq" class="bar"> <div id="wmqeeuq" class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span>resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.</span><span id="wmqeeuq" class="keyword">this</span><span>);  </span></span> </li> </ol> </div> <pre class="java" style="display: none" name="code">resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);</pre> <br /> <br /> 表面上,它只是执行了拦截器中的interceptҎQ如果我们结合拦截器来看Q就能看出点端倪来Q?<br /> <br /> <div id="wmqeeuq" class="dp-highlighter"> <div id="wmqeeuq" class="bar"> <div id="wmqeeuq" class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">public</span><span> String intercept(ActionInvocation invocation) </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span> <li><span>    String result = </span><span id="wmqeeuq" class="keyword">null</span><span>;   </span></span> <li><span>  </span> <li><span>        before(invocation);   </span> <li><span>        </span><span id="wmqeeuq" class="comment">// 调用invocation的invoke()ҎQ在q里形成了递归调用 </span><span>  </span></span> <li><span>        result = invocation.invoke();   </span> <li><span>        after(invocation, result);   </span> <li><span>  </span> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> result;   </span></span> <li><span>}  </span> </li> </ol> </div> <pre class="java" style="display: none" name="code">public String intercept(ActionInvocation invocation) throws Exception { String result = null; before(invocation); // 调用invocation的invoke()ҎQ在q里形成了递归调用 result = invocation.invoke(); after(invocation, result); return result; }</pre> <br /> <br /> 原来在intercept()Ҏ又对ActionInvocation的invoke()Ҏq行递归调用QActionInvocation循环嵌套在intercept()中,一直到语句result = invocation.invoke()执行l束。这PInterceptor又会按照刚开始执行的逆向序依次执行l束?<br /> <br /> <strong><span style="color: red">一个有序链表,通过递归调用Q变成了一个堆栈执行过E,一D|序执行的代码变成?D|行顺序完全相反的代码q程Q从而y妙地实现了AOP?/span></strong>q也成ZStruts2的Action层的AOP基础?</div> <img src ="http://www.aygfsteel.com/fantasy/aggbug/257349.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/fantasy/" target="_blank">Web 2.0 技术资?/a> 2009-03-02 15:24 <a href="http://www.aygfsteel.com/fantasy/articles/257349.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(?)Struts2.0 拦截器的实现与定?/title><link>http://www.aygfsteel.com/fantasy/articles/257311.html</link><dc:creator>Web 2.0 技术资?/dc:creator><author>Web 2.0 技术资?/author><pubDate>Mon, 02 Mar 2009 03:31:00 GMT</pubDate><guid>http://www.aygfsteel.com/fantasy/articles/257311.html</guid><wfw:comment>http://www.aygfsteel.com/fantasy/comments/257311.html</wfw:comment><comments>http://www.aygfsteel.com/fantasy/articles/257311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/fantasy/comments/commentRss/257311.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/fantasy/services/trackbacks/257311.html</trackback:ping><description><![CDATA[<p>转自(http://samyulong.javaeye.com/blog/217092)<br /> <br /> 一?span>什么是拦截器?</span></p> <p style="text-indent: 21pt"><span>提到拦截器,使我不得?惌v武侠剧中劫匪们常说的一句话Q?#8220;此山是我开Q此树是我栽Q要打此路过Q留下买路胦Q?#8221;。难不成E序中也?#8220;打劫”的,说的没错Q拦截器是个打劫的?在现实生zMQ劫匪劫的大都是pQ当然也有别的什么,那么E序中的“劫匪”劫的又是什么呢Q或者说E序中ؓ什么需要它Q在我们的日常编E中不了写一?重复的代码,例如在一个地方中写了一D代码,后来发现q段代码在其它地方中同样需要,在传l的~程中我们一定会采取复制、粘贴的办法。如果这D代码只在这 一两个处需要,我们采取q种办法Q还说的q去Q但是如果系l对q段代码q于依赖Q也是q段代码在系l中出现的过多,如果那一天我们发现这D代码中在某?地方q需要完善,我们是不是要着个修改它们呢Q我估计没有Zq么做,它严重违反了软g开发中一条非帔R要的</span>DRY<span>规则Q不写重复代码。说了这么多你一定知道我们ؓ什么需要在E序中弄一?#8220;劫匪”了吧。这?#8220;劫匪”是q不是劫取什么东西,只是Z在某个程序执行前后,动态的增加一些功能(以前所写通用代码块)或进行一些检查工作。那么这个拦截器到底是怎么实现的呢Q实际上它是?/span>Java<span>中的动态代理来实现的?/span></p> <p style="margin-left: 21pt; text-indent: -21pt">二?span>拦截器在</span>Struts2<span>中的应用</span></p> <p style="text-indent: 21pt"><span>对于</span>Struts2<span>框架而言Q正是大量的内置拦截器完成了大部分操作。像</span>params<span>拦截器将</span>http<span>h中参数解析出来赋值给</span>Action<span>中对应的属性?/span>Servlet-config<span>拦截器负责把h?/span>HttpServletRequest<span>实例?/span>HttpServletResponse<span>实例传递给</span>Action……struts2<span>内置的拦截器?/span><span>很多Q在此我׃一一列D?/span></p> <p style="text-indent: 21pt"><span>那么怎么?/span>struts2<span>中定义自q拦截器呢</span>?</p> <p><span>    很简?/span>Struts2<span>为我们提供了一?/span>Interceptor<span>接口</span>,<span>该接口源代码如下</span>:</p> <p style="text-align: left" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: &apos">public</span></strong><strong><span style="font-size: 10pt; color: #7f0055; font-family: &apos">interface</span></strong><span style="font-size: 10pt; color: #000000; font-family: &apos"> <span>Interceptor</span> </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &apos">extends</span></strong><span style="font-size: 10pt; color: #000000; font-family: &apos"> Serializable {</span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">    </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &apos">void</span></strong><span style="font-size: 10pt; color: #000000; font-family: &apos"> destroy();</span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">    </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &apos">void</span></strong><span style="font-size: 10pt; color: #000000; font-family: &apos"> init();</span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">    String intercept(ActionInvocation invocation) </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: &apos">throws</span></strong><span style="font-size: 10pt; color: #000000; font-family: &apos"> Exception;</span></p> <p><span style="font-size: 10pt; color: #000000; font-family: &apos">}</span></p> <p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10pt; color: #000000; font-family: &apos">1)<span style="font-family: &apos">    </span></span>init():<span>在拦截器执行之前调用Q主要用于初始化pȝ资源?/span></p> <p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10pt; color: #000000; font-family: &apos">2)<span style="font-family: &apos">    </span></span>destroty():<span>?/span>init()<span>对应Q用于拦截器执行之后销毁资源?/span></p> <p style="margin-left: 18pt; text-indent: -18pt"><span style="font-size: 10pt; color: #000000; font-family: &apos">3)<span style="font-family: &apos">    </span></span>intercept():<span>拦截器的核心ҎQ实现具体的拦截操作。与</span>action<span>一P该方法也q回一个字W串作ؓ逻辑视图。如果拦截器成功调用?/span>action<span>Q则q回一个真正的Q也是?/span>action<span>?/span>execute()<span>Ҏq回的逻辑视图Q反之,则返回一个自定义的逻辑视图?/span></p> <p><span>通常我们使用拦截器ƈ不需要申误源,为此</span>Struts2<span>qؓ我们提供了一?/span>AbstractInterceptor<span>c,该类?/span>init()<span>?/span>destroy()<span>都是I实现。我们开发自q拦截器只需要承这个类p了?/span></p> <p><span>    </span><span>下面创徏一个判断用h否登录的拦截器。代码如?/span>:<br />           </p> <div style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 4px; width: 95%; padding-top: 4px"> <div><span style="color: #0000ff">import</span><span style="color: #000000"> java.util.Map;<br /> </span><span style="color: #0000ff">import</span><span style="color: #000000"> com.opensymphony.xwork2.Action;<br /> </span><span style="color: #0000ff">import</span><span style="color: #000000"> com.opensymphony.xwork2.ActionInvocation;<br /> </span><span style="color: #0000ff">import</span><span style="color: #000000"> com.opensymphony.xwork2.interceptor.AbstractInterceptor;<br /> <br /> @SuppressWarnings(</span><span style="color: #000000">"</span><span style="color: #000000">serial</span><span style="color: #000000">"</span><span style="color: #000000">)<br /> </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> CheckLoginInterceptor </span><span style="color: #0000ff">extends</span><span style="color: #000000"> AbstractInterceptor {<br /> <br />     @SuppressWarnings(</span><span style="color: #000000">"</span><span style="color: #000000">unchecked</span><span style="color: #000000">"</span><span style="color: #000000">)<br />     </span><span style="color: #0000ff">public</span><span style="color: #000000"> String intercept(ActionInvocation actionInvocation) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {<br />          System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">begin check login interceptor!</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> <br />             </span><span style="color: #008000">//</span><span style="color: #008000"> 查Session中是否存在user</span><span style="color: #008000"><br /> </span><span style="color: #000000"><br />             Map session </span><span style="color: #000000">=</span><span style="color: #000000"> actionInvocation.getInvocationContext().getSession();<br /> <br />             String username </span><span style="color: #000000">=</span><span style="color: #000000"> (String) session.get(</span><span style="color: #000000">"</span><span style="color: #000000">user</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> <br />             </span><span style="color: #0000ff">if</span><span style="color: #000000"> (username </span><span style="color: #000000">!=</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000"> </span><span style="color: #000000">&&</span><span style="color: #000000"> username.length() </span><span style="color: #000000">></span><span style="color: #000000"> </span><span style="color: #000000">0</span><span style="color: #000000">) {<br /> <br />                 </span><span style="color: #008000">//</span><span style="color: #008000"> 存在的情况下q行后箋操作?/span><span style="color: #008000"><br /> </span><span style="color: #000000"><br />                 System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">already login!</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> <br />                 </span><span style="color: #0000ff">return</span><span style="color: #000000"> actionInvocation.invoke();<br /> <br />             } </span><span style="color: #0000ff">else</span><span style="color: #000000"> {<br /> <br />                 </span><span style="color: #008000">//</span><span style="color: #008000"> 否则l止后箋操作Q返回LOGIN</span><span style="color: #008000"><br /> </span><span style="color: #000000"><br />                 System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">no login, forward login page!</span><span style="color: #000000">"</span><span style="color: #000000">);<br /> <br />                 </span><span style="color: #0000ff">return</span><span style="color: #000000"> Action.LOGIN;<br /> <br />             }<br /> <br />         }<br /> <br />     }</span></div> </div>     创徏好拦截器后,q不能用,q需要我们在struts.xml<span>中配|一下?/span> <p> <p><span>  下面看一下怎么配置拦截器?/span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptors</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">           </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"checkLogin" </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">class</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"com.myblog.interceptor.CheckLoginInterceptor" </span><span style="font-size: 10pt; color: #008080; font-family: &apos">/></span></p> <p><span style="font-size: 10pt; color: #008080; font-family: &apos"></</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptors</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p><span>   q个定义好的拦截器在</span>Action<span>中怎么使用呢?使用Ҏ很简单,如下Q?/span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">action </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">" " </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">class</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">" " </span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">           </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><result> </result></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">           </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor-ref </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"checkLogin" </span><span style="font-size: 10pt; color: #008080; font-family: &apos">/></span></p> <p><span style="font-size: 10pt; color: #008080; font-family: &apos"></</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">action</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p><span>   一旦我们ؓ某个</span>action<span>引用了自定义的拦截器Q?/span>struts2<span>默认的拦截器׃会再起作用,因此q需要引用默认拦截器?/span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">action </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">" " </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">class</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">" " </span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">           </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><result> </result></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">           </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor-ref </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"checkLogin" </span><span style="font-size: 10pt; color: #008080; font-family: &apos">/></span></p> <p><span style="color: #008080">                     </span><interceptor-ref name="defaultStack" /></p> <p><span style="font-size: 10pt; color: #008080; font-family: &apos"></</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">action</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p><span>   但是我们q么做似乎也不太方便Q因为如果拦截器</span>checkLogin<span>需要被多个</span>action<span>引用的话Q每一个都要配|一遍太ȝ了。我们可以把它定义成默认的拦截器?/span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptors</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">           </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"checkLogin" </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">class</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"com.myblog.interceptor.CheckLoginInterceptor" </span><span style="font-size: 10pt; color: #008080; font-family: &apos">/></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #008080; font-family: &apos">           <!?</span><span>定义一个拦截器?/span><span style="font-size: 10pt; color: #008080; font-family: &apos">--></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">           </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor-stack </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"mydefault"</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">              </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor-ref </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"defaultStack" </span><span style="font-size: 10pt; color: #008080; font-family: &apos">/></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">              </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor-ref </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"checkLogin" </span><span style="font-size: 10pt; color: #008080; font-family: &apos">/></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">           </span><span style="font-size: 10pt; color: #008080; font-family: &apos"></</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor-stack</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #008080; font-family: &apos"></</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptors</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">default-interceptor-ref </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"mydefault" </span><span style="font-size: 10pt; color: #008080; font-family: &apos">/></span></p> <p><span>   另外Q?/span>struts2<span>qؓ我们提供了一个方法过滤的拦截?/span>MethodFilterInterceptor<span>c,该类l承</span>AbstractInterceptor<span>c,重写?/span><span style="font-size: 10pt; color: #000000; font-family: &apos">intercept(ActionInvocation invocation)</span><span>q提供了一个新的方?/span><span style="font-size: 10pt; color: #000000; font-family: &apos">doInterceptor(ActionInvocation invocation)</span><span>抽象Ҏ。该cȝ使用Ҏ很简单,׃举例了。这个拦截器与以往的拦截器配置有所不同。那是可以指定哪些Ҏ需要被拦截Q那些不需要。通常在引用该拦截器时指定?/span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor-ref </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"  "</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">       </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">param </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"exculdeMethods"</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">param</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p style="text-align: left" align="left"><span style="font-size: 10pt; color: #000000; font-family: &apos">       </span><span style="font-size: 10pt; color: #008080; font-family: &apos"><</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">param </span><span style="font-size: 10pt; color: #7f007f; font-family: &apos">name</span><span style="font-size: 10pt; color: #000000; font-family: &apos">=</span><span style="font-size: 10pt; color: #2a00ff; font-family: &apos">"includeMethods"</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">param</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span><span style="font-size: 10pt; color: #000000; font-family: &apos">     </span></p> <p><span style="font-size: 10pt; color: #008080; font-family: &apos"></</span><span style="font-size: 10pt; color: #3f7f7f; font-family: &apos">interceptor-ref</span><span style="font-size: 10pt; color: #008080; font-family: &apos">></span></p> <p>   exculdeMethods<span>Q是不被拦截的方法,如果有多个以逗号分隔?/span></p> <p>   includeMethods<span>Q需要被拦截的方法,如果有多个以逗号分隔?/span></p> <p> </p> <hr style="width: 100%; height: 2px" /> <p><span><br />     下面我来实验下。我们写个拦截器?br />     </span></p> <div style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 4px; width: 95%; padding-top: 4px"> <div><span style="color: #0000ff"><</span><span style="color: #800000">interceptors</span><span style="color: #0000ff">></span><span style="color: #000000"><br />    </span><span style="color: #0000ff"><</span><span style="color: #800000">interceptor </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="authorize"</span><span style="color: #ff0000"> class</span><span style="color: #0000ff">="com.struts2.interceptor.AuthorizeInterceptor"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/></span><span style="color: #000000"><br />    </span><span style="color: #0000ff"><</span><span style="color: #800000">interceptor-stack </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="appStack"</span><span style="color: #0000ff">></span><span style="color: #000000"><br />       </span><span style="color: #008000"><!--</span><span style="color: #008000"> 你自定义?nbsp;</span><span style="color: #008000">--></span><span style="color: #000000"><br />       </span><span style="color: #0000ff"><</span><span style="color: #800000">interceptor-ref </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="authorize"</span><span style="color: #0000ff">/></span><span style="color: #000000"><br />       </span><span style="color: #008000"><!--</span><span style="color: #008000"> pȝ内置的拦截器?nbsp;</span><span style="color: #008000">--></span><span style="color: #000000"><br />       </span><span style="color: #0000ff"><</span><span style="color: #800000">interceptor-ref </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="defaultStack"</span><span style="color: #0000ff">/></span><span style="color: #000000"><br />    </span><span style="color: #0000ff"></</span><span style="color: #800000">interceptor-stack</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> </span><span style="color: #0000ff"></</span><span style="color: #800000">interceptors</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> </span><span style="color: #0000ff"><</span><span style="color: #800000">action </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="forward"</span><span style="color: #ff0000"> class</span><span style="color: #0000ff">="com.struts2.RequestForward"</span><span style="color: #0000ff">></span><span style="color: #000000"><br />    </span><span style="color: #0000ff"><</span><span style="color: #800000">interceptor-ref </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="appStack"</span><span style="color: #0000ff">/></span><span style="color: #000000"><br />    </span><span style="color: #0000ff"><</span><span style="color: #800000">result </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="index"</span><span style="color: #0000ff">></span><span style="color: #000000">index.jsp</span><span style="color: #0000ff"></</span><span style="color: #800000">result</span><span style="color: #0000ff">></span><span style="color: #000000"><br />    </span><span style="color: #0000ff"><</span><span style="color: #800000">result </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="NOT_FOUND"</span><span style="color: #0000ff">></span><span style="color: #000000">not_found.jsp</span><span style="color: #0000ff"></</span><span style="color: #800000">result</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> </span><span style="color: #0000ff"></</span><span style="color: #800000">action</span><span style="color: #0000ff">></span></div> </div>     恩,q是有点很迷茫的位置Q比说的拦截器的调用序是根据xml里面的顺序来的吗Q还有可以指定只在action之前或者只在action之后调用吗?说实话我也搞不清楚,在运用的q程中,大家慢慢在来体会<br /> <br /> <br /> <p>拦截器几乎完成了Struts2框架70%的工作,包括解析h参数、将h参数赋值给Action属性、执行数据校验、文件上?#8230;…QStruts2设计的灵巧性,更大E度地得益于拦截器设计,当需要扩展Struts2功能Ӟ只需要提供对应拦截器Qƈ它配置在Struts2容器中即可;如果不需要该功能Ӟ也只需要取消该拦截器的配置卛_。这U可插拔式的设计Q正是Y件设计领域一直孜孜以求的目标?/p> <p>实际上,Struts2的精髓就在于拦截器,掌握了Struts2的拦截器机制Q你可以说_N了Struts2?br /> 从某个角度来看,我们可以把Struts2框架理解成一个空壻I而这些拦截器像一个一个抽屉,随时可以<br /> 插进入,也可以拔出来——这是Y件品一直追求的目标?br /> 如果你喜Ƣ,你可以把Struts2的全部插件拔出,那么Struts2成了一个空容器—?br /> 而这U空Q正?Struts2的魅力,你可以把M自己惌的东西填入进去,甚至包括自己完全实现q个框架?/p> <p>另一斚wQ因为Struts2的插件机?Struts2提供了无限扩展的可能性,你可以把自己惌的Q?br /> 东西做成插gQ然后填入Struts2——这Ll果是:一个企业,一个团队,可以把自׃务相关的东西<br /> 做成插gQ随旉地地复用?br /> 也就是说Q如果你惌Q你可以把Struts2攚w成属于自己的框架?/p> <p>当然QStruts2也内Z大量的拦截器Q这些拦截器以name-class对的形式配置在struts-default. xml文g中,其中name是拦截器的名字,是以后使用该拦截器的唯一标识Qclass则指定了该拦截器的实现类Q如果我们定义的packagel承了Struts2的默认struts-default包,则可以自׃用下面定义的拦截器,否则必须自己定义q些拦截器?br /> 下面是Struts2内徏拦截器的要介l:<br /> aliasQ实现在不同h中相似参数别名的转换?br /> autowiringQ这是个自动装配的拦截器Q主要用于当Struts2和Spring整合ӞStruts2可以使用自动装配的方式来讉KSpring容器中的Bean?br /> chainQ构Z个Action链,使当前Action可以讉K前一个Action的属性,一般和<result type="chain" .../>一起用?br /> conversionErrorQ这是一个负责处理类型{换错误的拦截器,它负责将cd转换错误从ActionContext中取出,q{换成Action的FieldError错误?br /> createSessionQ该拦截器负责创Z个HttpSession对象Q主要用于那些需要有HttpSession对象才能正常工作的拦截器中?br /> debuggingQ当使用Struts2的开发模式时Q这个拦截器会提供更多的调试信息?br /> execAndWaitQ后台执行ActionQ负责将{待画面发送给用户?br /> exceptionQ这个拦截器负责处理异常Q它异常映ؓl果?br /> fileUploadQ这个拦截器主要用于文g上传Q它负责解析表单中文件域的内宏V?<br /> i18nQ这是支持国际化的拦截器Q它负责把所选的语言、区域放入用户Session中?br /> loggerQ这是一个负责日志记录的拦截器,主要是输出Action的名字?br /> model-drivenQ这是一个用于模型驱动的拦截器,当某个ActioncdCModelDriven接口Ӟ它负责把getModel()Ҏ的结果堆入ValueStack中?<br /> scoped-model-drivenQ如果一个Action实现了一个ScopedModelDriven接口Q该拦截器负责从指定生存范围中找出指定的ModolQƈ通过setModelҎ该Model传给Action实例?br /> paramsQ这是最基本的一个拦截器Q它负责解析HTTPh中的参数Qƈ参数D|成Action对应的属性倹{?br /> prepareQ如果action实现了Preparable接口Q将会调用该拦截器的prepare()Ҏ?br /> static-paramsQ这个拦截器负责xml?lt;action>标签?lt;param>标签中的参数传入action?br /> scopeQ这是范围{换拦截器Q它可以Action状态信息保存到HttpSession范围Q或者保存到ServletContext范围内?br /> servlet-configQ如果某个Action需要直接访问Servlet APIQ就是通过q个拦截器实现的?br /> 注意Q尽量避免在Action中直接访问Servlet APIQ这样会DAction与Servlet的高耦合?br /> rolesQ这是一个JAASQJava Authentication and Authorization ServiceQJava授权和认证服务)拦截器,只有当浏览者取得合适的授权后,才可以调用被该拦截器拦截的Action?br /> timerQ这个拦截器负责输出Action的执行时_q个拦截器在分析该Action的性能瓉时比较有用?br /> tokenQ这个拦截器主要用于L重复提交Q它查传到Action中的tokenQ从而防止多ơ提交?br /> token-sessionQ这个拦截器的作用与前一个基本类|只是它把token保存在HttpSession中?br /> validationQ通过执行在xxxAction-validation.xml中定义的校验器,从而完成数据校验?br /> workflowQ这个拦截器负责调用ActioncM的validateҎQ如果校验失败,则返回input的逻辑视图?br /> 大部分时候,开发者无需手动控制q些拦截器,因ؓstruts-default.xml文g中已l配|了q些拦截器,只要我们定义的包l承了系l的struts-default包,可以直接用这些拦截器?/p> <p>当然QStruts2的拦截器机制q不是来自于Struts1Q而是来自于WebWork?/p> <br /> <img src ="http://www.aygfsteel.com/fantasy/aggbug/257311.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/fantasy/" target="_blank">Web 2.0 技术资?/a> 2009-03-02 11:31 <a href="http://www.aygfsteel.com/fantasy/articles/257311.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">گ</a>| <a href="http://" target="_blank">Զ</a>| <a href="http://" target="_blank">ɳ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">¸</a>| <a href="http://" target="_blank">ӳ</a>| <a href="http://" target="_blank">³ľ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank">ʲ</a>| <a href="http://" target="_blank">֣</a>| <a href="http://" target="_blank">౱</a>| <a href="http://" target="_blank">ɫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">¡</a>| <a href="http://" target="_blank">̫</a>| <a href="http://" target="_blank">³</a>| <a href="http://" target="_blank">ϲ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽң</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ൺ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ؼ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">̨ʡ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʹ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">˳</a>| <a href="http://" target="_blank">ԭ</a>| <a href="http://" target="_blank">鴨</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>