﻿<?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-刘文涛-随笔分类-Struts2.0</title><link>http://www.blogjava.net/liuwentao253/category/28006.html</link><description>SPRING,设计模式,UML,Oracle</description><language>zh-cn</language><lastBuildDate>Fri, 28 Dec 2007 04:32:38 GMT</lastBuildDate><pubDate>Fri, 28 Dec 2007 04:32:38 GMT</pubDate><ttl>60</ttl><item><title>struts2中配置篇值请求处理元素</title><link>http://www.blogjava.net/liuwentao253/archive/2007/12/28/171108.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Fri, 28 Dec 2007 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/12/28/171108.html</guid><description><![CDATA[对请求进行处理的元素主要有interceptors、Action以及Result。下面分别对其进行讲述。<br />
<br />
1．拦截器配置(interceptors)<br />
<br />
　　通过使用拦截器，我们可以在action中的方法执行之前先执行一些我们事先定义好了的方法，也可以在action中的方法执行之后立即执行一些我们事先定义好了的方法。在开发的过程中，拦截器将是一个强有力的工具。拦截器有很多很多的功能，如校验、属性封装、安全、日志等等，如下所示：<br />
<br />
校验(validation)： 检查输入是否正确<br />
<br />
属性封装(property population)： 将输入传输和转化为对象的属性<br />
<br />
日志(logging)： 记录关于每个action的详细信息<br />
<br />
切面(profiling)： 记录action的吞吐量，寻找性能瓶颈(不是很懂)<br />
<br />
　　我们可以将多个拦截器链接在一起形成一个拦截器栈。比方说一个action不仅要对客户端的资格进行审查，还要记录它自己的行为，那么我们可以将实现这两个功能的拦截器放在一起，形成一个<strong>拦截器栈</strong>(interceptor stack)。拦截器是以java类的形式实现的，因此每一个拦截器都有一个唯一的类名。为了让对拦截器的参考更加容易，我们可以在框架中为每个拦截器注册一个更简单的名字。下面给出了一个注册拦截器的例子：<br />
<br />
<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;</span><span style="color: #000000">interceptors</span><span style="color: #000000">&gt;<br />
</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">interceptor&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000"><u>security</u></span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">com.company.security.SecurityInterceptor</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;<br />
</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">interceptor</span><span style="color: #000000">-</span><span style="color: #000000">stack&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">secureStack</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">interceptor</span><span style="color: #000000">-</span><span style="color: #000000">ref&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000"><u>security</u></span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">interceptor</span><span style="color: #000000">-</span><span style="color: #000000">ref&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">defaultStack</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">interceptor</span><span style="color: #000000">-</span><span style="color: #000000">stack</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">interceptors</span><span style="color: #000000">&gt;</span></div>
<br />
<br />
　　在定义一个拦截器栈的时候，单个的拦截器和拦截器栈可以以任意的顺序混合在一起，struts框架将会按照拦截器在栈里面的顺序调用它们。大多数应用程序都会定义一个默认的拦截器栈，如：＜default-interceptor-ref name="defaultStack"/＞，默认的拦截器栈会作用于package中的每个action上。当然action还可以定义它自己的本地(局部)栈，如下面例子所示：<br />
<br />
<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 src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;</span><span style="color: #000000">action&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">VelocityCounter</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">org.apache.struts2.example.counter.SimpleCounter</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">result&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">success</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">result</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">interceptor</span><span style="color: #000000">-</span><span style="color: #000000">ref&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">defaultComponentStack</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">action</span><span style="color: #000000">&gt;</span></div>
<br />
<br />
　　2．Action配置<br />
<br />
　　action mappings是框架中的基本工作单元，框架通过对请求的request路径进行映射来决定由哪个action来处理请求。action mappings能指定一系列的result、异常处理器以及拦截器。action元素的所有属性中只有name属性是必须的，其它属性都是可选的。关于如何从请求路径映射到action在namespace那节中已经说过了，这里就不说了。尽管对于action的命名很灵活，但是action的名字中最好不要出现斜线(/)、点号(.)、破折号(/)，以免出现一些不可预知的错误。<br />
<br />
　　在Action接口中定义了action默认的方法入口，它就是execute方法。但是并不是每个action类都必须实现这个接口，如果action类没有实现这个接口的话，框架将使用反射来寻找一个execute方法。有时候我们的action中可能会包括多个方法入口，并且不同的情况下方法入口不同，例如执行修改操作时我们想进入action的mofify方法，执行增加操作时进入action的add方法，这个时候怎么办呢？我们可以通过指定action元素的method属性来实现，如下所示：<br />
<br />
＜action name="modify" class="example.CrudAction" method="modify"＞<br />
<br />
　　如果在action类中没有execute方法，也没有在配置文件中指定其它的方法，框架会抛出异常。<br />
<br />
　　很多时候，多个action mapping会共享一个相同的模式，这个时候我们可以使用通配符方法。还是举例来说,如下所示。<br />
<br />
＜action name=&#8221;editCrud&#8221; class=&#8221;example.CrudAction&#8221; method=&#8221;edit&#8221;/＞<br />
<br />
＜action name=&#8221;deleteCrud&#8221; class=&#8221; example.CrudAction&#8221; method=&#8221; delete&#8221;/＞<br />
<br />
　　上述两个action mapping调用的是同一个action类，只是执行的方法不同而已，并且所执行的方法名都是action mapping名字的开头部分，而且action mapping的名字除去方法名之后剩下的部分是一样的。这种情况下我们可以使用一个action mapping来代替上面两个action mapping：<br />
<br />
＜action name=&#8221;*Crud&#8221; class=&#8221;example.CrudAction&#8221; method=&#8221;{1}&#8221;＞<br />
<br />
　　匹配过程是这样的 (以请求的action mapping的名字是editCrud为例) ：<br />
<br />
　　● *可以表示任何内容，因此任何以Crud结尾的action mapping都会匹配上<br />
<br />
　　● 当editCrud匹配上后，*的内容此时就是edit<br />
<br />
　　● 调用名字为第一个*号的内容的方法，此时仅有一个*号，并且此时它的内容为edit，因此action类的edit方法被调用了<br />
<br />
　　● 同理，如果请求的action是deleteCrud，匹配成功后*的内容就是delete，调用的方法就是delete了。<br />
<br />
　　使用通配符匹配方法可以让我们减少配置文件的内容，是配置更加简洁。<br />
<br />
　　如果我们没有给action元素指定class属性的话，框架会默认它的class属性为com.opensymphony.xwork.ActionSupport，如果想指定别的类作为默认的Action类，可以通过package的default-action-ref属性来设置。在设置了default-action-ref之后，如果我们在package中没有匹配到所请求的action，那么这个默认的action就会被调用。一般一个命名空间下最好只定义一个默认的action。<br />
<br />
　　3．Result元素配置<br />
<br />
　　action类处理完一个请求后会返回一个字符串，这个字符串将被用来选择一个result元素。通常一个action mapping会有多个result，代表各个可能不同的结果。ActionSupport中定义了几个标准的result token，如下所示：<br />
<br />
String SUCCESS = "success"; <br />
String NONE = "none"; <br />
String ERROR = "error"; <br />
String INPUT = "input"; <br />
String LOGIN = "login"; <br />
<br />
　　通常我们都会自定义一些result token类匹配特定的情况。<br />
<br />
　　result元素负责完成两个工作：1.提供一个逻辑名用于与action类的返回字符串进行匹配；2.提供一个返回类型(Result Type)。尽管大多数的result只是简单的转向一个页面或模板，但是我们还可以利用其它的返回类型(Result Type)做其它的一些事情。我们可以为每个包设置默认的返回类型(Result Type)，如果一个包继承了另外一个包，它可以选择设置自己的默认返回类型或者直接使用父包的。设置默认返回类型的方式如下：<br />
<br />
＜result-types＞<br />
＜result-type name="dispatcher" default="true" <br />
class="org.apache.struts2.dispatcher.ServletDispatcherResult"/＞<br />
＜/result-types＞<br />
Result元素有两个属性：name和type，它们都是可选的，name属性的默认值是&#8220;success&#8221;，type的属性为我们所设置的默认返回类型，如上例中即为dispatcher。<br />
<br />
　　定义在action元素里面的result我们可以称之为局部result，除此之外我们可以还可以全局的result，这些result会被多个action所共享。框架会首先寻找嵌套在action元素中的result，如果没有匹配的就去全局result中去寻找。一个全局result的例子如下：<br />
<br />
＜global-results＞<br />
＜result name="error"＞/Error.jsp＜/result＞<br />
＜result name="invalid.token"＞/Error.jsp＜/result＞<br />
＜result name="login" type="redirect-action"＞Logon!input＜/result＞<br />
＜/global-results＞<br />
<br />
　　有时候我们的result在运行前可能是未知的。比方说，一个result它所跳转的页面取决于它所在action类的运行结果或者客户端的输入等等，这时候我们可以使用动态的result，也就是说result的值可以使用表达式语言(EL)来表示，这个表达式的值是动态的，取决于action的运行时状况，下面是一个例子：<br />
<br />
private String nextAction; <br />
public String getNextAction() {<br />
return nextAction; <br />
}<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
＜action name="fragment" class="FragmentAction"＞<br />
＜result name="next" type="redirect-action"＞${nextAction}＜/result＞<br />
＜/action＞<br />
<br />
　　在上例中result的值将是它所在action的nextAction的属性值，nextAction属性的值不同，当action的方法返回&#8221;next&#8221;时所跳向的url也不同。 
<img src ="http://www.blogjava.net/liuwentao253/aggbug/171108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-12-28 10:53 <a href="http://www.blogjava.net/liuwentao253/archive/2007/12/28/171108.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>理解拦截器</title><link>http://www.blogjava.net/liuwentao253/archive/2007/12/10/166685.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Mon, 10 Dec 2007 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/12/10/166685.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: .1.&nbsp;&nbsp;&nbsp; 什么是拦截器：拦截器，在AOP（Aspect-Oriented Programming）中用于在某个方法或字段被访问之前，进行拦截,然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码，...&nbsp;&nbsp;<a href='http://www.blogjava.net/liuwentao253/archive/2007/12/10/166685.html'>阅读全文</a><img src ="http://www.blogjava.net/liuwentao253/aggbug/166685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-12-10 15:56 <a href="http://www.blogjava.net/liuwentao253/archive/2007/12/10/166685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>理解拦截器</title><link>http://www.blogjava.net/liuwentao253/archive/2007/12/10/166686.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Mon, 10 Dec 2007 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/12/10/166686.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: .1.&nbsp;&nbsp;&nbsp; 什么是拦截器：拦截器，在AOP（Aspect-Oriented Programming）中用于在某个方法或字段被访问之前，进行拦截,然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码，...&nbsp;&nbsp;<a href='http://www.blogjava.net/liuwentao253/archive/2007/12/10/166686.html'>阅读全文</a><img src ="http://www.blogjava.net/liuwentao253/aggbug/166686.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-12-10 15:56 <a href="http://www.blogjava.net/liuwentao253/archive/2007/12/10/166686.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2与Struts1的对比</title><link>http://www.blogjava.net/liuwentao253/archive/2007/12/10/166673.html</link><dc:creator>刘文涛</dc:creator><author>刘文涛</author><pubDate>Mon, 10 Dec 2007 07:25:00 GMT</pubDate><guid>http://www.blogjava.net/liuwentao253/archive/2007/12/10/166673.html</guid><description><![CDATA[<p>
<table class="confluenceTable" style="border-right: 1px solid; border-top: 1px solid; border-left: 1px solid; border-bottom: 1px solid" bordercolor="#000000" cellspacing="1" bgcolor="#c0c0c0">
    <tbody>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#000000"><font size="2">特性 </font></th>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#000000"><font size="2">Struts 1 </font></th>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#000000"><font size="2">Struts 2 </font></th>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Action 类</font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080">
            <p><font size="2">Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是<u>使用抽象类编程而不是接口</u>。</font></p>
            </td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080">
            <p><font size="2">Struts 2 Action类可以实现一个Action接口，也可实现其他接口，使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去实现 常用的接口。Action接口不是必须的，<u>任何有execute标识的POJO对象都可以用作Struts2的Action对象。</u></font></p>
            </td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">线程模式</font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts1 Action是<u>单例模式并且必须是线程安全的</u>，因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事，并且要在开发时特别小心。Action资源必须是线程安全的或同步的。</font></td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts2 Action对象为每一个请求产生一个实例，因此没有线程安全问题。（实际上，servlet容器给每个请求产生许多可丢弃的对象，并且不会导致性能和垃圾回收问题）</font></td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Servlet 依赖 </font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。</font></td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts 2 Action不依赖于容器，允许Action脱离容器单独被测试。如果需要，Struts2 Action仍然可以访问初始的request和response。但是，其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。</font></td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">可测性</font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">测试Struts1 Action的一个主要问题是execute方法暴露了servlet API（这使得测试要依赖于容器）。一个第三方扩展－－Struts TestCase－－提供了一套Struts1的模拟对象（来进行测试）。</font></td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts 2 Action可以通过初始化、设置属性、调用方法来测试<u>，&#8220;依赖注入&#8221;支持也使测试更容易</u>。</font></td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">捕获输入</font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm，开发者经常创建多余的类捕获输入。动态Bean（DynaBeans）可以作为创建传统ActionForm的选择，但是，开发者可能是在重新描述(创建)已经存在的JavaBean（仍然会导致有冗余的javabean）。<br clear="all" />
            　</font></td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts 2直接使用Action属性作为输入属性，消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型，包括业务对象，能够用作输入/输出对象。这种ModelDriven 特性简化了taglib对POJO输入对象的引用。</font></td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">表达式语言</font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts1 整合了JSTL，因此使用JSTL EL。这种EL有基本对象图遍历，但是对集合和索引属性的支持很弱。</font></td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts2可以使用JSTL，但是也支持一个更强大和灵活的表达式语言－－"Object Graph Notation Language" (OGNL). </font></td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">绑定值到页面（view）</font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts 1使用标准JSP机制把对象绑定到页面中来访问。</font></td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts 2 使用 "ValueStack"技术，使taglib能够访问值而不需要把你的页面（view）和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面（view）。<br clear="all" />
            　</font></td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">类型转换</font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器，对每一个实例来说是不可配置的。 </font>
            <p><font size="2">　</font></p>
            </td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。</font></td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">校验 </font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts 1支持在ActionForm的validate方法中手动校验，或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容，但不能校验子对象。</font></td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#808080"><font size="2">Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验，来支持chain校验子属性 </font></td>
        </tr>
        <tr>
            <th class="confluenceTh" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#000000"><font size="2">Action执行的控制</font></th>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#000000"><font size="2">Struts1支持每一个模块有单独的Request Processors（生命周期），但是模块中的所有Action必须共享相同的生命周期。</font></td>
            <td class="confluenceTd" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid" bordercolor="#000000"><font size="2">Struts2支持通过拦截器堆栈（Interceptor Stacks）为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。</font></td>
        </tr>
    </tbody>
</table>
&nbsp;</p>
<img src ="http://www.blogjava.net/liuwentao253/aggbug/166673.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuwentao253/" target="_blank">刘文涛</a> 2007-12-10 15:25 <a href="http://www.blogjava.net/liuwentao253/archive/2007/12/10/166673.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>