??xml version="1.0" encoding="utf-8" standalone="yes"?>97久久超碰,99只有精品,51精品久久久久久久蜜臀http://www.aygfsteel.com/conans/category/32511.html你越挣扎我就兴?/description>zh-cnSun, 09 Aug 2009 23:11:08 GMTSun, 09 Aug 2009 23:11:08 GMT60Struts2采用convention-plugin实现雉|?/title><link>http://www.aygfsteel.com/conans/articles/289508.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Sun, 02 Aug 2009 14:28:00 GMT</pubDate><guid>http://www.aygfsteel.com/conans/articles/289508.html</guid><description><![CDATA[<p>最q开始关注struts2的新Ҏ,从这个版本开始,Struts开始用convention-plugin代替codebehind-plugin来实现struts的零配置?br /> 配置文g_了,的确是简便了开发过E,但是Q我们熟悉的配置H然disappear了,真是一下很不适应。跟着潮流走吧Q看看该怎样来搞定convention-plugin?br /> 使用Convention插gQ你需要将其JAR文g攑ֈ你应用的WEB-INF/lib目录中,你也可以在你Maven目的POM文g中添加下面包依赖</p> <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://javeye.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">dependency</span><span id="wmqeeuq" class="tag">></span><span>  </span></span></li> <li><span>  </span><span id="wmqeeuq" class="tag"><</span><span id="wmqeeuq" class="tag-name">groupId</span><span id="wmqeeuq" class="tag">></span><span>org.apache.struts</span><span id="wmqeeuq" class="tag"></</span><span id="wmqeeuq" class="tag-name">groupId</span><span id="wmqeeuq" class="tag">></span><span>  </span></li> <li><span>  </span><span id="wmqeeuq" class="tag"><</span><span id="wmqeeuq" class="tag-name">artifactId</span><span id="wmqeeuq" class="tag">></span><span>struts2-convention-plugin</span><span id="wmqeeuq" class="tag"></</span><span id="wmqeeuq" class="tag-name">artifactId</span><span id="wmqeeuq" class="tag">></span><span>  </span></li> <li><span>  </span><span id="wmqeeuq" class="tag"><</span><span id="wmqeeuq" class="tag-name">version</span><span id="wmqeeuq" class="tag">></span><span>2.1.6</span><span id="wmqeeuq" class="tag"></</span><span id="wmqeeuq" class="tag-name">version</span><span id="wmqeeuq" class="tag">></span><span>  </span></li> <li><span id="wmqeeuq" class="tag"></</span><span id="wmqeeuq" class="tag-name">dependency</span><span id="wmqeeuq" class="tag">></span><span>  </span></li> </ol> </div> <pre class="xml" style="display: none;" name="code"><dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-convention-plugin</artifactId> <version>2.1.6</version> </dependency></pre> <p><br /> <br /> 雉|ƈ不是没有配置Q而是通过U定大于配置的方式,大量通过U定来调度页面的跌{而得配|大大减。所以,首先应该了解下convention-plugin的约定:<br /> 1. 默认所有的l果面都存储在WEB-INF/content下,你可以通过讄struts.convention.result.pathq个属性的值来改变到其他\径。如Q?/p> <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://javeye.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">constant</span><span> </span><span id="wmqeeuq" class="attribute">name</span><span>=</span><span id="wmqeeuq" class="attribute-value">"struts.convention.result.path"</span><span> </span><span id="wmqeeuq" class="attribute">value</span><span>=</span><span id="wmqeeuq" class="attribute-value">"/WEB-INF/page"</span><span> </span><span id="wmqeeuq" class="tag">/></span><span>  </span></span></li> </ol> </div> <pre class="xml" style="display: none;" name="code"><constant name="struts.convention.result.path" value="/WEB-INF/page" /></pre> <p><br /> 则将路径配置CWEB-INF/page 下?br /> 2. 默认包\径包含action,actions,struts,struts2的所有包都会被struts作ؓ含有Actioncȝ路径来搜索。你可以通过讄struts.convention.package.locators属性来修改q个配置。如Q?/p> <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://javeye.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">constant</span><span> </span><span id="wmqeeuq" class="attribute">name</span><span>=</span><span id="wmqeeuq" class="attribute-value">"struts.convention.package.locators"</span><span> </span><span id="wmqeeuq" class="attribute">value</span><span>=</span><span id="wmqeeuq" class="attribute-value">"web,action"</span><span> </span><span id="wmqeeuq" class="tag">/></span><span>  </span></span></li> </ol> </div> <pre class="xml" style="display: none;" name="code"><constant name="struts.convention.package.locators" value="web,action" /></pre> <p><br /> 则定义了在项目中Q包路径包含web和action的将被视为Action存在的\径来q行搜烦?br /> Com.ustb.web.*/com.ustb.action.*都将被视为含有Action的包路径而被搜烦?br /> 3. 接着QConvention从前一步找到的package以及其子package中寻?com.opensymphony.xwork2.Action 的实C及以Actionl尾的类Q?/p> <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://javeye.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span>com.example.actions.MainAction   </span></span></li> <li><span>com.example.actions.products.Display (</span><span id="wmqeeuq" class="keyword">implements</span><span> com.opensymphony.xwork2.Action)   </span></li> <li><span>com.example.struts.company.details.ShowCompanyDetailsAction  </span></li> </ol> </div> <pre class="java" style="display: none;" name="code">com.example.actions.MainAction com.example.actions.products.Display (implements com.opensymphony.xwork2.Action) com.example.struts.company.details.ShowCompanyDetailsAction</pre> <p><br /> <br /> 4. 命名I间。从定义?package.locators标示开始到包结束的部分Q就是命名空间。D个例子:<br /> Com.ustb.web.user.userAction的命名空间是Q?#8221;/user”。Com.ustb.web.user.detail.UserAction的命名空间是Q?#8221;/user/detail”<br /> 5. Convention通过如下规则定URL的具体资源部?Lcd的Action部分。然后将每个分部的首字母{为小写,?#8217;-’分割Q你可以讄struts.convention.action.name.separator ?/p> <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://javeye.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">constant</span><span> </span><span id="wmqeeuq" class="attribute">name</span><span>=</span><span id="wmqeeuq" class="attribute-value">"struts.convention.action.name.separator"</span><span> </span><span id="wmqeeuq" class="attribute">value</span><span>=</span><span id="wmqeeuq" class="attribute-value">"-"</span><span> </span><span id="wmqeeuq" class="tag">/></span><span>  </span></span></li> </ol> </div> <pre class="xml" style="display: none;" name="code"><constant name="struts.convention.action.name.separator" value="-" /></pre> <p><br /> q是举个例子Q?br /> UserAction->user  UserDetailAction ->user-detail。结合上面的。对于com.ustb.web.user.detail.UserDetailActionQ映的url是/WEB-INF/content/user/detail/user-detail.jsp<br /> 6. struts支持.jsp .html .htm .vm格式的文件?br /> 下面是actiong和结果模版的映射关系Q?strong><br /> </strong></p> <table style="height: 130px;" align="left" border="1" width="590"> <tbody> <tr> <td><strong>URL</strong> </td> <td><strong>Result <br /> </strong></td> <td><strong>File that could match</strong> </td> <td><strong>Result Type</strong> </td> </tr> <tr> <td>/hello</td> <td>success</td> <td>/WEB-INF/content/hello.jsp</td> <td>Dispatcher</td> </tr> <tr> <td>/hello</td> <td>success</td> <td>/WEB-INF/content/hello-success.htm </td> <td>Dispatcher</td> </tr> <tr> <td>/hello</td> <td>success</td> <td>/WEB-INF/content/hello.ftl </td> <td>FreeMarker</td> </tr> <tr> <td>/hello-world</td> <td>input</td> <td>/WEB-INF/content/hello-world-input.vm</td> <td>Velocity</td> </tr> <tr> <td>/test1/test2/hello</td> <td>error</td> <td>/WEB-INF/content/test/test2/hello-error.html</td> <td>Dispatcher</td> </tr> </tbody> </table> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p>以上的内Ҏ自struts2的文?a target="_blank">http://struts.apache.org/2.1.6/docs/convention-plugin.html</a> </p> <p> </p> <p><br /> 当然Q简单的通过默认的方式来q行配置不能完全满实际目的需要。所q,convention的零配置是非常灵zȝ?br /> <strong>通过@Action注释</strong> <br /> 对如下例子:</p> <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://javeye.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.example.web;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.Action;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;    </span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> HelloAction </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"action1"</span><span>)   </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> String method1() {   </span></li> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> SUCCESS;   </span></li> <li><span>    }   </span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/user/action2"</span><span>)   </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> String method2() {   </span></li> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> SUCCESS;   </span></li> <li><span>}   </span></li> <li><span>}  </span></li> </ol> </div> <pre class="java" style="display: none;" name="code">package com.example.web; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionSupport; public class HelloAction extends ActionSupport { @Action("action1") public String method1() { return SUCCESS; } @Action("/user/action2") public String method2() { return SUCCESS; } } </pre> <p> </p> <table style="height: 65px;" border="0" width="640"> <tbody> <tr> <td><strong>Ҏ?/strong> </td> <td><strong>默认调用路径</strong> </td> <td><strong>默认映射路径</strong> </td> </tr> <tr> <td><span style="font-size: small;">method1</span> </td> <td><span style="font-size: small;">/hello!method1.action .</span> </td> <td><span style="font-size: small;">/WEB-INF/content/hello.jsp</span> </td> </tr> <tr> <td><span style="font-size: small;">method2</span> </td> <td><span style="font-size: small;">/hello!method2.action.</span> </td> <td><span style="font-size: small;">/WEB-INF/content/hello.jsp</span> </td> </tr> </tbody> </table> <p><span style="color: #ff6600;"><span style="text-decoration: underline;">通过@Action注释?/span> </span></p> <table style="height: 64px;" border="0" width="639"> <tbody> <tr> <td><strong>Ҏ?/strong> </td> <td><strong>@Action注释后调用\?/strong> </td> <td><strong>@Action注释</strong> <strong>后映\?/strong> </td> </tr> <tr> <td><span style="font-size: small;">method1</span> </td> <td><span style="font-size: small;">/action1!method1.action.</span> </td> <td><span style="font-size: small;">/WEB-INF/content/action1.jsp</span> </td> </tr> <tr> <td><span style="font-size: small;">method1</span> </td> <td><span style="font-size: small;">/user/action2!method2.action</span> </td> <td><span style="font-size: small;">/WEB-INF/content/user/action2.jsp</span> </td> </tr> </tbody> </table> <p><br /> <strong>通过@Actions注释</strong> </p> <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://javeye.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.example.web;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;    </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Action;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Actions;   </span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> HelloAction </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></li> <li><span>  </span><span id="wmqeeuq" class="annotation">@Actions</span><span>({   </span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/different/url"</span><span>),   </span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/another/url"</span><span>)   </span></li> <li><span>  })   </span></li> <li><span>  </span><span id="wmqeeuq" class="keyword">public</span><span> String method1() {   </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">return</span><span> “error”;   </span></li> <li><span>  }  </span></li> </ol> </div> <pre class="java" style="display: none;" name="code">package com.example.web; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Actions; public class HelloAction extends ActionSupport { @Actions({ @Action("/different/url"), @Action("/another/url") }) public String method1() { return “error”; }</pre> <p><br /> 我们可以通过Q?span style="font-size: medium;"><strong><span style="color: #008000;"><span style="color: #0000ff;"><span style="font-size: small;"><em>/different/url!method1.action</em> </span></span></span></strong>?/span> <span style="font-size: small; color: #008000;"><strong><span style="font-size: medium;"><span style="color: #0000ff;"><span style="font-size: small;"><em>/another/url!method1.action</em> </span></span></span></strong></span>来调?strong>method1</strong> Ҏ?br /> 对应的映\径分别是<strong><span style="font-size: small; color: #0000ff;"><em>/WEB-INF/content/different/url-error.jsp; /WEB-INF/content/another/url-error.jsp</em> </span><br /> </strong><br /> 可能误导了大Ӟ一个方法被@Action注释后,只是多了一U调用方式,而不是说覆盖了原来的调用方式。比如对于如下例子:</p> <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://javeye.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.example.web;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;    </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Action;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Actions;   </span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> HelloAction </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></li> <li><span>  </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/another/url"</span><span>)   </span></li> <li><span>  </span><span id="wmqeeuq" class="keyword">public</span><span> String method1() {   </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">return</span><span> “error”;   </span></li> <li><span>  }  </span></li> </ol> </div> <pre class="java" style="display: none;" name="code">package com.example.web; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Actions; public class HelloAction extends ActionSupport { @Action("/another/url") public String method1() { return “error”; }</pre> <p><br /> 我们调用method1Ҏ可以通过两种方式Q?br /> 1 <span style="font-size: medium; color: #0000ff;"> <span style="font-size: small;"><strong>/hello!method1.action</strong> </span></span><span style="font-size: small;">映射</span> <span style="font-size: small;">urlQ?strong><span style="font-size: small; color: #0000ff;">/WEB-INF/content/hello-error.jsp</span> </strong></span><span style="font-size: small;"><br /> 2</span> <span style="font-size: small;"><span style="font-size: medium;"><strong><span style="font-size: small; color: #0000ff;">/another/url!method1.action</span> </strong></span></span><span style="font-size: small;">映射</span> <span style="font-size: small;">urlQ?span style="font-size: small;"><strong><span style="color: #0000ff;">/WEB-INF/content/another/url-error.jsp</span> </strong></span></span><br /> 可见Q两U方式均可对method1Ҏq行调用Q唯一的区别就是,两种调用的映是不一LQ所以,惌转到不同的界面,q是一个非常好的选择?br /> <br /> <br /> <strong>通过@Namespace 注释</strong> </p> <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://javeye.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.example.web;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;    </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Action;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Actions;   </span></li> <li><span id="wmqeeuq" class="annotation">@Namespace</span><span>(</span><span id="wmqeeuq" class="string">"/other"</span><span>)   </span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> HelloWorld </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></li> <li><span>  </span></li> <li><span>  </span><span id="wmqeeuq" class="keyword">public</span><span> String method1() {   </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">return</span><span> “error”;   </span></li> <li><span>  }   </span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"url"</span><span>)   </span></li> <li><span>  </span><span id="wmqeeuq" class="keyword">public</span><span> String method2() {   </span></li> <li><span id="wmqeeuq" class="keyword">return</span><span> “error”;   </span></li> <li><span>  }   </span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/different/url"</span><span>)   </span></li> <li><span>  </span><span id="wmqeeuq" class="keyword">public</span><span> String method3() {   </span></li> <li><span id="wmqeeuq" class="keyword">return</span><span> “error”;   </span></li> <li><span>  }   </span></li> <li><span>}  </span></li> </ol> </div> <pre class="java" style="display: none;" name="code">package com.example.web; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Actions; @Namespace("/other") public class HelloWorld extends ActionSupport { public String method1() { return “error”; } @Action("url") public String method2() { return “error”; } @Action("/different/url") public String method3() { return “error”; } }</pre> <p><br /> <br /> <span style="font-size: small;">通过 <strong><span style="font-size: small; color: #0000ff;">/other/hello-world!method1.action</span> </strong></span><span style="font-size: small;">讉K<strong>method1</strong> Ҏ?br /> 通过</span> <strong><span style="font-size: small; color: #0000ff;">/other/url!method2.action</span> </strong><span style="font-size: small;">讉K<strong>method2</strong> Ҏ<br /> 通过</span> <strong><span style="font-size: small; color: #0000ff;">/different /url!method3.action</span> </strong><span style="font-size: small;">讉K<strong>method3</strong> Ҏ</span> <br /> 与@Action 注释不同的是Q该注释覆盖了默认的namespace(q里?#8217;/’)Q此时再?span style="font-size: small;">hello!method1.action</span> 已经不能讉K<strong>method1</strong> ?<br /> <strong>@Results和@Result</strong> <br /> <strong>1 全局的(globalQ?/strong> <br /> 全局results可以被actioncM所有的action分nQ这Uresults在actioncM使用注解q行声明?/p> <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://javeye.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.example.actions;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;    </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Action;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Actions;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Result;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Results;   </span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="annotation">@Results</span><span>({   </span></li> <li><span>  </span><span id="wmqeeuq" class="annotation">@Result</span><span>(name=</span><span id="wmqeeuq" class="string">"failure"</span><span>, location=</span><span id="wmqeeuq" class="string">"/WEB-INF/fail.jsp"</span><span>)   </span></li> <li><span>})   </span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> HelloWorld </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></li> <li><span>  </span><span id="wmqeeuq" class="keyword">public</span><span> String method1() {   </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">return</span><span> “failure”;   </span></li> <li><span>  }   </span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/different/url"</span><span>)   </span></li> <li><span>  </span><span id="wmqeeuq" class="keyword">public</span><span> String method2() {   </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">return</span><span> “failure”;   </span></li> <li><span>  }   </span></li> <li><span>  </span></li> <li><span>}  </span></li> </ol> </div> <pre class="java" style="display: none;" name="code">package com.example.actions; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Actions; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; @Results({ @Result(name="failure", location="/WEB-INF/fail.jsp") }) public class HelloWorld extends ActionSupport { public String method1() { return “failure”; } @Action("/different/url") public String method2() { return “failure”; } }</pre> <p><span style="font-size: small;"><br /> </span><span style="font-size: small;">当我们访?/span> <span style="font-size: small;"><strong></strong></span><span style="font-size: small;"><strong><span style="font-size: small; color: #0000ff;">/hello</span> </strong></span><span style="font-size: small;"><strong><span style="font-size: small; color: #0000ff;">-world</span> </strong></span><span style="font-size: small;"><strong><span style="font-size: small; color: #0000ff;">!method1.action</span> </strong><span style="font-size: small;">Ӟq回</span> <span style="font-size: small; color: #0000ff;"><strong>/WEB-INF/fail.jsp</strong> </span><br /> <span style="font-size: small;">当我们访?/span> <strong><span style="font-size: small; color: #0000ff;">/hello</span> </strong></span><span style="font-size: small;"><strong><span style="font-size: small; color: #0000ff;">-world</span> </strong></span><span style="font-size: small;"><strong><span style="font-size: small; color: #0000ff;">!method2.action</span> </strong><span style="font-size: small;">Ӟq回</span> <strong><span style="font-size: small; color: #0000ff;">/WEB-INF/fail.jsp</span> </strong><br /> <span style="font-size: small;">当我们访?/span> <strong><span style="font-size: small; color: #0000ff;">/different/url!method2.action</span> </strong><span style="font-size: small;">Ӟq回</span> <strong><span style="font-size: small; color: #0000ff;">/WEB-INF/fail.jsp</span> </strong></span><br /> <br /> <strong>2 本地的(localQ?/strong> <br /> 本地results只能在actionҎ上进行声明?/p> <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://javeye.javaeye.com/images/icon_copy.gif" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.example.actions;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;    </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Action;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Actions;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Result;   </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> org.apache.struts2.convention.annotation.Results;   </span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> HelloWorld </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(value=</span><span id="wmqeeuq" class="string">"/other/bar"</span><span>,results={</span><span id="wmqeeuq" class="annotation">@Result</span><span>(name = </span><span id="wmqeeuq" class="string">"error"</span><span>, location = </span><span id="wmqeeuq" class="string">"www.baidu.com"</span><span>,type=</span><span id="wmqeeuq" class="string">"redirect"</span><span>)})   </span></li> <li><span>  </span><span id="wmqeeuq" class="keyword">public</span><span> String method1() {   </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">return</span><span> “error”;   </span></li> <li><span>  }   </span></li> <li><span>}  </span></li> </ol> </div> <pre class="java" style="display: none;" name="code">package com.example.actions; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Actions; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; public class HelloWorld extends ActionSupport { @Action(value="/other/bar",results={@Result(name = "error", location = "www.baidu.com",type="redirect")}) public String method1() { return “error”; } }</pre> <p><br /> <span style="font-size: small;">当我们调?/span> <span style="font-size: small;"><strong><span style="color: #0000ff;">/hello</span> </strong></span><span style="font-size: small;"><strong><span style="font-size: small; color: #0000ff;">-world</span> </strong></span><span style="font-size: small;"><strong><span style="color: #0000ff;">!method1.action</span> </strong></span><span style="font-size: small;">Ӟq回</span> <strong><span style="font-size: small; color: #0000ff;">/WEB-INF/content/hello-error.jsp</span> </strong><span style="font-size: small;"><br /> </span><span style="font-size: small;">当我们调?/span> <strong><span style="font-size: small; color: #0000ff;">/other/bar!method1.action</span> </strong><span style="font-size: small;">Ӟq回</span> <span style="font-size: small;"><strong><span style="color: #0000ff;">www.baidu.com</span> </strong></span><br /> </p> <img src ="http://www.aygfsteel.com/conans/aggbug/289508.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/conans/" target="_blank">CONAN</a> 2009-08-02 22:28 <a href="http://www.aygfsteel.com/conans/articles/289508.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2开发环境搭?http://www.aygfsteel.com/conans/articles/283364.htmlCONANCONANSat, 20 Jun 2009 08:16:00 GMThttp://www.aygfsteel.com/conans/articles/283364.html 搭徏最单的开发环? Top
首先我们来看看如何搭建最单的J2EE目的开发环境?

1. 我们需要徏立的一个空的J2EE目的目录结?/strong>



在这里,我简单解释一下这些目录的作用Q?

src(source folder)Q存放所有的Java源代码?
conf(source folder)Q存放所有的配置文g?
test(source folder)Q存放所有的Java试代码和调试代码?
webQweb目的根目录Q下面有WEB-INF目录以及在此之下的classes和lib目录。classes目录会成ؓ所有的source folder的编译对象目录,而lib目录则存N目所依赖的jar包?
libQ也存放jar包,q些jar包可能仅仅在开发调试时依赖Q项目本w则不依赖这些jar文g?

2. ~写IDE相关的文?/strong>

在这里,你还能看到classpath文g和project文g。这两个文g是导入到eclipse中所必须的文Ӟ是我为eclipse工程而写的文件。如果你使用其他IDEQ可能需要自行编辑与其他IDE相关的项目文件?

在徏立了q些目录l构后,你就可以其导入到eclipse中作为eclipse的工E了?



3. 加入相关调试所需要的jar包,q指定classpath

接下来,我们把Jetty所需要的jar包copy到lib目录下,q在IDE中指定classpath?



4. dJetty启动c?/strong>

在test下徏一个runtime的目录,q添加Jetty启动cR?

Java代码
  1. package runtime;  
  2.   
  3. import org.mortbay.jetty.Connector;  
  4. import org.mortbay.jetty.Server;  
  5. import org.mortbay.jetty.nio.SelectChannelConnector;  
  6. import org.mortbay.jetty.webapp.WebAppContext;  
  7.   
  8. /** 
  9.  * Jetty Server starter. Use embedded mode. 
  10.  *  
  11.  * @author Downpour 
  12.  */  
  13. public class JettyStarter {  
  14.   
  15.     /** 
  16.      * @param args 
  17.      * @throws Exception 
  18.      */  
  19.     public static void main(String[] args) throws Exception {  
  20.         long begin = System.currentTimeMillis();  
  21.         Connector connector = new SelectChannelConnector();  
  22.         connector.setPort(Integer.getInteger("jetty.port"8080).intValue());  
  23.   
  24.         WebAppContext webapp = new WebAppContext("web""/struts-sample");  
  25.         webapp.setDefaultsDescriptor("./test/runtime/webdefault.xml");  
  26.           
  27.         Server server = new Server();  
  28.         server.setConnectors(new Connector[] { connector });  
  29.         server.setHandler(webapp);  
  30.         server.start();  
  31.         System.out.println("Jetty Server started, use " + (System.currentTimeMillis() - begin) + " ms");  
  32.     }  
  33. }  


如果此时Q你在WEB-INF下有web.xmlQ那么你可以执行上面这个Jetty的启动类?



5. 启动、调试、测?/strong>

执行了Jetty的启动类后,可以看到启动界面的日志:

Java代码
  1. 15 [main] INFO org.mortbay.log - Logging to org.slf4j.impl.SimpleLogger(org.mortbay.log) via org.mortbay.log.Slf4jLog  
  2. 15 [main] INFO org.mortbay.log - jetty-6.1.7  
  3. 1109 [main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8080  
  4. Jetty Server started, use 1547 ms  


q表CZ已经成功启动了Jetty作ؓ你的Web服务器。当Ӟ你可以用Debug模式来执行Jettyc,q样p入了调试模式Q你可以在代码中讄断点q行调试?

在这里,q有一炚w要简单提一下,默认情况下,Jetty会在windows上用缓存,所以会把jsQcss{文件进行锁定,使你无法~辑。ؓ了解册个问题,需要设|一些默认参数。这里,我们可以使用google大法Q已l有朋友为我们解决了q个问题Q?

http://www.aygfsteel.com/alwayscy/archive/2007/05/27/120305.html

所以,我在runtime的同U目录徏立了一个webdefault.xml文gQƈ且指定Jetty使用该文件作为默认的参数讑֮?

【小l?/strong>
在上面我介绍了我个h的开发调试环境,q种开发环境的好处可能有一下这些:

1. 开发环境不依赖于Q何IDE或者相关的插gQ只需要运行Java文g卛_q行调试。(当然Q你可能需要编写IDE相关的project文g来获取IDE的工E支持)

2. 开发环境不依赖于Q何外部的Web服务器,与环境无养I所以无论将目q移到哪里,都可以直接运行?

3. 不需要开发h员额外学习如何搭建开发环境,开发环境已l内|,降低了开发h员的学习成本?

完善Library的管理方? Top

在上面搭建环境的q程中,我们发现QLibrary的管理存在着一定问题。这个问题主要表CؓQ?

1. 不容易做Library的版本管理。如果Library的版本需要升U,那么我们不得不重新copy一份新的jar包,q且借助IDE重新指定目? classpath。这U劳动,对于一个项目还可以接受Q如果你?0多个目Q那么jar包的复制工作会让你很头疼?

2. 每个目都会有Library的副本。这一点让人非常恼火。实际上Q对于一个公司或者一个项目组而言Q用的技术体pd本不变。然而,每个目? Library却是分开的。不仅如此,每个目都要从svn中下载大量的相同的Library文gQ给我们的硬盘造成极大的空间浪贏V对于那些频J? Branch的项目来_q些Library的下载简直就是噩梦?

所以,我们需要一?strong>集中式的Library理方式
。而这一Ҏl在Javaeye的v阔天I版Ȁ烈得讨论q用maven来进行管理还是自行管理?

Readonly 写道

׃ncd可以用IDE reference project解决Q公司内部项目给常用的lib建立一个projectQ从CVS上check outQ其他工E项目都依赖q个project可以了Qant build也直接引用这个项目的jar可以,目体积照样只有几百K?

——一个讨厌antQ更加讨厌maven的h


我比较赞同Readonly老大的说法而們֐于自行管理。mavenq样的高U货Q偶实在是用不来啊。那么我们就来看看如何用共享类库来q行Library理?


1. 首先建立一个共享类?/strong>

建立一个共享类库,项目中需要共享的Libraryq行恰当的分cR同Ӟ为每个加入到Library中的jar包进行统一的格式化的命名方 式。例如:spring/spring-2.5.5.jar{等。这L好处在于Q一旦jar包的版本有更斎ͼ可以加入新的jar包而保留原来的。在目 中,可以通过引用不同版本的jar包来对Libraryq行版本理?

以下是我个人徏立的一个共享类库,大家可以参考:

svn://www.demo2do.com/library

2. checkout׃ncdQƈ其导入到IDE中作Z个Library工程



3. Z的项目指定classpathQ引用的jar包存在于Library工程?/strong>



在这里,我们可以看到Q原来项目中的lib目录被删除,jar包也被删除。在目中所引用的jar包是Library目中的jar包?

【小l?/strong>
完成了上q所有的步骤之后QLibraryp集中理hQ而每个项目也不会再变得那么庞大。当Ӟ开发环境的搭徏完全取决于个人的习惯Q所以用各自喜Ƣ的方式吧,不要让环境问题束~你们的手脚?br />
转自Qhttp://www.javaeye.com/wiki/struts2/1321-struts2-development-environment-to-build


CONAN 2009-06-20 16:16 发表评论
]]>
LightURL——打造零配置的Struts2开发方?/title><link>http://www.aygfsteel.com/conans/articles/231367.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Fri, 26 Sep 2008 12:03:00 GMT</pubDate><guid>http://www.aygfsteel.com/conans/articles/231367.html</guid><description><![CDATA[<strong>背景</strong> <br /> <br /> Struts2已经日益成ؓWeb层比较主的开发框Ӟ它来源于Webwork2Q是一个非怼U的MVC框架。在Webwork2设计之处QAnnotation和Ruby on Railsq没有像现在那么火,所以整个框架在配置斚wq是沿用了Web框架惯用的XML作ؓ主要的配|方式?<br /> <br /> 随着时代的发展,对于WebE序员来_如何化配|成了一个很重要的课题。在q方面,Struts2也有一些探索。在Struts2的官方网站上Q我们可以找C些优U的plugin来做q些工作Q?<br /> <br /> <a target="_blank">http://cwiki.apache.org/S2PLUGINS/codebehind-plugin.html</a> <br /> <br /> <a target="_blank">http://cwiki.apache.org/S2PLUGINS/smarturls-plugin.html</a> <br /> <br /> LightURL的目的是Z吸取q些优秀的plugin的优点,q支持更方便的配|方式?<br /> <br /> <strong>安装</strong> <br /> <br /> 1. struts2-lighturl-plugin.jar加入到classpath?<br /> <br /> 2. 配置你的web.xml <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.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol class="dp-j"> <li><span><span>       </span></span></li> <li><span>    <!-- Struts Filter -->   </span></li> <li><span><filter>   </span></li> <li><span>    <filter-name>struts</filter-name>   </span></li> <li><span>    <filter-</span><span id="wmqeeuq" class="keyword">class</span><span>>com.demo2do.lighturl.LightURLFilter</filter-</span><span id="wmqeeuq" class="keyword">class</span><span>>   </span></span></li> <li><span></filter>   </span></li> <li><span>  </span></li> <li><span><!-- Struts URL Definition -->   </span></li> <li><span><filter-mapping>   </span></li> <li><span>    <filter-name>struts</filter-name>   </span></li> <li><span>    <url-pattern>/*</url-pattern>   </span></li> <li><span></filter-mapping>      </span></li> </ol> </div> <pre class="java" style="display: none" name="code"> <!-- Struts Filter --> <filter> <filter-name>struts</filter-name> <filter-class>com.demo2do.lighturl.LightURLFilter</filter-class> </filter> <!-- Struts URL Definition --> <filter-mapping> <filter-name>struts</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </pre> <br /> <br /> 3. 需要指定你的action package所在位|和一些基本配|?<br /> <br /> q一步一般在struts.properties中完成。你可以Z个struts.properties的配|文Ӟq放到classpath下,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.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol class="dp-j"> <li><span><span>## action </span><span id="wmqeeuq" class="keyword">package</span><span> config   </span></span></li> <li><span>lighturl.action.packages=com.demo2do.lighturl.action   </span></li> <li><span>  </span></li> <li><span>## action mapping implementation </span><span id="wmqeeuq" class="keyword">class</span><span>  </span></span></li> <li><span>struts.mapper.</span><span id="wmqeeuq" class="keyword">class</span><span>=com.demo2do.lighturl.LightURLActionMapper   </span></span></li> <li><span>  </span></li> <li><span>## </span><span id="wmqeeuq" class="keyword">default</span><span> parent </span><span id="wmqeeuq" class="keyword">package</span><span>  </span></span></li> <li><span>lighturl.action.</span><span id="wmqeeuq" class="keyword">default</span><span>.parent.</span><span id="wmqeeuq" class="keyword">package</span><span>=struts-config   </span></span></li> <li><span>  </span></li> <li><span>## define your entity </span><span id="wmqeeuq" class="keyword">package</span><span> (optional)   </span></span></li> <li><span># lighturl.entity.</span><span id="wmqeeuq" class="keyword">package</span><span>=com.demo2do.lighturl.entity  </span></span></li> </ol> </div> <pre class="java" style="display: none" name="code">## action package config lighturl.action.packages=com.demo2do.lighturl.action ## action mapping implementation class struts.mapper.class=com.demo2do.lighturl.LightURLActionMapper ## default parent package lighturl.action.default.parent.package=struts-config ## define your entity package (optional) # lighturl.entity.package=com.demo2do.lighturl.entity </pre> <br /> <br /> 在完成以上的步骤后,lighturl的所有配|即告完成,现在你已l可以用所有lighturl所提供的特性?<br /> <br /> <strong>Namespace, ActionName和URL映射</strong> <br /> <br /> lighturl所提供的最基本的特性是Ҏ你的Action所在的packageQ确定namespace和actionNameQƈq行对应的URL映射?<br /> <br /> 举例说明Q你在上面所讲述的struts.properties中,已经指定了你的action package <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.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol class="dp-j"> <li><span><span>lighturl.action.packages=com.demo2do.lighturl.action  </span></span></li> </ol> </div> <pre class="java" style="display: none" name="code">lighturl.action.packages=com.demo2do.lighturl.action </pre> <br /> <br /> 那么Q如果你有以下的Actionc,那么lighturl根据如下的规则来确定每个ActioncL对应的namespaceQactionName和url映射关系 <br /> <br /> 1. Ҏlighturl.action.packages的配|的packageC的Actioncȝ相对package来确定namespaceQ如果其中有驼峰法命名,那么转化?-"q接的单?<br /> <ul> <li>com.demo2do.lighturl.action.Index  ----> / <li>com.demo2do.lighturl.action.user.Search ----> /user <li>com.demo2do.lighturl.action.blog.category.Index ----> /blog/category <li>com.demo2do.lighturl.action.accoutDetail.View ----> /account-detail </li> </ul> <br /> 2. Actioncȝcd转化成actionName。如果碰到的ActioncM"Action"l尾Q则L末尾?Action"Q如果其中有驼峰法命?那么转化?-"q接的单?<br /> <ul> <li>com.demo2do.lighturl.action.Index ----> index <li>com.demo2do.lighturl.action.user.SearchAction ----> search <li>com.demo2do.lighturl.action.blog.CategoryBlog ----> category-blog </li> </ul> <br /> 3. namespace与actionNameDv来,成构成映射到具体Actioncȝurl <br /> <ul> <li>http://host:port/app/user/index ---> com.demo2do.lighturl.action.user.Index <li>http://host:port/app/blog/category-blog ---> com.demo2do.lighturl.action.blog.CategoryBlog </li> </ul> <br /> 上面的这UURL匚w方式Q我UC为:<strong>package匚w</strong> <br /> <br /> <strong>Ҏ形式的URL</strong> <br /> <br /> 应该说根据package来进行Action映射Q可以解决绝大多Curl到action的映配|问题。不q有的时候,我们可能需要支持一些特DŞ式的url。LightURL在默认情况下Q支持下?U特DŞ式的URL <br /> <br /> 1. 支持名为Index的Action直接映射到package?<br /> <br /> q种匚w我称之ؓQ?strong>Namespace匚w</strong>。这一个特性很直观。如果你在某个Action的package下面有一个名为Index的Actionc,那么如果你直接访问这个packageQ那么你可以讉K到这个类Q?<br /> <ul> <li>com.demo2do.lighturl.action.Index ---> http://host:port/app/ <li>com.demo2do.lighturl.action.user.Index ---> http://host:port/app/user <li>com.demo2do.lighturl.action.blog.category.Index ---> http://host:port/app/blog/category </li> </ul> <br /> 2. 支持cM: /entity/${id}形式的URL <br /> <br /> q种匚w我通常UC为:<strong>entity匚w</strong>。这个特性也比较单,如果你有某个entityQƈ且在你的Action package下有一个与entity同名的package。同时在q个package下有一个叫View的ActionQ那么上qŞ式的URL会被映射到该Action?<br /> <ul> <li>com.demo2do.lighturl.action.user.View ---> http://host:port/app/user/3456 <li>com.demo2do.lighturl.action.blog.View ---> http://host:port/app/user/1113 </li> </ul> <br /> 你可以通过在struts.properties中指定你entity所在的package来对哪些url可以具备q些Ҏ,如果你输入的url不在你所指定的package中含有entityQ那么这个url无法被识别?<br /> 针对有些情况Q数据库的主键可能不是数字。此Ӟ你可以通过自己实现com.demo2do.lighturl.config.EntityPrimaryKeyIdentifier的接口来指定你的url中id具备什么特炏V默认的实现是将主键识别为数字?<br /> <br /> <strong>使用Annotation来指定映?/strong> <br /> <br /> 除了上述q些基本Ҏ以外,q可以通过Annotaion来指定URL映射。目前情况下QLightURL所支持的Annotation有两U类? <br /> <br /> 1. URL完整匚w <br /> <br /> URL完整匚w是指如果某个url完整匚w于Annotation中所指定的内容,那么q个URL被映射到Annotation所在的Actioncȝmethod <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.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.demo2do.lighturl.action.user;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.demo2do.lighturl.annotation.Action;   </span></span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="comment">/** </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> * @author Downpour </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> * </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> */</span><span>  </span></span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> Search </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></span></li> <li><span>       </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> </span><span id="wmqeeuq" class="keyword">static</span><span> </span><span id="wmqeeuq" class="keyword">final</span><span> </span><span id="wmqeeuq" class="keyword">long</span><span> serialVersionUID = -1728616675239859226L;   </span></span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="comment">/* (non-Javadoc) </span> </span></li> <li><span><span id="wmqeeuq" class="comment">     * @see com.opensymphony.xwork2.ActionSupport#execute() </span> </span></li> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Override</span><span>  </span></span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/all/search-user"</span><span>)   </span></span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> String execute() </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span></li> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> </span><span id="wmqeeuq" class="keyword">super</span><span>.execute();   </span></span></li> <li><span>    }   </span></li> <li><span>  </span></li> <li><span>}  </span></li> </ol> </div> <pre class="java" style="display: none" name="code">package com.demo2do.lighturl.action.user; import com.demo2do.lighturl.annotation.Action; import com.opensymphony.xwork2.ActionSupport; /** * @author Downpour * */ public class Search extends ActionSupport { private static final long serialVersionUID = -1728616675239859226L; /* (non-Javadoc) * @see com.opensymphony.xwork2.ActionSupport#execute() */ @Override @Action("/all/search-user") public String execute() throws Exception { return super.execute(); } } </pre> <br /> <br /> 例如Q上q的ActioncL一个AnnotationQ那么这个Action和method被映射到对应的URL:http://host:port/app/all/search-user?<br /> <br /> 注意Q此Ӟ虽然从url上来看,q是一个没有什么规则的urlQ但是其所对应的namespace和actionNameq是Ҏcom.demo2do.lighturl.action.user.Search来进行计的?<br /> <br /> 2. URL Template <br /> <br /> URL Template是指Qurl可以匚wAnnotaion中指定的某种URL TemplateQƈ其中的可变部分作ؓ参数映射到Action中?<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.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.demo2do.lighturl.action.blog;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.demo2do.lighturl.annotation.Action;   </span></span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="comment">/** </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> * @author Downpour </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> * </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> */</span><span>  </span></span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> Category </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> </span><span id="wmqeeuq" class="keyword">static</span><span> </span><span id="wmqeeuq" class="keyword">final</span><span> </span><span id="wmqeeuq" class="keyword">long</span><span> serialVersionUID = -1535992103374733252L;   </span></span></li> <li><span>  </span></li> <li><span>        </span><span id="wmqeeuq" class="keyword">private</span><span> Long id;   </span></span></li> <li><span>       </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> </span><span id="wmqeeuq" class="keyword">int</span><span> year;   </span></span></li> <li><span>       </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> </span><span id="wmqeeuq" class="keyword">int</span><span> month;   </span></span></li> <li><span>       </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> </span><span id="wmqeeuq" class="keyword">int</span><span> day;   </span></span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="comment">/* (non-Javadoc) </span> </span></li> <li><span><span id="wmqeeuq" class="comment">     * @see com.opensymphony.xwork2.ActionSupport#execute() </span> </span></li> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Override</span><span>  </span></span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/blogs/${year}/${month}/${day}"</span><span>)   </span></span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> String execute() </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span></li> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> </span><span id="wmqeeuq" class="keyword">super</span><span>.execute();   </span></span></li> <li><span>    }   </span></li> <li><span>           </span></li> <li><span>        </span><span id="wmqeeuq" class="annotation">@Action</span><span>(</span><span id="wmqeeuq" class="string">"/blog/${id}/edit"</span><span>)   </span></span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> String edit() </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span></li> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> </span><span id="wmqeeuq" class="keyword">super</span><span>.execute();   </span></span></li> <li><span>    }   </span></li> <li><span>        </span><span id="wmqeeuq" class="comment">// setters and getters </span><span>  </span></span></li> <li><span>       </span></li> <li><span>}  </span></li> </ol> </div> <pre class="java" style="display: none" name="code">package com.demo2do.lighturl.action.blog; import com.demo2do.lighturl.annotation.Action; import com.opensymphony.xwork2.ActionSupport; /** * @author Downpour * */ public class Category extends ActionSupport { private static final long serialVersionUID = -1535992103374733252L; private Long id; private int year; private int month; private int day; /* (non-Javadoc) * @see com.opensymphony.xwork2.ActionSupport#execute() */ @Override @Action("/blogs/${year}/${month}/${day}") public String execute() throws Exception { return super.execute(); } @Action("/blog/${id}/edit") public String edit() throws Exception { return super.execute(); } // setters and getters } </pre> <br /> <br /> 在上q的例子中,可以发现Q在Annotation中所指定的内Ҏ一个URL TemplateQ如果你有一个urlQ可以匹配上面的URL TemplateQ那么url匹配到q个Action的methodQƈ且将对应位置的值注入到Action中的同名参数中?<br /> <br /> 针对上面的例子: <br /> http://host:port/app/blogs/2008/08/07被映射到这个Action的executeQƈ?008Q?8?7分别映射到yearQmonth和day中?<br /> http://host:port/app/blog/2345/edit被映射到Action的editҎQƈ?345映射到id中作为参?<br /> <br /> <strong>URL的匹配顺序与重复配置的校?/strong> <br /> <br /> 在上面的例子中,介绍了那么多的url映射到Action中的方式。他们之间可能会出现冲突Q有些冲H,LightURL会在pȝ启动时ؓ你检查出来,q强制要求你U正它,而有些冲H,则通过优先U匹配的方式q行?<br /> <br /> 下列冲突被认ؓ是你必须在系l启动前p行纠正的Q?<br /> 1. Annotation中定义的URL Template互相之间冲突 <br /> <br /> 例如Q?blogs/${year}/${month}/${day}?blogs/${category}/${id}/edit是冲突的?<br /> <br /> 2. Annotation中定义的URL Template与其他Annotation中定义的完全匚wURL冲突 <br /> <br /> 例如Q?blogs/${year}/${month}?blogs/category/index是冲突的?<br /> <br /> 3. Annotation中定义的URL Template与Ş?entity/${id}的url定义冲突 <br /> <br /> 例如Q?user/${id}形式的Annotation定义可能会与pȝ默认支持的冲H?<br /> <br /> 在其他情况下Q如果你定义的URL映射互相直接有冲H,那么LightURL根据某个顺序进行URL匚wQƈ扑ֈW一个匹配的映射方式Q然后放弃查找。这个顺序ؓQ?<br /> 1. 首先q行<strong>Namespace匚w</strong>Q如果url恰好能匹配某个namespaceQƈ且其对应的package下有Index作ؓActionQ那么直接进行匹配?<br /> 2. 其次查看所有的Annotation定义中,是否存在<strong>完整的URL匚w</strong>Q如果找刎ͼ那么q行直接匚w?<br /> 3. 接着q行<strong>package匚w</strong>Q将url分解成相应的namespace和actionNameQ与已有的配|进行匹配,如果扑ֈQ那么直接匹配?<br /> 4. 然后q行<strong>entity匚w</strong>Q看看url是否形如:/entity/${id}Q如果是Q那么直接匹配?<br /> 5. 最后进行Annotation定义?strong>Url Template匚w</strong>?<br /> <br /> 如果所有的五种情况都无法进行匹配,那么q个URL无法被LightURL识别Ql交由Struts2q行后箋处理?<br /> <br /> <br /> 上面所描述的内定w是Url到Action的映。下面的部分Q描q的是如何在Action执行完毕之后Q{到相应的l果view?<br /> <br /> <strong>Codebehind</strong> <br /> <br /> LightURL支持codebehind。有关codebehind的相关知识,可以参考struts2的相x档: <br /> <a target="_blank">http://struts.apache.org/2.x/docs/codebehind-plugin.html</a> <br /> <br /> 有了codebehind的支持,那么从Action转到cMjspQftl或者vm的view层组件就不需要Q何配|,只要W合一定的命名规范Q就可以直接q行转向?<br /> <br /> <strong>ResultCode的识?/strong> <br /> <br /> 但是在很多情况下Q我们需要的是全方位的Resultcd的支持。例如,有的时候我们需要返回JSON ResultQ有的时候,我们可能需要RedirectC个新的Action。此Ӟ我们不得不ؓ此增加一些配|,或者借助Annotation来完成?<br /> <br /> 为此QLightURL提供了一U根据ResultCodeq行识别的命名方式来匚w你所指定的Result?<br /> <br /> 以JSON ResultZQ你可以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.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.demo2do.lighturl.action.user;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.demo2do.lighturl.entity.User;   </span></span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="comment">/** </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> * @author Downpour </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> * </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> */</span><span>  </span></span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> Index </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> </span><span id="wmqeeuq" class="keyword">static</span><span> </span><span id="wmqeeuq" class="keyword">final</span><span> </span><span id="wmqeeuq" class="keyword">long</span><span> serialVersionUID = -5017825114664788765L;   </span></span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> User user;   </span></span></li> <li><span>       </span></li> <li><span>    </span><span id="wmqeeuq" class="comment">/* (non-Javadoc) </span> </span></li> <li><span><span id="wmqeeuq" class="comment">     * @see com.opensymphony.xwork2.ActionSupport#execute() </span> </span></li> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Override</span><span>  </span></span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> String execute() </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span></li> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> </span><span id="wmqeeuq" class="string">"j:user"</span><span>;   </span></span></li> <li><span>    }   </span></li> <li><span>  </span></li> <li><span>        </span><span id="wmqeeuq" class="comment">// setters and getters </span><span>  </span></span></li> <li><span>}  </span></li> </ol> </div> <pre class="java" style="display: none" name="code">package com.demo2do.lighturl.action.user; import com.demo2do.lighturl.entity.User; import com.opensymphony.xwork2.ActionSupport; /** * @author Downpour * */ public class Index extends ActionSupport { private static final long serialVersionUID = -5017825114664788765L; private User user; /* (non-Javadoc) * @see com.opensymphony.xwork2.ActionSupport#execute() */ @Override public String execute() throws Exception { return "j:user"; } // setters and getters } </pre> <br /> <br /> 在这里,你可以发玎ͼresultCode变成了j:user。那么此ӞLightURL会将q个resultCode识别成:误回JSON ResultQƈ且JSON的Result的root为user对象?<br /> <br /> 再例如: <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.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol class="dp-j"> <li><span><span id="wmqeeuq" class="keyword">package</span><span> com.demo2do.lighturl.action.user;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.demo2do.lighturl.entity.User;   </span></span></li> <li><span id="wmqeeuq" class="keyword">import</span><span> com.opensymphony.xwork2.ActionSupport;   </span></span></li> <li><span>  </span></li> <li><span id="wmqeeuq" class="comment">/** </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> * @author Downpour </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> * </span> </span></li> <li><span><span id="wmqeeuq" class="comment"> */</span><span>  </span></span></li> <li><span id="wmqeeuq" class="keyword">public</span><span> </span><span id="wmqeeuq" class="keyword">class</span><span> Index </span><span id="wmqeeuq" class="keyword">extends</span><span> ActionSupport {   </span></span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> </span><span id="wmqeeuq" class="keyword">static</span><span> </span><span id="wmqeeuq" class="keyword">final</span><span> </span><span id="wmqeeuq" class="keyword">long</span><span> serialVersionUID = -5017825114664788765L;   </span></span></li> <li><span>  </span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">private</span><span> User user;   </span></span></li> <li><span>       </span></li> <li><span>    </span><span id="wmqeeuq" class="comment">/* (non-Javadoc) </span> </span></li> <li><span><span id="wmqeeuq" class="comment">     * @see com.opensymphony.xwork2.ActionSupport#execute() </span> </span></li> <li><span><span id="wmqeeuq" class="comment">     */</span><span>  </span></span></li> <li><span>    </span><span id="wmqeeuq" class="annotation">@Override</span><span>  </span></span></li> <li><span>    </span><span id="wmqeeuq" class="keyword">public</span><span> String execute() </span><span id="wmqeeuq" class="keyword">throws</span><span> Exception {   </span></span></li> <li><span>        </span><span id="wmqeeuq" class="keyword">return</span><span> </span><span id="wmqeeuq" class="string">"r:/user/add-user"</span><span>;   </span></span></li> <li><span>    }   </span></li> <li><span>  </span></li> <li><span>        </span><span id="wmqeeuq" class="comment">// setters and getters </span><span>  </span></span></li> <li><span>}  </span></li> </ol> </div> <pre class="java" style="display: none" name="code">package com.demo2do.lighturl.action.user; import com.demo2do.lighturl.entity.User; import com.opensymphony.xwork2.ActionSupport; /** * @author Downpour * */ public class Index extends ActionSupport { private static final long serialVersionUID = -5017825114664788765L; private User user; /* (non-Javadoc) * @see com.opensymphony.xwork2.ActionSupport#execute() */ @Override public String execute() throws Exception { return "r:/user/add-user"; } // setters and getters } </pre> <br /> <br /> 在这里,"r:/user/add-user"会被识别成:误回Redirect Result。Redirect的URL?user/add-user?<br /> <br /> LightURL默认情况下,实现了对Redirect Result和JSON Result的ResultCode识别Qƈ他们的前缀分别定制为:"r:"("redirect:")或?j:"("json:")?<br /> <br /> 当然Q你可以Ҏ你自q情况Q实C自己的ResultCode的识别程序,你只需要实现com.demo2do.lighturl.result.ResultCodeConfig接口卛_。ƈ在struts.properties中指定你希望LightURLq行ResultCode匚w的顺序?<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.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol class="dp-j"> <li><span><span>lighturl.result.code.config=yourpackage.ResultCodeConfigImpl1,yourpackage.ResultCodeConfigImpl2  </span></span></li> </ol> </div> <pre class="java" style="display: none" name="code">lighturl.result.code.config=yourpackage.ResultCodeConfigImpl1,yourpackage.ResultCodeConfigImpl2 </pre> <br /> <br /> q样QLightURL会根据你所指定的顺序,依次q行ResultCode的匹配,直到扑ֈW一个匹配的Result TypeZ?<br /> <br /> 当然Q默认情况下QLightURL的匹配顺序ؓQ?<br /> <br /> codebehind -> 你自定义的ResultCode识别实现 -> json -> redirect <img src ="http://www.aygfsteel.com/conans/aggbug/231367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/conans/" target="_blank">CONAN</a> 2008-09-26 20:03 <a href="http://www.aygfsteel.com/conans/articles/231367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2教程Q-W二章 Struts2的工作机制及分析 http://www.aygfsteel.com/conans/articles/214089.htmlCONANCONANThu, 10 Jul 2008 11:29:00 GMThttp://www.aygfsteel.com/conans/articles/214089.html阅读全文

CONAN 2008-07-10 19:29 发表评论
]]>
Struts2与Struts1.x的深度比?/title><link>http://www.aygfsteel.com/conans/articles/213756.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Wed, 09 Jul 2008 11:12:00 GMT</pubDate><guid>http://www.aygfsteel.com/conans/articles/213756.html</guid><description><![CDATA[<p><span>Struts</span><span>作ؓ</span><span>MVC 2</span><span>?/span><span>Web</span><span>框架Q自推出以来不断受到开发者的q捧Q得到广泛的应用。作为最成功?/span><span>Web</span><span>框架Q?/span><span>Struts</span><span>自然拥有众多的优点:</span><span>MVC 2</span><span>模型的用、功能齐全的标志库(</span><span>Tag Library</span><span>Q、开放源代码?/span></p> <p><span>但是Q正所?/span><span>“</span><span>没有最好,只有更好</span><span>”</span><span>Q?/span><span>Struts1.x</span><span>自n也有不少的缺点:需要编写的代码q多Q容易引?/span><span>“</span><span>cȝ?/span><span>”</span><span>、单元测试困难。这些缺炚w着</span><span>Web</span><span>的发展越来越明显。这׃生了</span><span>Struts 2</span><span>Q它的诞生能很好的解决上q问题?/span></p> <p><span>在本文中Q笔者将?/span><span>Struts2</span><span>?/span><span>Struts1.x</span><span>q两U框架进行详l的比较。比较将涉及到这两种框架?/span><span>Action</span><span>、验证、类型{换及如何开发等斚w的内宏V希望通过q样的比较,让读者了解这两种框架各自的特点,以便于在自己的项目中Q根据实际情况,快的过渡到</span><span>Struts2</span><span>的时代。本文的内容Z</span><span>Struts<ST1:CHSDATE w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">2.0.6</ST1:CHSDATE></span><span>?/span></p> <p><strong> </strong></p> <p><strong><span><span>一?span>       </span></span></span></strong><strong><span>引言</span></strong><strong></strong></p> <p><strong> </strong></p> <p><span>Struts</span><span>的第一个版本是?/span><span>2001</span><span>q?/span><span>5</span><span>月䆾发布的。它的最初设x通过l合</span><span>JSP</span><span>?/span><span>Servlet</span><span>Q</span><span>Web</span><span>应用的视囑֒业务</span><span>/</span><span>应用逻辑得以清晰地分d来。在</span><span>Struts</span><span>之前Q最常见的做法是?/span><span>JSP</span><span>中加入业务和应用逻辑Q或者在</span><span>Servlet</span><span>中通过</span><span>println()</span><span>来生成视图?/span></p> <p><span>自从W一版发布以来,</span><span>Struts</span><span>实际上已成ؓ业界公认?/span><span>Web</span><span>应用标准。它的炙手可热也己带来了改进和变_所以不但要跟上?/span><span>Web</span><span>应用框架不断变化的需求,而且要与日渐增多竞争Ȁ烈的众多框架的特性相融合?/span></p> <p><span>到最后,产生了几个下一?/span><span>Struts</span><span>的解x案。其中两个最受瞩目的Ҏ?/span><span>Shale</span><span>?/span><span>Struts Ti</span><span>?/span><span>Shale</span><span>是一个基于构件的框架Qƈ在最q成?/span><span>Apache</span><span>的顶U项目。?/span><span>Struts Ti</span><span>则是?/span><span>Struts</span><span>的成功经验基上l坚持对前端控制器(</span><span>Front Controller</span><span>Q和</span><span>MVC</span><span>Q?/span><span>model-view-controller</span><span>Q模式进行改q?/span></p> <p><span>WebWork</span><span>目是在</span><span>2002</span><span>q?/span><span>3</span><span>月发布的Q它?/span><span>Struts</span><span>式框架进行了革命性改q,引进了不新的思想、概念和功能Q但和原</span><span>Struts</span><span>代码q不兼容?/span><span>WebWork</span><span>是一个成熟的框架Q经q了好几ơ重大的改进与发布?/span></p> <p><span>?/span><span>2005</span><span>q?/span><span>12</span><span>月,</span><span>WebWork</span><span>?/span><span>Struts Ti</span><span>宣布合ƈ。与此同Ӟ</span><span>Struts Ti</span><span>改名?/span><span>Struts Action Framework 2.0</span><span>Q成?/span><span>Struts</span><span>真正的承者?/span></p> <p><span>最后要注意的是Qƈ不是?/span><span>Struts</span><span>?/span><span>WebWork</span><span>目已经停止开发了。由于h们对q两个项目的兴趣仍然很高Q而且也有很多开发者仍然愿意用它们,因此q两个项目还在l开发中Ql修?/span><span>Bug</span><span>Q改q功能和l箋d新功能?/span><strong></strong></p> <p><strong> </strong></p> <p><strong><span><span>二?span>       </span></span></span></strong><strong><span>Action</span></strong><strong><span>的区?/span></strong><strong></strong></p> <p><strong> </strong></p> <p><span>对于有着丰富?/span><span>Struts1.x</span><span>开发经验的朋友来说Q都十分的清?/span><span>Action</span><span>是整?/span><span>Struts</span><span>框架的核心内容,当然</span><span>Struts2</span><span>也不例外。不q,</span><span>Struts1.x</span><span>?/span><span>Struts2</span><span>?/span><span>Action</span><span>模型很大的区别?/span></p> <p><span>Struts2</span><span>?/span><span>Struts1.x</span><span>的差别,最明显的就?/span><span>Struts2</span><span>是一?/span><span>pull-MVC</span><span>架构。这是什么意思呢Q从开发者角度看Q就是说需要显C给用户的数据可以直接从</span><span>Action</span><span>中获取,而不?/span><span>Struts1.x</span><span>那样Q必L相应?/span><span>Bean</span><span>存到</span><span>Page</span><span>?/span><span>Request</span><span>或?/span><span>Session</span><span>中才能获取?/span><span>Struts1.x </span><span>必须l承</span><span>org.apache.struts.action.Action</span><span>或者其子类Q表单数据封装在</span><span>FormBean</span><span>中?/span><span>Struts 2</span><span>无须l承Mcd或实CQ何接口,表单数据包含?/span><span>Action</span><span>中,通过</span><span>Getter</span><span>?/span><span>Setter</span><span>获取Q如下面?/span><span>ActionForStruts2</span><span>的代码示例)?/span></p> <p><span>虽然Q在理论?/span><span>Struts2</span><span>?/span><span>Action</span><span>无须实现M接口或者是l承M的类Q但是,在实际编E过E中Qؓ了更加方便的实现</span><span>Action</span><span>Q大多数情况下都会?/span><span>com.opensymphony.xwork2.ActionSupport</span><span>c,q且重蝲Q?/span><span>Override</span><span>Q此c里?/span><span>String execute()</span><span>Ҏ。如下所C:</span></p> <p align="left"><span>package ActionDiffer;</span></p> <p align="left"><span> import java.text.DateFormat;</span></p> <p align="left"><span> import java.util.Date;</span></p> <p align="left"> </p> <p align="left"><span> import com.opensymphony.xwork2.ActionSupport;</span></p> <p align="left"> </p> <p align="left"><span> public class ActionForStruts2 extends ActionSupport {</span></p> <p align="left"><span><span>     </span>private String message;</span></p> <p align="left"><span><span>    </span></span></p> <p align="left"><span><span>     </span>public String getMessage() {</span></p> <p align="left"><span><span>         </span>return message;</span></p> <p align="left"><span><span>    </span>} </span></p> <p align="left"><span><span>    </span></span></p> <p align="left"><span><span>    </span>@Override </span></p> <p align="left"><span><span>     </span>public String execute() {</span></p> <p align="left"><span><span>        </span>message = " This is hello from strtuts2. Now is: " + DateFormat.getInstance().format( new Date());</span></p> <p align="left"><span><span>         </span>return SUCCESS;</span></p> <p align="left"><span><span>    </span>} </span></p> <p align="left"><span>}</span></p> <p><span>首先Q从</span><span>ActionForStruts2</span><span>可以看出Q返回的对象不是</span><span>ActionForward</span><span>Q而是</span><span>String</span><span>。如果你不喜Ƣ以字符串的形式出现在你的代码中Q有?/span><span>Helper</span><span>接口</span><span>Action</span><span>可以以常量方式提供常见结果,?/span><span>“success”</span><span>?/span><span>“none”</span><span>?/span><span>“error”</span><span>?/span><span>“input”</span><span>?/span><span>“login”</span><span>?/span></p> <p><span>另外Q?/span><span> </span><span>按照惯例Q在</span><span>Struts1.x</span><span>中只?/span><span>“execute”</span><span>Ҏ能调?/span><span>Action,</span><span> 但在</span><span>Struts2</span><span>中ƈ非必要,M声明?/span><span>public String methodName() </span><span>ҎQ都能通过配置来调?/span><span>Action</span><span>?/span></p> <p><span>最后,?/span><span>Struts1.x</span><span>最大的革命性的不同是,</span><span>Struts2</span><span>处理</span><span>Action</span><span>q程中调用的ҎQ?/span><span>“execute”</span><span>ҎQ是不带参数的。那如何获取所需要的对象呢?{案是?/span><span>IoC</span><span>Q反转控Ӟ</span><span>Inversion of Control)</span><span>Q也?/span><span>“</span><span>依赖注入Q?/span><span>Dependency Injection</span><span>Q?/span><span>”</span><span>的模式(x多地了解q方面信息请?/span><span>Martin Fowler</span><span>的文?/span><span><a target="_blank"><span>http://www.martinfowler.com/articles/injection.html</span></a></span><span>Q?/span><span>Spring</span><span>框架使得q个模式行hQ然?/span><span>Struts2</span><span>的前w(</span><span>WebWork</span><span>Q也同时应用上了q个模式?/span></p> <p><strong> </strong></p> <p><strong><span><span>三?span>       </span></span></span></strong><strong><span>IoC</span></strong></p> <p><span>IoC(Inversion of Control</span><span>Q以下译为控制反转)Q随着</span><span>Java</span><span>C֌中轻量容器Q?/span><span>Lightweight Contianer</span><span>Q的推广而越来越为大家耳熟能详。在此,无需再多费唇舌来解释</span><span>“</span><span>什么是控制反{</span><span>”</span><span>?/span><span>“</span><span>Z么需要控制反?/span><span>”</span><span>。因Z联网上已l有非常多的文章对诸如此cȝ问题作了_ֽ而准的回答。读者可以去M?/span><span>Rod Johnson</span><span>?/span><span>Juergen Hoeller</span><span>合著的?/span><span><a ><span>Expert one-on-one J2EE Development without EJB</span></a></span><span>》或</span><span>Martin Fowler</span><span>所写的?/span><span><a target="_blank"><span>Inversion of Control Containers and the Dependency Injection pattern</span></a></span><span>》?/span></p> <p><span>众所周知Q?/span><span>Struts2</span><span>是以</span><span>Webwork 2</span><span>作ؓ基础发展出来。而在</span><span>Webwork 2.2</span><span>之前?/span><span>Webwork</span><span>版本Q其自n有一套控制反转的实现Q?/span><span>Webwork 2.2</span><span>?/span><span><a ><span>Spring </span><span><span>框架</span></span></a></span><span>的如火如荼发展的背景下,军_攑ּ控制反{功能的开发,转由</span><span>Spring</span><span>实现。值得一提的是,</span><span>Spring</span><span>实是一个值得学习的框Ӟ因ؓ有越来越多的开源组Ӟ?/span><span><a ><span>iBATIS</span></a></span><span>{)都放弃与</span><span>Spring</span><span>重叠的功能的开发。因此,</span><span>Struts2</span><span>推荐大家通过</span><span>Spring</span><span>实现控制反{?/span></p> <p><span>Z更好C解反转控Ӟ下面来看一个例子,如何利用</span><span>IoC</span><span>?/span><span>Action</span><span>处理q程中可以访问到当前h</span><span>HttpServerRequest</span><span>对象?/span></p> <p><span>在例子中Q用的依赖注入机制是接口注入。就如其名称一P接口注入需要的是已l被实现了的接口。这个接口包含了相应属性的</span><span>setter</span><span>Qؓ</span><span>Action</span><span>提供倹{例子中使用?/span><span>ServletRequestAware</span><span>接口Q如下:</span></p> <p align="left"><span>public interface ServletRequestAware {<br /> <span>    </span>public void setServletRequest(HttpServletRequest request);<br /> }</span></p> <p><span>当承这个接口后Q原本简单的</span><span>Action</span><span>看v来有点复杂了Q但是这时可以获?/span><span>HttpServerRequest</span><span>对象来用了?/span></p> <p align="left"><span>public class IoCForStruts2 implements ServletRequestAware {<br /> <span>   </span>private HttpServletRequest request;<br /> <span>   </span>public void setServletRequest(HttpServletRequest request) {<br /> <span>        </span>this.request = request;<br /> <span>   </span>}<br /> <span>   </span>public String execute() throws Exception {<br /> <span>        </span>// </span><span>可以开始?/span><span>request</span><span>对象q行工作?/span><span><br /> <span>        </span>return Action.SUCCESS;<br /> <span>   </span>}<br /> }</span></p> <p><span>看v来现在这些属性是cȝ别的Qƈ不是U程安全的,会出现问题。其实在</span><span>Struts2</span><span>里ƈ没有问题Q因为每个请求过来的时候都会生一个新?/span><span>Action</span><span>对象实例Q它q没有和其他h׃n一个对象,所以不需要考虑U程安全问题?/span></p> <p> </p> <p><strong><span><span>四?span>       </span></span></span></strong><strong><span>拦截?/span></strong><strong></strong></p> <p> </p> <p><span>Interceptor</span><span>Q以下译为拦截器Q,?/span><span>AOP</span><span>Q?/span><span>Aspect-Oriented Programming</span><span>Q中用于在某个方法或字段被访问之前,q行拦截然后在之前或之后加入某些操作。拦截是</span><span>AOP</span><span>的一U实现策略?/span></p> <p><span>?/span><span>Webwork</span><span>的中文文档的解释?/span><span>—?/span><span>拦截器是动态拦?/span><span>Action</span><span>调用的对象。它提供了一U机制可以开发者定义在一?/span><span>action</span><span>执行的前后执行的代码Q也可以在一?/span><span>action</span><span>执行前阻止其执行。同时也提供了一U可以提?/span><span>action</span><span>中可重用的部分的方式?/span></p> <p><span>Struts1.x</span><span>的标准框架中不提供Q何Ş式的拦截器,虽一个名?/span><span>SAIF</span><span>的附加项目则实现了这L功能Q但它的适用的范围还很有限?/span></p> <p><span>拦截器是</span><span>Struts2</span><span>的一个强有力的工P有许多功能(</span><span>feature</span><span>Q都是构Z它之上,?/span><span><a href="http://www.aygfsteel.com/max/archive/2006/11/01/78536.html"><span><span>国际?/span></span></a></span><span>?/span><span><a href="http://www.aygfsteel.com/max/archive/2006/11/07/79602.html"><span><span>转换?/span></span></a></span><span>Q?/span><span><a href="http://www.aygfsteel.com/max/archive/2006/11/14/81106.html"><span><span>校验</span></span></a></span><span>{。谈到拦截器Q还有一个流行的?/span><span>—?/span><span>拦截器链Q?/span><span>Interceptor Chain</span><span>Q在</span><span>Struts2</span><span>中称为拦截器?/span><span>Interceptor Stack</span><span>Q。拦截器铑ְ是将拦截器按一定的序联结成一条链。在讉K被拦截的Ҏ或字D|Q拦截器链中的拦截器׃按其之前定义的顺序被调用?/span></p> <p><span>Struts 2</span><span>的拦截器实现相对比较单。当h到达</span><span>Struts2</span><span>?/span><span>ServletDispatcher</span><span>Ӟ</span><span>Struts 2</span><span>会查N|文Ӟq根据其配置实例化相对的拦截器对象,然后串成一个列表(</span><span>list</span><span>Q,最后一一地调用列表中的拦截器Q如?/span><span>1</span><span>所C?/span></p> <p> </p> <p align="center"><span>拦截器调用序列器</span></p> <p><span>Struts 2</span><span>已经提供丰富多样功能齐全的拦截器实现。读者可以到</span><span>struts2-all-<ST1:CHSDATE w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">2.0.6</ST1:CHSDATE>.jar</span><span>?/span><span>struts2-core-2.0.6.jar</span><span>包的</span><span>struts-default.xml</span><span>查看关于默认的拦截器与拦截器铄配置?/span></p> <p><span>作ؓ</span><span>“</span><span>框架Q?/span><span>framework</span><span>Q?/span><span>”</span><span>Q可扩展性是不可~少的,因ؓ世上没有放之四v而皆准的东西。虽Ӟ</span><span>Struts 2</span><span>为我们提供如此丰富的拦截器实玎ͼ但是qƈ不意x们失d定义拦截器的能力Q恰恰相反,?/span><span>Struts 2</span><span>自定义拦截器是相当容易的一件事?/span></p> <p> </p> <p><strong><span><span>五?span>       </span></span></span></strong><strong><span>Struts2</span></strong><strong><span>?/span></strong><strong><span>Struts1.x</span></strong><strong><span>的全面比?/span></strong><strong><span><br /> <br /> </span></strong></p> <p><span>Z?/span><span>Struts2</span><span>?/span><span>Strtus1.x</span><span>q行全面的比较,让读者了解这两种框架各自的优~点Q以便于在自q目中,Ҏ实际情况Q选择合适的框架Q对它们两者进行比较,ȝ了如下表分析比较?/span><span><br /> <br /> </span></p> <table cellspacing="0" cellpadding="0" width="600" border="0"> <tbody> <tr> <td width="87"> <p align="center"><strong><span>Ҏ?/span></strong><strong><span> </span></strong></p> </td> <td> <p align="center"><strong><span>Struts1.x</span></strong></p> </td> <td width="272"> <p align="center"><strong><span>Struts2 </span></strong></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>Action</span></strong><strong><span>c?/span></strong></p> </td> <td> <p align="left"><span>Struts1.x</span><span>要求</span><span>Action</span><span>c要扩展自一个抽象基cR?/span><span>Struts1.x</span><span>的一个共有的问题是面向抽象类~程而不是面向接口编E?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>?/span><span>Action</span><span>cdC一?/span><span>Action</span><span>接口Q连同其他接口一h实现可选择和自定义的服务?/span><span>Struts2</span><span>提供一个名?/span><span>ActionSupport</span><span>的基cL实现一般用的接口。当Ӟ</span><span>Action</span><span>接口不是必须的。Q何?/span><span>execute</span><span>Ҏ?/span><span>POJO</span><span>对象可以被当?/span><span>Struts 2</span><span>?/span><span>Action</span><span>对象来用?/span><span> </span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>U程模型</span></strong></p> </td> <td> <p align="left"><span>Struts1.x Action</span><span>cL单例c,因ؓ只有一个实例来控制所有的h。单例类{略造成了一定的限制Qƈ且给开发带来了额外的烦恹{?/span><span>Action</span><span>资源必须是线E安全或者同步的?/span></p> </td> <td width="272"> <p align="left"><span>Struts2 Action</span><span>对象为每一个请求都实例化对象,所以没有线E安全的问题。(实践中,</span><span>servlet</span><span>容器l每一个请求生许多丟弃的对象Qƈ且不会导致性能和垃圑֛攉题)?/span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>Servlet </span></strong><strong><span>依赖</span></strong><strong><span> </span></strong></p> </td> <td> <p align="left"><span>Struts1.x</span><span>?/span><span>Action</span><span>cM赖于</span><span>servlet API</span><span>Q当</span><span>Action</span><span>被调用时Q以</span><span>HttpServletRequest</span><span>?/span><span>HttpServletResponse</span><span>作ؓ参数传给</span><span>execute</span><span>Ҏ?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>?/span><span>Action</span><span>和容器无兟?/span><span>Servlet</span><span>上下文被表现为简单的</span><span>Maps</span><span>Q允?/span><span>Action</span><span>被独立的试?/span><span>Struts2</span><span>?/span><span>Action</span><span>可以讉K最初的h</span><span>(</span><span>如果需要的?/span><span>)</span><span>。但是,可能避免或排除其他元素直接讉K</span><span>HttpServletRequest</span><span>?/span><span>HttpServletResponse</span><span>?/span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>易测?/span></strong><strong><span> </span></strong></p> </td> <td> <p align="left"><span>试</span><span>Struts1.x</span><span>的主要问题是</span><span>execute</span><span>Ҏ暴露?/span><span>Servlet API</span><span>q得测试要依赖于容器)。第三方的扩展,?/span><span>Struts TestCase</span><span>Q提供了一?/span><span>Struts1</span><span>的模拟对象(来进行测试)?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>?/span><span>Action</span><span>可以通过初始化、设|属性、调用方法来试。依赖注入的支持也是试变得更简单?/span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>捕获输入</span></strong></p> </td> <td> <p align="left"><span>Struts1.x</span><span>使用</span><span>ActionForm</span><span>对象来捕莯入。象</span><span>Action</span><span>一P所有的</span><span>ActionForm</span><span>必须扩展基类。因为其他的</span><span>JavaBean</span><span>不能作ؓ</span><span>ActionForm</span><span>使用Q开发者经常创建多余的cL捕获输入?/span><span>DynaBeans</span><span>可以被用来作为替?/span><span>ActionForm</span><span>的类来创建。但是,开发者可能是在重新描q?/span><span>(</span><span>创徏</span><span>)</span><span>已经存在?/span><span>JavaBean</span><span>Q仍然会D有冗余的</span><span>javabean</span><span>Q?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>直接使用</span><span>Action</span><span>属性作入属性,消除了对W二个输入对象的需求。输入属性可能是有自?/span><span>(</span><span>?/span><span>)</span><span>属性的</span><span>rich</span><span>对象cd?/span><span>Action</span><span>属性能够通过</span><span>web</span><span>面上的</span><span>taglibs</span><span>讉K?/span><span>Struts2</span><span>也支?/span><span>ActionForm</span><span>模式?/span><span>rich</span><span>对象cdQ包括业务对象,能够用作输入</span><span>/</span><span>输出对象。这U?/span><span>ModelDriven </span><span>Ҏ简化了</span><span>taglib</span><span>?/span><span>POJO</span><span>输入对象的引用?/span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>表达式语a</span></strong><strong><span> </span></strong></p> </td> <td> <p align="left"><span>Struts1.x</span><span>整合</span><span>JSTL</span><span>Q所以它使用</span><span>JSTL</span><span>的表辑ּ语言。表辑ּ语言有基本的囑Ş对象UdQ但是对集合和烦引属性的支持很弱?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>使用</span><span>JSTL</span><span>Q但是也支持一个更强大和灵zȝ表达式语aQ-</span><span>"Object Graph Notation Language" (OGNL)</span><span>?/span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>值绑定到面</span></strong><strong><span> </span></strong></p> </td> <td> <p align="left"><span>Struts1.x</span><span>使用标准</span><span>JSP</span><span>机制来绑定对象到面上下文?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>使用“</span><span>ValueStack</span><span>”技术,?/span><span>taglib</span><span>能够讉KD不需要把你的面Q?/span><span>view</span><span>Q和对象l定h?/span><span>ValueStack</span><span>{略允许通过一pd名称相同但类型不同的属性重用页面(</span><span>view</span><span>Q?/span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>cd转换</span></strong><strong><span> </span></strong></p> </td> <td> <p align="left"><span>Struts1.x</span><span>?/span><span>ActionForm</span><span>属性经帔R?/span><span>String</span><span>?/span><span>Struts 1.x</span><span>使用</span><span>Commons-Beanutils</span><span>来进行类型{换。{换每一个类Q而不是ؓ每一个实例配|?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>使用</span><span>OGNL</span><span>q行cd转换。提供基本和常用对象的{换器?/span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>验证</span></strong><strong><span> </span></strong></p> </td> <td> <p align="left"><span>Struts1.x</span><span>支持?/span><span>ActionForm</span><span>?/span><span>validate</span><span>Ҏ中手动校验,或者通过</span><span>Commons Validator</span><span>的扩展来校验。同一个类可以有不同的校验内容Q但不能校验子对象?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>支持通过</span><span>validate</span><span>Ҏ?/span><span>XWork</span><span>校验框架来进行校验?/span><span>XWork</span><span>校验框架使用为属性类cd定义的校验和内容校验Q来支持</span><span>chain</span><span>校验子属?/span></p> </td> </tr> <tr> <td width="87"> <p align="center"><strong><span>Action</span></strong><strong><span>执行控制</span></strong><strong><span> </span></strong></p> </td> <td> <p align="left"><span>Struts1.x</span><span>支持每一个模块有单独?/span><span>Request Processors</span><span>Q生命周期)Q但是模块中的所?/span><span>Action</span><span>必须׃n相同的生命周期?/span></p> </td> <td width="272"> <p align="left"><span>Struts2</span><span>支持通过拦截器堆栈(</span><span>Interceptor Stacks</span><span>Qؓ每一?/span><span>Action</span><span>创徏不同的生命周期。堆栈能够根据需要和不同?/span><span>Action</span><span>一起用?/span></p> </td> </tr> </tbody> </table> <p> </p> <p> </p> <p><strong><span><span>六?span>       </span></span></span></strong><strong><span>l论</span></strong><strong><span><br /> <br /> </span></strong></p> <p align="left"><span>前面已经要介l了</span><span>Struts2</span><span>的v源,q详l对比了</span><span>Struts2</span><span>?/span><span>Struts1.x</span><span>的差异,读?/span><span>应该?/span><span>Struts2</span><span>的基有所了解?/span><span>—?/span><span>包括高层的框架概念和基础的请求流E,q理?/span><span>Struts1.x</span><span>?/span><span>Struts2</span><span>两者之间在</span><span>Action</span><span>斚w的差别,</span><span>Struts2</span><span>加强了对拦截器与</span><span>IoC</span><span>的支持,而在</span><span>Struts1.x</span><span>中,q些Ҏ是很难惌的?/span></p> <p align="left"><span>同时Q读者应该明白:</span><span>Struts2</span><span>?/span><span>WebWork</span><span>的升U,而不?/span><span>Struts 1.x</span><span>的升U。虽?/span><span>Struts 2</span><span>提供了与</span><span>Struts1.x</span><span>的兼容,但已l不?/span><span>Struts1.x</span><span>的升U。对于已?/span><span>Struts1.x</span><span>开发经验的开发者而言Q?/span><span>Struts1.x</span><span>的开发经验对?/span><span>Struts2</span><span>q没有太大的帮助Q相反,对于已经?/span><span>WebWork</span><span>开发经验的开发者而言Q?/span><span>WebWork</span><span>的开发经验对</span><span>Struts2</span><span>的开发将有很好的借鉴意义?/span></p> <img src ="http://www.aygfsteel.com/conans/aggbug/213756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/conans/" target="_blank">CONAN</a> 2008-07-09 19:12 <a href="http://www.aygfsteel.com/conans/articles/213756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的struts2目性能调优三步?http://www.aygfsteel.com/conans/articles/212190.htmlCONANCONANWed, 02 Jul 2008 12:10:00 GMThttp://www.aygfsteel.com/conans/articles/212190.html 一Q根据struts2官方的性能调优说明q行了一些参数的修改?br /> http://struts.apache.org/2.x/docs/performance-tuning.html
http://cwiki.apache.org/WW/performance-tuning.html

Turn off logging and devMode.(关闭logging和Devmode)
q个当然没问题,但是全部关闭logging不现实,我只是关闭了struts2相关package的logging

Do not use interceptors you do not need.
把struts.xml中不需要的interceptorl统删除

Use the correct HTTP headers (Cache-Control & Expires).
不确定应该如何修?br />
Copy the static content from the Struts 2 jar when using the Ajax theme (Dojo) or the Calendar tag.
关于q点Q后面会提到

Create a freemarker.properties file in your WEB-INF/classes directory.
照做

Create the freemarker.properties file and add the following setting (or whatever value you deem fitting):
template_update_delay=60000
照做

Enable Freemarker template caching
As of Struts 2.0.10, setting the property struts.freemarker.templatesCache to true will enable the Struts internal caching of Freemarker templates. This property is set to false by default.
照做

q行上述修改后,发现面打开的速度q没有明昄提高.

二,此时我已l基本锁定网|开速度慢的原因与ajax(或者说是dojo)有关。因为dojo的js库大概有450K左右Q先试使用gzip压羃javascriptQ减传输量Q看能否加快面的加载速度
在Tomcat的server.xml的connector中添加如下配|,Ȁzgzip功能
 compression="on"
 compressionMinSize="2048"
 noCompressionUserAgents="gozilla, traviata"
 compressableMimeType="text/html,text/xml,text/javascript,application/x-javascript,application/javascript"
q行上述修改后,发现面打开的速度q是没有明显的提?

三,l过上述两个实验Q觉得应该是struts2所闭的dojo的性能问题了。于是引入JQuery.
JQuery的js文g最是55K, gzip后应该更,面的响应速度明显改善Q一个数量以上的提高)Q主要原因在于与服务器交互的处理上极大地提升了效率。而且面处理代码更加z明了?br />
最后,我删除了所有的<s:head theme="ajax"/>?<s:head/>(如果面中加?lt;s:head />Q那么在Struts2生成的html中后包含dojo.js)Q用JQuery来完成所有的Ajax和javascript功能?br />

CONAN 2008-07-02 20:10 发表评论
]]>
Struts2(Webwork2)一些实战开发技?/title><link>http://www.aygfsteel.com/conans/articles/210934.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Thu, 26 Jun 2008 11:55:00 GMT</pubDate><guid>http://www.aygfsteel.com/conans/articles/210934.html</guid><description><![CDATA[<span style="font-size: medium; color: #ff6600">一Q?</span><span style="font-size: medium; color: #ff6600; font-family: 宋体">使用反射动态取?/span> <span style="font-size: medium; color: #ff6600">Pojo </span><span style="font-size: medium; color: #ff6600; font-family: 宋体">的属?/span> <p><span style="font-family: 宋体">q一招在一些特D的场合下非常管用.比如_用户在第一个页面,选择了某个实体其中要昄出来的几个属性,那个q个时候用反射是非怸错的选择Q少了大?/span> if <span style="font-family: 宋体">语句Q?/span> </p> <div> <div> <div>Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li>package com.leo.util;   </li> <li>  </li> <li>import java.lang.reflect.Method;   </span></li> <li>  </li> <li>public class HelloWorldBean {   </span></li> <li>  </li> <li>    private String word;   </span></li> <li>  </li> <li>    private String name;   </span></li> <li>  </li> <li>    public String getName() {   </span></li> <li>        return name;   </span></li> <li>    }   </li> <li>  </li> <li>    public void setName(String name) {   </span></li> <li>        this.name = name;   </span></li> <li>    }   </li> <li>  </li> <li>    public String getWord() {   </span></li> <li>        return word;   </span></li> <li>    }   </li> <li>  </li> <li>    public void setWord(String word) {   </span></li> <li>        this.word = word;   </span></li> <li>    }   </li> <li>  </li> <li>    public HelloWorldBean() {   </span></li> <li>        name = "superleo";   </span></li> <li>        word = "Hello World!!!";   </span></li> <li>    }   </li> <li>  </li> <li>    public String getProperty(String name) throws Exception {   </span></li> <li>        if (name != null && !name.equals("")) {   </span></li> <li>            Character ch = name.charAt(0);   </span></li> <li>            name = Character.toUpperCase(ch) + name.substring(1, name.length());   </span></li> <li>            Class cls = Class.forName("com.leo.util.HelloWorldBean");   </span></li> <li>            Method meth = cls.getMethod("get" + name, null);   </span></li> <li>            Object retobj = meth.invoke(this, null);   </span></li> <li>            return (String) retobj;   </span></li> <li>  </li> <li>        }   </li> <li>        throw new RuntimeException();   </span></li> <li>    }   </li> <li>  </li> <li>    public static void main(String[] args) throws Exception {   </span></li> <li>        HelloWorldBean bean = new HelloWorldBean();   </span></li> <li>        bean.setName("superleo");   </span></li> <li>        bean.setWord("name");   </span></li> <li>        System.out.println(bean.getProperty("name"));   </span></li> <li>        System.out.println(bean.getProperty("word"));   </span></li> <li>    }   </li> <li>  </li> <li>}  </li> </ol> </div> <pre style="display: none" name="code">package com.leo.util; import java.lang.reflect.Method; public class HelloWorldBean { private String word; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWord() { return word; } public void setWord(String word) { this.word = word; } public HelloWorldBean() { name = "superleo"; word = "Hello World!!!"; } public String getProperty(String name) throws Exception { if (name != null && !name.equals("")) { Character ch = name.charAt(0); name = Character.toUpperCase(ch) + name.substring(1, name.length()); Class cls = Class.forName("com.leo.util.HelloWorldBean"); Method meth = cls.getMethod("get" + name, null); Object retobj = meth.invoke(this, null); return (String) retobj; } throw new RuntimeException(); } public static void main(String[] args) throws Exception { HelloWorldBean bean = new HelloWorldBean(); bean.setName("superleo"); bean.setWord("name"); System.out.println(bean.getProperty("name")); System.out.println(bean.getProperty("word")); } } </pre> <p>OK <span style="font-family: 宋体">Q假设我们在</span> HelloAction <span style="font-family: 宋体">使用了这?/span> HelloWorldBean <span style="font-family: 宋体">Qƈ且运行后Q蟩转到相应面Q你可以q样d</span> HelloWorldBean <span style="font-family: 宋体">?/span> word <span style="font-family: 宋体">?/span> name <span style="font-family: 宋体">属性了Q?/span> </p> <div> <div> <div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  </li> <li><%@ taglib prefix="s" uri="/struts-tags"%>  </span></li> <li><html>  </span></li> <li>    <body>  </span></li> <li>        <h3>  </span></li> <li>            正常ҎQ?lt;s:property value="helloWorld.name" /> <br />  </span></li> <li>            <s:property value="helloWorld.word" /> <br />  </span></li> <li>            反射ҎQ?lt;s:property value="helloWorld.getProperty('name')" /> <br />  </span></li> <li>            <s:property value="helloWorld.getProperty('word')" />  </span></li> <li>        </h3>  </span></li> <li>    </body>  </span></li> <li></html>  </span></li> </ol> </div> <pre style="display: none" name="code"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <html> <body> <h3> 正常ҎQ?lt;s:property value="helloWorld.name" /> <br /> <s:property value="helloWorld.word" /> <br /> 反射ҎQ?lt;s:property value="helloWorld.getProperty('name')" /> <br /> <s:property value="helloWorld.getProperty('word')" /> </h3> </body> </html> </pre> <p><span style="font-family: 宋体">对于公共属性,q可以将此方法移到父cR?/span> </p> <p style="margin-left: 21pt; text-indent: -21pt"><span style="font-size: medium; color: #ff6600; font-family: 宋体">?/span> <span style="font-size: medium; color: #ff6600">iterator </span><span style="font-size: medium; color: #ff6600; font-family: 宋体">q代</span> <span style="font-size: medium; color: #ff6600">Map </span><span style="font-size: medium; color: #ff6600; font-family: 宋体">对象</span> </p> <p><span style="font-family: 宋体">q对昄</span> Hibernate 多表q接的查询结果非常管用?</p> <p><span style="font-family: 宋体">以前Q在使用</span> Hibernate <span style="font-family: 宋体">的时候,因ؓ涉及到多个表查询是很普遍的,每个表取一些字D,xC在面Q比较好的办法是新徏一?/span> VO <span style="font-family: 宋体">对象Q专门用来显C查询的l果Q但~点是Q如果这L查询很多Q?/span> VO <span style="font-family: 宋体">cM来多Q如果不断的往一?/span> VO <span style="font-family: 宋体">增加字段的话Q那么这?/span> VO <span style="font-family: 宋体">也越来越大,构造函C特别夸张Q,׃来看一个例子:</span> </p> <div> <div> <div>Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li>List list = session.createQuery("select new MyVO(a.name, b.name, c.id) from .....").list();  </li> </ol> </div> <p><span style="font-family: 宋体">q样q回?/span> List <span style="font-family: 宋体">直接可以在面上用</span> iterator <span style="font-family: 宋体">标签q代了,但假如现在要?/span> 10 <span style="font-family: 宋体">呢?不仅</span> HQL <span style="font-family: 宋体">语句要修改,而且</span> MyVO <span style="font-family: 宋体">也要修改Q下面是一U更好的做法Q?/span> </p> <div> <div> <div>Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li>List list = session.createQuery("select new Map(a.name as fristName, b.name as secondName, c.id as id from .....").list();  </li> </ol> </div> <p><span style="font-family: 宋体">q里改用</span> Map <span style="font-family: 宋体">了,<span style="color: red">注意每个属性都?#8220;</span> </span><span style="color: red">as</span> <span style="color: red; font-family: 宋体">”重新启了一个别名,q个非常重要Q否则在面昄Ӟ很费Ԍ</span> </p> <p><span style="font-family: 宋体">现在来看面调用代码Q?/span> </p> <div> <div> <div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li><s:iterator value="list" id="maps">  </li> <li>      <tr class="row1">  </span></li> <li>      <input type="checkbox" name="ids" value="<s:property value="#maps.get('id')" />" />  </span></li> <li>      <td align="center"><s:property value="#maps.get('fristName')" /></td>  </span></li> <li>      <td align="center"><s:property value="#maps.get('secondName')" /></td>  </span></li> <li>    </tr>  </span></li> <li>    </s:iterator>  </span></li> </ol> </div> <pre style="display: none" name="code"><s:iterator value="list" id="maps"> <tr class="row1"> <input type="checkbox" name="ids" value="<s:property value="#maps.get('id')" />" /> <td align="center"><s:property value="#maps.get('fristName')" /></td> <td align="center"><s:property value="#maps.get('secondName')" /></td> </tr> </s:iterator> </pre>   <p><span style="font-family: 宋体">注意上面的页面中</span> Map <span style="font-family: 宋体">的取值就是当?/span> hql <span style="font-family: 宋体">语句?#8220;</span> as <span style="font-family: 宋体">”后的别名Q?/span> </p> <p><span style="font-family: 宋体">虽然相对于以往?/span> JSTL <span style="font-family: 宋体">来说Q要写的标签代码更多了,但强大的</span> OGNL <span style="font-family: 宋体">表达式也让你在视囑ֱ拥有更强大的灉|性与扩展性.</span> </p> <p><span style="font-family: 宋体">序无关Q如果你使用?/span> <span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'">select new List(...)</span> <span style="font-family: 宋体">也能辑ֈcM效果Q但因ؓ</span> List <span style="font-family: 宋体">是有序的Q所以在面昄非常不灵z,不推荐用.</span> </p> <p style="margin-left: 21pt; text-indent: -21pt"><span style="font-size: medium; color: #ff6600; font-family: 宋体">?/span> <span style="font-size: medium; color: #ff6600">if </span><span style="font-size: medium; color: #ff6600; font-family: 宋体">标签判断汉字问题</span> </p> <p><span style="font-family: 宋体">q个问题具体原因不明Q先看下面一D代码:</span> </p> <div> <div> <div>Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li><s:if test="user.name == 'E序'">   </li> <li>...  </li> </ol> </div> <pre style="display: none" name="code"><s:if test="user.name == 'E序'"> ... </pre> <p><span style="font-family: 宋体">q样q</span> user.name <span style="font-family: 宋体">{于“E序”也是无法通过的,需要修Ҏ以下代码Q?/span> </p> <div> <div> <div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li><s:if test="user.name == "'E序"'">  </li> <li>...  </li> </ol> </div> <pre style="display: none" name="code"><s:if test="user.name == "'E序"'"> ... </pre> <p><span style="font-family: 宋体">如果“E序”是你pȝ的一个常量,更推荐的作法是:</span> </p> <div> <div> <div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li><s:if test="user.name == @com.leo.util.Constants@TYPE ">  </li> <li>...  </li> </ol> </div> <pre style="display: none" name="code"><s:if test="user.name == @com.leo.util.Constants@TYPE "> ... </pre>   <p><span style="font-family: 宋体">我不知道原因是不是因为版本问题?希望有知道的Q回复一下.</span> </p> <p style="margin-left: 21pt; text-indent: -21pt"><span style="font-size: medium; color: #ff6600; font-family: 宋体">?/span> <span style="font-size: medium; color: #ff6600">iterator </span><span style="font-size: medium; color: #ff6600; font-family: 宋体">双重循环</span> </p> <p><span style="font-family: 宋体">q个也很常用Q相信很多h都轻车熟路,那我们来回顾一下。假?/span> lists <span style="font-family: 宋体">装的都是</span> Group <span style="font-family: 宋体">对象Q?/span> Group <span style="font-family: 宋体">持有一?/span> List<User> <span style="font-family: 宋体">那个我们接下来可以:</span> </p> <div> <div> <div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" ><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div> </div> <ol> <li><ww:iterator value="lists" id="top">  </li> <li><ww:iterator value="users" id="sub">  </span></li> <li>l名Q?lt;s:property value="#top.name" />Q成员名Q?lt;s:property value="#sub.name" />  </span></li> <li></ww:iterator>  </span></li> <li>  应该lLQ?lt;s:property value="users.size" />  </span></li> <li></ww:iterator>  </span></li> </ol> </div> <pre style="display: none" name="code"><ww:iterator value="lists" id="top"> <ww:iterator value="users" id="sub"> l名Q?lt;s:property value="#top.name" />Q成员名Q?lt;s:property value="#sub.name" /> </ww:iterator> 应该lLQ?lt;s:property value="users.size" /> </ww:iterator> </pre> <p><span style="font-family: 宋体">上面的写法有很多U,但效果都是一LQ有兴趣可以多看?/span> OGNL <span style="font-family: 宋体">?/span> </p> <p>q有一些没有及时整理好Q下ơ统一再给大家分n一下.</p> <img src ="http://www.aygfsteel.com/conans/aggbug/210934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/conans/" target="_blank">CONAN</a> 2008-06-26 19:55 <a href="http://www.aygfsteel.com/conans/articles/210934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2利用stream直接输出Excel http://www.aygfsteel.com/conans/articles/210375.htmlCONANCONANTue, 24 Jun 2008 11:41:00 GMThttp://www.aygfsteel.com/conans/articles/210375.html在利用网展C查询结果,l常会遇到要求导出成Excel的需求。采用这U方法可以定制输出的格式和内容(q不支持合ƈ单元格和公式Q,生成真正的Excel格式Q不是csvQ的Excel?br /> 一、struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
  
<struts>

    <constant name="struts.i18n.encoding" value="UTF-8"/>

    <package name="demo" extends="struts-default">
        <action name="excel" method="execute" class="demo.ExcelAction">
                <result name="excel" type="stream">
                    <param name="contentType">application/vnd.ms-excel</param>    <!-- 注意q里的ContentType -->
                    <param name="inputName">excelStream</param>                   <!-- q里需要和Action里的变量名一?-->
                    <param name="contentDisposition">filename="standard.xls"</param>
                    <param name="bufferSize">1024</param>
                </result>
        </action>
    </package>
</struts>

二、Struts2?Action

package demo;
public class ExcelAction {
    private InputStream excelStream; // 需要生成getter和setter

    public String execute() throws Exception {
        StringBuffer excelBuf = new StringBuffer();
        excelBuf.append("BookName").append("\t").append("Year").append("\t").append("author").append("\n");
        excelBuf.append("Thinking in Java").append("\t").append("2001").append("\t").append("Eckel").append("\n");
        excelBuf.append("Spring in action").append("\t").append("2005").append("\t").append("Rod").append("\n");
        String excelString = excelBuf.toString();
        logger.debug("result excel String: " + excelString);
        excelStream = new ByteArrayInputStream(excelString.getBytes(), 0, excelString.length());
        return "excel";
    }

    // getter and setter
    ...
}

三、Jsp面

<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <s:head />
 </head>

 <body>

    <s:form action="" method="post">
       <s:submit key="button.submit"/>
    </s:form>
 </body>
</html>



CONAN 2008-06-24 19:41 发表评论
]]>
再谈Struts2囄按钮标签的用:囄根\径无法取得,使用传统Ҏ http://www.aygfsteel.com/conans/articles/209893.htmlCONANCONANSun, 22 Jun 2008 11:07:00 GMThttp://www.aygfsteel.com/conans/articles/209893.html                    <s:submit type="image" value="user_doDelete.action" label="删除指定用户"
                     src="myroot/images/btn/btn_delete.jpg" cssClass="button_image"
                            onclick="return CheckSelectForDelete();" action="user" method="doDelete"/></td>
  在这里面的src有个问题是必须带着目的rootQ如上例中的myrootQ一旦项目的讉K路径变了Q就ȝ了,昄不出囄来了Q传l的Ҏ是加<%=request.getContextPath()%>,但是在Struts2标签中不能这么引用?br /> ?.0.11的时候还可以?br />     ${pageContext.request.contextPath},但是必须使用theme=ajaxQ我q不想用Q?br /> ?.1.2的时候ajax从标准标{ֺ中分出去了,想用也不行了?br /> 现在只能不用Submit标签了,但是q想用它的一些功能,主要是那个action,method了,通过分析生成的代码ȝ新的Ҏ如下Q?br />                     <input type="image" alt="删除指定用户"
                           src="<%=request.getContextPath() %>/images/btn/btn_del.gif"
                           id="doDelete" name="action:user!doDelete" 
                           class="button_image" onclick="return CheckSelectForDelete();"/>
无他Q就是把标签中的action和method合ƈhQ加到name中去了其它的照旧?

CONAN 2008-06-22 19:07 发表评论
]]>
Spring和struts2的整?/title><link>http://www.aygfsteel.com/conans/articles/209888.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Sun, 22 Jun 2008 11:00:00 GMT</pubDate><guid>http://www.aygfsteel.com/conans/articles/209888.html</guid><description><![CDATA[<table style="table-layout: fixed"> <tbody> <tr> <td> <div id="wmqeeuq" class="cnt"> <div id="wmqeeuq" class="cnt">在Struts2中整合Spring的IoC支持是一件十分简单的事情。让我们一步一步来实现Q?br /> 1Q复制struts2-spring-plugin-x-x-x.jar和相应的spring.jar?WEB-INF/lib目录下?br /> 2Q在struts.properties中设|struts.objectFactory属性?br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; border-bottom: #3c78b5 1px dashed; background-color: #f0f0f0; text-align: center"><strong>struts.properties</strong></div> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre>struts.objectFactory = spring </pre> </div> </div> 或者是在XML文g中进行常量配|?br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; border-bottom: #3c78b5 1px dashed; background-color: #f0f0f0; text-align: center"><strong>struts.xml</strong></div> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre><struts>        <constant name="struts.objectFactory" value="spring" /> </struts> </pre> </div> </div> 3Q配|Spring监听?br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; border-bottom: #3c78b5 1px dashed; background-color: #f0f0f0; text-align: center"><strong>web.xml</strong></div> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre><listener>        <listener-class>org.springframework.web.context.ContextLoaderListener<span id="wmqeeuq" class="code-tag"></listener-class> </listener> </span> </pre> </div> </div> 通过Spring配置来注册对?br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; border-bottom: #3c78b5 1px dashed; background-color: #f0f0f0; text-align: center"><strong>applicationContext.xml</strong></div> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre><?xml version=<span id="wmqeeuq" class="code-quote">"1.0"</span> encoding="UTF-8"?> <!DOCTYPE beans PUBLIC        "-//SPRING//DTD BEAN//EN"        "http://www.springframework.org/dtd/spring-beans.dtd"> <beans default-autowire="byName">        <bean id="personManager" class="com.acme.PersonManager"/> </beans> </pre> </div> </div> 当然你也可以拥有更多的Spring配置文g。在web.xml中进行下列设|,从而Spring的ApplicationContext通过匚w所l定模式的文件来初始化对?br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre><!-- 用来定位Spring XML文g的上下文配置 --> <context-param>        <param-name>contextConfigLocation<span id="wmqeeuq" class="code-tag"></param-name>        <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value> </context-param> </span> </pre> </div> </div> 4Q修改你的Struts配置文g<br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; border-bottom: #3c78b5 1px dashed; background-color: #f0f0f0; text-align: center"><strong>struts.xml</strong></div> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre><!DOCTYPE struts PUBLIC        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"        "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts>        <include file="struts-default.xml"/>        <package name="default" extends="struts-default">            <action name="foo" class="com.acme.Foo">                <result>foo.ftl</result>            </action>        </package>        <package name="secure" namespace="/secure" extends="default">            <action name="bar" class="bar">                <result>bar.ftl</result>            </action>        </package> </struts> </pre> </div> </div> 默认情况下,Spring从下面的文g中寻找ؓbar所做的配置<br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; border-bottom: #3c78b5 1px dashed; background-color: #f0f0f0; text-align: center"><strong>applicationConext.xml</strong></div> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre><?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC        "-//SPRING//DTD BEAN//EN"        "http://www.springframework.org/dtd/spring-beans.dtd"> <beans default-autowire="byName">        <bean id="bar" class="com.my.BarClass" singleton="false"/>        ... </beans> </pre> </div> </div> 5Q好了,现在你的Struts2和Springp正常的一起工作了。有几个配置技术点需要详l说明下Q装配模式。你可以通过讄修改struts.properties中下列属性的值来改变装配模式?br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre class="code-java">struts.objectFactory.spring.autoWire = type </pre> </div> </div> 该参数可供选择的设|值有<br /> <table style="margin: 5px; border-collapse: collapse"> <tbody> <tr> <th style="border-right: #ccc 1px solid; padding-right: 4px; border-top: #ccc 1px solid; padding-left: 4px; padding-bottom: 3px; border-left: #ccc 1px solid; padding-top: 3px; border-bottom: #ccc 1px solid; background-color: #f0f0f0; text-align: center">name</th> <td style="border-right: #ccc 1px solid; padding-right: 4px; border-top: #ccc 1px solid; padding-left: 4px; padding-bottom: 3px; border-left: #ccc 1px solid; padding-top: 3px; border-bottom: #ccc 1px solid">按照你的action的属性的名字和Spring里的bean的名字匹配,如果匚wp动装配。这?strong>~省?/strong></td> </tr> <tr> <th style="border-right: #ccc 1px solid; padding-right: 4px; border-top: #ccc 1px solid; padding-left: 4px; padding-bottom: 3px; border-left: #ccc 1px solid; padding-top: 3px; border-bottom: #ccc 1px solid; background-color: #f0f0f0; text-align: center">type</th> <td style="border-right: #ccc 1px solid; padding-right: 4px; border-top: #ccc 1px solid; padding-left: 4px; padding-bottom: 3px; border-left: #ccc 1px solid; padding-top: 3px; border-bottom: #ccc 1px solid">按照你的action的属性的cdQ在Spring注册的bean中查找,如果相同p动装配。这需要你在Spring中仅注册了一个此cd的bean</td> </tr> <tr> <th style="border-right: #ccc 1px solid; padding-right: 4px; border-top: #ccc 1px solid; padding-left: 4px; padding-bottom: 3px; border-left: #ccc 1px solid; padding-top: 3px; border-bottom: #ccc 1px solid; background-color: #f0f0f0; text-align: center">auto</th> <td style="border-right: #ccc 1px solid; padding-right: 4px; border-top: #ccc 1px solid; padding-left: 4px; padding-bottom: 3px; border-left: #ccc 1px solid; padding-top: 3px; border-bottom: #ccc 1px solid">Spring会试图自动监来扑ֈ最好的Ҏ自动装配你的action</td> </tr> <tr> <th style="border-right: #ccc 1px solid; padding-right: 4px; border-top: #ccc 1px solid; padding-left: 4px; padding-bottom: 3px; border-left: #ccc 1px solid; padding-top: 3px; border-bottom: #ccc 1px solid; background-color: #f0f0f0; text-align: center">constructor</th> <td style="border-right: #ccc 1px solid; padding-right: 4px; border-top: #ccc 1px solid; padding-left: 4px; padding-bottom: 3px; border-left: #ccc 1px solid; padding-top: 3px; border-bottom: #ccc 1px solid">Spring会自动装配bean的构造函数的参数</td> </tr> </tbody> </table> 是否使用cȝ存。你可以通过讄修改struts.properties中下列属性的值来改变是否使用Spring自n的类~存机制。可以设定的gؓtrue或falseQ默认ؓtrue?br /> <div style="border-right: #3c78b5 1px dashed; border-top: #3c78b5 1px dashed; margin: 10px; border-left: #3c78b5 1px dashed; line-height: 13px; border-bottom: #3c78b5 1px dashed"> <div style="padding-right: 3px; padding-left: 3px; padding-bottom: 3px; padding-top: 3px; background-color: #f0f0f0; text-align: left"> <pre>struts.objectFactory.spring.useClassCache = false </pre> </div> </div> </div> </div> </td> </tr> </tbody> </table> <img src ="http://www.aygfsteel.com/conans/aggbug/209888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/conans/" target="_blank">CONAN</a> 2008-06-22 19:00 <a href="http://www.aygfsteel.com/conans/articles/209888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2中的单Form多图片提交按?Submit)的?http://www.aygfsteel.com/conans/articles/209883.htmlCONANCONANSun, 22 Jun 2008 10:55:00 GMThttp://www.aygfsteel.com/conans/articles/209883.html在Struts2里面一个Form中如果有多个提交按钮Q比如添加,更新Q保存等Q?br /> q些按钮使用一个ActionQ调用不同的ҎQƈ且在调用前要执行一个JavaScript的检查?br /> 怎么用这个提交按钮?
l过ȝ如下Q?br /> 先在form标签头指定Action的命名空_
<s:form namespace="/system/usermanager" >
然后如下调用Q?br />                     <s:submit type="image" id="FIND" value="FIND" label="按指定条件检索用户信?
                              src="/issframe/images/btn/btn_find.jpg" cssClass="button_image"
                              onclick="return CheckInputForRequired();" action="user" method="doSearch"/>
上面是一个图片提交按钮的CZQ因Z般在目中都是用图片按?)
在onclick中执行javascriptQ记得不要漏掉return?br /> action是你要调用的Action在Struts2的配|文件中定义的那个name
例如Q?lt;action name="user_*" class="com.system.action.ManagerUserAction" method="{1}">

注意不包括通配W?"_"或?!"{??br /> mothed是ActioncM定义的对应的Ҏ了?

CONAN 2008-06-22 18:55 发表评论
]]>
strust2实践ȝhttp://www.aygfsteel.com/conans/articles/209884.htmlCONANCONANSun, 22 Jun 2008 10:55:00 GMThttp://www.aygfsteel.com/conans/articles/209884.html
2Q在面中实现自动增加的序号用iterator的statuts的index属?egQ?

<s:iterator value="#request.inOutAccountList" id="data" status="listStat">

<s:property value="#listStat.index+1"/>

</s:iterator>

3:在actioncM取得request和session对象的方?

Map session = ActionContext.getContext().getSession();
HttpServletRequest request = ServletActionContext.getRequest ();

讄它们的值的Ҏ

session.put("operation", "add");
request.setAttribute("name", name);

面中取得它们的|

<s:property value="#session.operation"/>
<s:property value="#request.name"/>

4:面中奇偶行样式不一L控制ҎQ?

<tr class="<s:if test='#listStat.odd == true '>tableStyle-tr1</s:if><s:else>tableStyle-tr2</s:else>" >

5:单选框和复选框的用方?

1):可以讄默认选中|注意list的值的讄Q通过q种方式使key和value不一Pq种Ҏ比较常用(checkboxlist or radio)

<s:radio name="uncarInsPolicy.policyStateCode"
list="#{'5':'通过' , '2':'不通过'}"
listKey="key"
listValue="value"
value='5'
/>

2):q里的key和value的值是一L(checkboxlist or radio)

<s:checkboxlist
list="{'Red', 'Blue', 'Green'}"
name="favoriteColor"/>

6:struts2 中的标签会生成类似由<tr><td></td></tr>构成的字Ԍ具体什么标{成什么,可以查看生成后的面的源代码Q如果不限制q些多余代码的生成,面变得无法控Ӟ所以一般我们是不希望它生成多余的代码的Q具体的讄Ҏ如果Q在struts.xml中统一配置
<constant name="struts.ui.theme" value="simple"/>加上该句卛_
也可以通过在页面中tag的theme属性设?simple"取消光认的表格布局
不过最好是Q自定义一个themeQƈ其设ؓ默认应用到整个站点,如此一来就可以得到l一的站炚w?

7Qjsp面中格式化日期的方?

<s:date name="unCarInsModificationInfo.createTime" format="yyyy-MM-dd" nice="false"/>q样可以将日期格式化ؓyyyyQMMQdd的Ş?

8Q默认情况下Q当haction发生ӞStrutsq行ӞRuntimeQ根据struts.xml里的Action映射?Mapping)Q实例化action对应的类Qƈ调用其executeҎ。当Ӟ我们可以通过以下两种Ҏ改变q种默认调用

1Q在classes/sturts.xml中新建ActionQƈ指明其调用的Ҏ
比如惌用actioncM?

public String aliasAction() {
message ="自定义Action调用Ҏ";
return SUCCESS;
}
则在classes/sturts.xml中加入下面代码:
<action name="AliasHelloWorld" class="tutorial.HelloWorld" method="aliasAction">
<result>/HelloWorld.jsp</result>
</action>
既可用action名调用该Ҏ?

2Q(比较常用Q?

讉KActionӞ在Action名后加上“!xxx”Qxxx为方法名Q?

9QStruts 2.0有两个配|文Ӟstruts.xml和struts.properties都是攑֜WEB-INF/classes/下?
struts.xml用于应用E序相关的配|?
struts.properties用于Struts 2.0的运行时QRuntimeQ的配置

10:在actioncM取得web下某一文g夹物理\径(l对路径Q的Ҏ
filePath = ServletActionContext.getServletContext().getRealPath("/upLoadFiles")

11Q要惌回的面不是一个直接JSP面而是要先通过q回action中的Ҏd相应的数据再q回到jsp面Q有两种Ҏ

1Q在struts.xml中这么设|?

<result name="list" type="redirect-action">sysmanage/UserBaseInfoAction!findUserBaseInfo.action</result>

2Q在action中返回时直接调用q个Ҏ卛_

return findListQ)Q?

12Q设|checkboxlist中默认值的Ҏ

<s:checkboxlist name="skills1"
="Skills 1"
list="{ 'Java', '.Net', 'RoR', 'PHP' }"
value="{ 'Java', '.Net' }" />
<s:checkboxlist name="skills2"
label="Skills 2"
list="#{ 1:'Java', 2: '.Net', 3: 'RoR', 4: 'PHP' }"
listKey="key"
listValue="value"
value="{ 1, 2, 3 }"/>

13Q二Uq下拉框

<s:set name="foobar"
value="#{'Java': {'Spring', 'Hibernate', 'Struts 2'}, '.Net': {'Linq', ' ASP.NET 2.0'}, 'Database': {'Oracle', 'SQL Server', 'DB2', 'MySQL'}}" />
<s:doubleselect list="#foobar.keySet()"
doubleName="technology"
doubleList="#foobar[top]"
label="Technology" />

CONAN 2008-06-22 18:55 发表评论
]]>
վ֩ģ壺 | ׯ| ʶ| | ˫Ѽɽ| ˮ| | »| ԰| Դ| ̨| ǭ| ͷ| | | | ½| | | ֻ| 㶫ʡ| ɽʡ| | | | Т| | ͳ| ī| | °Ͷ| | ¸| Դ| | ǰ| | Դ| | ֺ| ̩|