﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-zhouyangLib-文章分类-J2EE</title><link>http://www.blogjava.net/yangmage/category/37483.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 09 Feb 2009 11:40:01 GMT</lastBuildDate><pubDate>Mon, 09 Feb 2009 11:40:01 GMT</pubDate><ttl>60</ttl><item><title>Struts2的拦截器</title><link>http://www.blogjava.net/yangmage/articles/253564.html</link><dc:creator>Solar</dc:creator><author>Solar</author><pubDate>Fri, 06 Feb 2009 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/yangmage/articles/253564.html</guid><wfw:comment>http://www.blogjava.net/yangmage/comments/253564.html</wfw:comment><comments>http://www.blogjava.net/yangmage/articles/253564.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yangmage/comments/commentRss/253564.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yangmage/services/trackbacks/253564.html</trackback:ping><description><![CDATA[<p><span>http://www.blogjava.net/bacon/archive/2009/02/06/253561.html<br />
<br />
<br />
struts2的拦截器(Interceptor)是struts中比较复杂也比较核心的内容，功能挺强大。不过对于这种很难很强大的东东，一般还是比较抵触的：毕竟学起来比较艰深，学完了有没有用又另当别论了——那为什么还要学呢？<br />
如果不能解决实际问题，它吹得再牛，也不见得有多好。所以，拦截器到底做什么的呢？<br />
</span></p>
<p><strong><span>拦截器的一个最广泛的应用是全局访问权限控制。</span></strong></p>
<p><br />
<span>在做网站的时候，一般来说都有全局的权限控制这一块。如果在每个页面的前头加一段代码的话，页面少还问题不大，页面多了维护起来就比较恐怖了。Struts中提供了一种全局性的解决方案：拦截器。<br />
<br />
拦截器的底层实现机制还是AOP，其原理是&#8230;&#8230;AOP的实现原理就不说了，拦截器的原理是在特定函数的执行前后，插入自定义方法，具体到对Action拦截器中，就是每个（或者每个指定的）Action的Execute()或者其他指定方法执行前后，插入自定义的方法。</span></p>
<p><span>也就是说，你可以在（除了登录Action本身之外）所有Action逻辑发生之前，插入一段用户验证逻辑，从而将绕过登录界面的用户请求挡在核心业务逻辑之外；进一步的，可以将各种业务按照权限分级分类，使用不同的拦截器逻辑进行拦截，从而达到多级权限控制的效果。</span></p>
<p><br />
<span>上面说的只是拦截器的一部分功能，其实struts自己也预定义了许多拦截器，比如说。Action映射、参数解析、日志、国际化 、验证&#8230;&#8230;struts中许多非常核心的功能其实都是通过拦截器机制来实现的。如果有兴趣了解，struts2-core-xxx.jar中struts-default.xml的&lt;interceptors&gt;节点可以作为起点，其中定义了struts内建的所有拦截器。</span></p>
<p><span><br />
<strong>下面简单记录实现步骤<br />
1、定义拦截器。</strong><br />
Struts2规定用户自定义拦截器必须实现<em>com.opensymphony.xwork2.interceptor.Interceptor</em>接口<br />
。该接口声明了3个方法，<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;init();<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;destroy();<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />String&nbsp;intercept(ActionInvocation&nbsp;invocation)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Exception;</span></div>
<p>其中，init和destroy方法会在程序开始和结束时各执行一遍，不管使用了该拦截器与否，只要在<em>struts.xml</em>中声明了该拦截器就会被执行。<br />
intercept方法就是拦截的主体了，每次拦截器生效时都会执行其中的逻辑。</span></p>
<p><span>不过，struts中又提供了几个抽象类来简化这一步骤。<br />
<em>public abstract class AbstractInterceptor implements Interceptor;<br />
public abstract class MethodFilterInterceptor extends AbstractInterceptor;<br />
</em>都是模板方法实现的。<br />
其中<em>AbstractInterceptor</em>提供了init()和destroy()的空实现，使用时只需要覆盖intercept()方法；<br />
而<em>MethodFilterInterceptor</em>则提供了includeMethods和excludeMethods两个属性，用来过滤执行该过滤器的action的方法。可以通过param来加入或者排除需要过滤的方法。</span></p>
<p><span>一般来说，拦截器的写法都差不多。看下面的示例：<br />
</p>
<span id="Codehighlighter1_60_514_Open_Text"><span id="Codehighlighter1_137_514_Open_Text"><span id="Codehighlighter1_208_514_Open_Text">
<p>&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_60_628_Open_Image" onclick="this.style.display='none'; Codehighlighter1_60_628_Open_Text.style.display='none'; Codehighlighter1_60_628_Closed_Image.style.display='inline'; Codehighlighter1_60_628_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_60_628_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_60_628_Closed_Text.style.display='none'; Codehighlighter1_60_628_Open_Image.style.display='inline'; Codehighlighter1_60_628_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;AuthInterceptor&nbsp;</span><span style="color: #0000ff">extends</span><span style="color: #000000">&nbsp;MethodFilterInterceptor</span><span id="Codehighlighter1_60_628_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_60_628_Open_Text"><span style="color: #000000">{<br />
<img id="Codehighlighter1_138_626_Open_Image" onclick="this.style.display='none'; Codehighlighter1_138_626_Open_Text.style.display='none'; Codehighlighter1_138_626_Closed_Image.style.display='inline'; Codehighlighter1_138_626_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_138_626_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_138_626_Closed_Text.style.display='none'; Codehighlighter1_138_626_Open_Image.style.display='inline'; Codehighlighter1_138_626_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;String&nbsp;doIntercept(ActionInvocation&nbsp;invocation)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Exception&nbsp;</span><span id="Codehighlighter1_138_626_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_138_626_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;invocation.getInvocationContext().getSession();<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">如果session中存在username字段，且传入Action实现了Authenticatable接口，且验证成功<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">当然这里只是举例子，具体要根据业务逻辑来写</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(session.containsKey(</span><span style="color: #000000">"</span><span style="color: #000000">username</span><span style="color: #000000">"</span><span style="color: #000000">)</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;(invocation&nbsp;</span><span style="color: #0000ff">instanceof</span><span style="color: #000000">&nbsp;Authenticatable)<br />
<img id="Codehighlighter1_502_567_Open_Image" onclick="this.style.display='none'; Codehighlighter1_502_567_Open_Text.style.display='none'; Codehighlighter1_502_567_Closed_Image.style.display='inline'; Codehighlighter1_502_567_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_502_567_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_502_567_Closed_Text.style.display='none'; Codehighlighter1_502_567_Open_Image.style.display='inline'; Codehighlighter1_502_567_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;((Authenticatable)invocation).validate((String)session.get(</span><span style="color: #000000">"</span><span style="color: #000000">username</span><span style="color: #000000">"</span><span style="color: #000000">),(String)session.get(</span><span style="color: #000000">"</span><span style="color: #000000">password</span><span style="color: #000000">"</span><span style="color: #000000">)))</span><span id="Codehighlighter1_502_567_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_502_567_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">将数据流转给真正的Action</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;invocation.invoke();<br />
<img id="Codehighlighter1_572_623_Open_Image" onclick="this.style.display='none'; Codehighlighter1_572_623_Open_Text.style.display='none'; Codehighlighter1_572_623_Closed_Image.style.display='inline'; Codehighlighter1_572_623_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_572_623_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_572_623_Closed_Text.style.display='none'; Codehighlighter1_572_623_Open_Image.style.display='inline'; Codehighlighter1_572_623_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #0000ff">else</span><span id="Codehighlighter1_572_623_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_572_623_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">返回一个全局登录失败的result</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;Action.LOGIN;<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
<p></span></span></span></span></p>
<p>其中，if()逻辑内执行了从session中取用户信息及验证的逻辑，如果成功，则调用invocation.invoke()将逻辑交给Action，否则退出并返回一个全局的Login结果。</p>
<p><br />
<span><strong>2.声明拦截器</strong><br />
拦截器需要在struts.xml中声明。在说明步骤之前，先介绍一下struts中拦截器的框架。</span></p>
<p><span>在struts中拦截器实际上分为拦截器和拦截器栈，拦截器栈可以包含一到多个拦截器或者拦截器栈。从上层看来，拦截器和拦截器栈实际上没有什么区别（就像操作系统中的文件夹和文件）。struts在入口处递归的调用了<em>&lt;default-interceptor-ref&gt;</em>中定义的拦截器（栈）中的所有拦截器。</span></p>
<p><span>其实之前如果看过<em>struts-default.xml</em>的话，可以看到struts中内建了许多的拦截器，事实上，即便我们在<em>struts.xml</em>中什么都不声明，程序也会在后台执行缺省拦截器栈中定义的许多拦截器逻辑，比如说将页面上的field映射到对应Action的同名属性中、自动执行类型转换、自动关联验证xml等等。这些拦截器会在每个没有显式声明拦截器的Action执行前后被执行。</span></p>
<p><span>需要注意的是，正如上面一句所提到的，如果在Action中显式声明了一个拦截器，那么系统默认的拦截器将不会被调用。因此，如果直接将自定义的拦截器放入Action中的话，内建的那些拦截器将会被忽略，这会导致错误。所以我们需要在<em>struts.xml</em>的<em>&lt;package&gt;</em>元素下覆盖缺省拦截器。像下面这样：<br />
</span></p>
<p>&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">interceptors</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">interceptor-stack&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="default-with-my-inteceptor"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">interceptor-ref&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="defaultStack"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">interceptor-ref&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="XXX-interceptor"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">interceptor-stack</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">interceptor&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="XXX-interceptor"</span><span style="color: #ff0000">&nbsp;class</span><span style="color: #0000ff">="com.dev.interceptors.XXXInterceptor"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">interceptors</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">default-interceptor-ref&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="default-with-my-inteceptor"</span><span style="color: #0000ff">/&gt;</span></div>
<p>&nbsp;</p>
<p><span>这样就将自定义拦截器加上了struts缺省拦截器形成新的缺省拦截器。</span></p>
<p><span>因为全局定义了拦截器，虽然拦截器在通过拦截的情况下会返回特定Action的result，但有时候比如权限验证失败等情况下，自定义拦截器会返回自定义的结果，不属于任何特定Action，所以我们也需要定义一个全局result用以响应这个拦截器的返回值。<br />
紧挨在<em>&lt;default-interceptor-ref&gt;</em>元素下面添加<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">global-results</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">result&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">=""</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="redirectAction"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">global_error.jsp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">result</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">global-results</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /></span></div>
<p><br />
注意到其result type为redirectAction重定向Action，这样struts将以重定向方式处理该Action，并跳转到global_error.jsp而不会显示出最后一次执行的Action名字。顺便，Action的result缺省是以dispatcher也就是请求转发的方式处理的。</span></p>
<p><span>同时，按照业务逻辑，有些特定Action是不能执行自定义拦截器的。比如说，如果我们定义了一个全局的拦截器，它从session中取出用户名和密码进行验证，验证通过则继续，不通过则返回到login.jsp页面，那么很显然login.jsp页面提交的那个Action本身是不能使用该拦截器的，否则就没有地方可以将用户信息放入session了。<br />
这种情况下，就要借助之前提到的&#8220;特定Action中定义的拦截器会覆盖全局设置&#8221;这个特性了。在需要屏蔽该拦截器的个别Action中显式的声明defaultStack拦截器（也就是struts内建的拦截器栈），这样，自定义拦截器在这个Action中就不会生效了。</span></p>
<p><br />
<span><strong>小结一下：</strong><br />
写了这么多，其实大部分都在讲原理，如果理解了原理，这几部做起来是否常容易的。所以重要的是掌握原理。<br />
回忆一下，真正要做的只有三个地方：<br />
(1)写一个拦截器类（实现接口也好，继承抽象类也好）<br />
(2)修改struts.xml声明新的缺省拦截器栈和全局result<br />
(3)对于特定Action，显式声明defaultStack拦截器以屏蔽自定义拦截器</span></p>
<p><span><strong style="color: #333399">另外谈一点自己的看法：</strong><br />
拦截器可以说是struts当之无愧的核心，无论是struts的实现原理还是我们基于struts搭建的应用扩展，拦截器都发挥了重要的作用。当然也有可能是我自己的理解不够深入，但是有一点没想明白，就是拦截器只能基于Action发挥效用，如果一些功能和Action无关，那么拦截器没法发生效用。不知道struts底层实现细节中是否只开放了基于Action的拦截器，其实理论上来说，在web.xml中设置了struts作为filter，并拦截所有请求，拦截器在从页面发送至服务器被struts filter到的那一刻起（准确地说是&#8220;前一刻起&#8221;），拦截器就能发挥作用了。比如说现在这种过滤器只能在页面提交到Action时起作用，但无法防止用户直接访问JSP</span></p>
 <img src ="http://www.blogjava.net/yangmage/aggbug/253564.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yangmage/" target="_blank">Solar</a> 2009-02-06 15:00 <a href="http://www.blogjava.net/yangmage/articles/253564.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>