﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-CONAN ZONE-文章分类-Struts2/Webwork</title><link>http://www.blogjava.net/conans/category/32511.html</link><description>你越挣扎我就越兴奋</description><language>zh-cn</language><lastBuildDate>Sun, 09 Aug 2009 23:11:08 GMT</lastBuildDate><pubDate>Sun, 09 Aug 2009 23:11:08 GMT</pubDate><ttl>60</ttl><item><title>Struts2采用convention-plugin实现零配置</title><link>http://www.blogjava.net/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.blogjava.net/conans/articles/289508.html</guid><description><![CDATA[<p>最近开始关注struts2的新特性，从这个版本开始，Struts开始使用convention-plugin代替codebehind-plugin来实现struts的零配置。<br />
配置文件精简了，的确是简便了开发过程，但是，我们熟悉的配置突然disappear了，真是一下很不适应。跟着潮流走吧，看看该怎样来搞定convention-plugin。<br />
使用Convention插件，你需要将其JAR文件放到你应用的WEB-INF/lib目录中，你也可以在你Maven项目的POM文件中添加下面包依赖</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-xml">
    <li><span><span class="tag">&lt;</span><span class="tag-name">dependency</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">groupId</span><span class="tag">&gt;</span><span>org.apache.struts</span><span class="tag">&lt;/</span><span class="tag-name">groupId</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">artifactId</span><span class="tag">&gt;</span><span>struts2-convention-plugin</span><span class="tag">&lt;/</span><span class="tag-name">artifactId</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">version</span><span class="tag">&gt;</span><span>2.1.6</span><span class="tag">&lt;/</span><span class="tag-name">version</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li><span class="tag">&lt;/</span><span class="tag-name">dependency</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="xml" style="display: none;" name="code">&lt;dependency&gt;
&lt;groupId&gt;org.apache.struts&lt;/groupId&gt;
&lt;artifactId&gt;struts2-convention-plugin&lt;/artifactId&gt;
&lt;version&gt;2.1.6&lt;/version&gt;
&lt;/dependency&gt;</pre>
<p><br />
<br />
零配置并不是没有配置，而是通过约定大于配置的方式，大量通过约定来调度页面的跳转而使得配置大大减少。所以，首先应该了解下convention-plugin的约定：<br />
1.
默认所有的结果页面都存储在WEB-INF/content下，你可以通过设置struts.convention.result.path这个属性的值来改变到其他路径。如：</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-xml">
    <li><span><span class="tag">&lt;</span><span class="tag-name">constant</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"struts.convention.result.path"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"/WEB-INF/page"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none;" name="code">&lt;constant name="struts.convention.result.path" value="/WEB-INF/page" /&gt;</pre>
<p><br />
则将路径配置到了WEB-INF/page 下。<br />
2.
默认包路径包含action,actions,struts,struts2的所有包都会被struts作为含有Action类的路径来搜索。你可以通过设置struts.convention.package.locators属性来修改这个配置。如：</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-xml">
    <li><span><span class="tag">&lt;</span><span class="tag-name">constant</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"struts.convention.package.locators"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"web,action"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none;" name="code">&lt;constant name="struts.convention.package.locators" value="web,action" /&gt;</pre>
<p><br />
则定义了在项目中，包路径包含web和action的将被视为Action存在的路径来进行搜索。<br />
Com.ustb.web.*/com.ustb.action.*都将被视为含有Action的包路径而被搜索。<br />
3.
接着，Convention从前一步找到的package以及其子package中寻找 com.opensymphony.xwork2.Action
的实现以及以Action结尾的类：</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><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 &nbsp;&nbsp;</span></span></li>
    <li><span>com.example.actions.products.Display&nbsp;(</span><span class="keyword">implements</span><span>&nbsp;com.opensymphony.xwork2.Action)
    &nbsp;&nbsp;</span></li>
    <li><span>com.example.struts.company.details.ShowCompanyDetailsAction&nbsp;&nbsp;</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.
命名空间。从定义的.package.locators标示开始到包结束的部分，就是命名空间。举个例子：<br />
Com.ustb.web.user.userAction的命名空间是：&#8221;/user&#8221;。Com.ustb.web.user.detail.UserAction的命名空间是：&#8221;/user/detail&#8221;<br />
5.
Convention通过如下规则确定URL的具体资源部分:去掉类名的Action部分。然后将将每个分部的首字母转为小写，用&#8217;-&#8217;分割，你可以设置struts.convention.action.name.separator
如</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-xml">
    <li><span><span class="tag">&lt;</span><span class="tag-name">constant</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"struts.convention.action.name.separator"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"-"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="xml" style="display: none;" name="code">&lt;constant name="struts.convention.action.name.separator" value="-" /&gt;</pre>
<p><br />
还是举个例子：<br />
UserAction-&gt;user&nbsp; UserDetailAction
-&gt;user-detail。结合上面的。对于com.ustb.web.user.detail.UserDetailAction，映射的url就是/WEB-INF/content/user/detail/user-detail.jsp<br />
6.
struts支持.jsp .html .htm
.vm格式的文件。<br />
下面是actiong和结果模版的映射关系：<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>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>以上的内容来自struts2的文档<a href="http://struts.apache.org/2.1.6/docs/convention-plugin.html" target="_blank">http://struts.apache.org/2.1.6/docs/convention-plugin.html</a> </p>
<p>&nbsp;</p>
<p><br />
当然，简单的通过默认的方式来进行配置不能完全满足实际项目的需要。所幸，convention的零配置是非常灵活的。<br />
<strong>通过@Action注释</strong>
<br />
对如下例子：</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.example.web;
    &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.Action;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport;&nbsp;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloAction&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"action1"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method1()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;SUCCESS;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/user/action2"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method2()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;SUCCESS;
    &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</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>&nbsp;</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 class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.example.web;
    &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport;&nbsp;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Action;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Actions;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloAction&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="annotation">@Actions</span><span>({
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/different/url"</span><span>), &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/another/url"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;}) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method1()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;&#8220;error&#8221;;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;}&nbsp;&nbsp;</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 &#8220;error&#8221;;
}</pre>
<p><br />
我们可以通过：<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注释后，只是多了一种调用方式，而不是说覆盖了原来的调用方式。比如对于如下例子：</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.example.web;
    &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport;&nbsp;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Action;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Actions;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloAction&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/another/url"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method1()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;&#8220;error&#8221;;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;}&nbsp;&nbsp;</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 &#8220;error&#8221;;
}</pre>
<p><br />
我们调用method1方法可以通过两种方式：<br />
1&nbsp;<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;">url：<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;">url：<span style="font-size: small;"><strong><span style="color: #0000ff;">/WEB-INF/content/another/url-error.jsp</span>
</strong></span></span><br />
可见，两种方式均可对method1方法进行调用，唯一的区别就是，两种调用的映射是不一样的，所以，想跳转到不同的界面，这是一个非常好的选择。<br />
<br />
<br />
<strong>通过@Namespace
注释</strong> </p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.example.web;
    &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport;&nbsp;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Action;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Actions;
    &nbsp;&nbsp;</span></li>
    <li><span class="annotation">@Namespace</span><span>(</span><span class="string">"/other"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloWorld&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method1()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;&#8220;error&#8221;;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"url"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method2()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">return</span><span>&nbsp;&#8220;error&#8221;;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/different/url"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method3()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">return</span><span>&nbsp;&#8220;error&#8221;;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</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 &#8220;error&#8221;;
}
@Action("url")
public String method2() {
return &#8220;error&#8221;;
}
@Action("/different/url")
public String method3() {
return &#8220;error&#8221;;
}
}</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;">访问<strong>method1</strong>
方法。<br />
通过</span> <strong><span style="font-size: small; color: #0000ff;">/other/url!method2.action</span>
</strong><span style="font-size: small;">访问<strong>method2</strong>
方法<br />
通过</span> <strong><span style="font-size: small; color: #0000ff;">/different /url!method3.action</span>
</strong><span style="font-size: small;">访问<strong>method3</strong> 方法</span>
<br />
与@Action 注释不同的是，该注释覆盖了默认的namespace(这里是&#8217;/&#8217;)，此时再用<span style="font-size: small;">hello!method1.action</span>
已经不能访问<strong>method1</strong> 了.<br />
<strong>@Results和@Result</strong>
<br />
<strong>1 全局的（global）。</strong>
<br />
全局results可以被action类中所有的action分享，这种results在action类上使用注解进行声明。</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.example.actions;
    &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport;&nbsp;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Action;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Actions;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Result;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Results;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="annotation">@Results</span><span>({
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="annotation">@Result</span><span>(name=</span><span class="string">"failure"</span><span>,&nbsp;location=</span><span class="string">"/WEB-INF/fail.jsp"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span>}) &nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloWorld&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method1()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;&#8220;failure&#8221;;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/different/url"</span><span>) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method2()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;&#8220;failure&#8221;;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</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 &#8220;failure&#8221;;
}
@Action("/different/url")
public String method2() {
return &#8220;failure&#8221;;
}
}</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;">时，返回</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;">时，返回</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;">时，返回</span> <strong><span style="font-size: small; color: #0000ff;">/WEB-INF/fail.jsp</span>
</strong></span><br />
<br />
<strong>2 本地的（local）。</strong>
<br />
本地results只能在action方法上进行声明。</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://javeye.javaeye.com/blog/358744#"><img alt="复制代码" src="http://javeye.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.example.actions;
    &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport;&nbsp;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Action;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Actions;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Result;
    &nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.apache.struts2.convention.annotation.Results;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloWorld&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(value=</span><span class="string">"/other/bar"</span><span>,results={</span><span class="annotation">@Result</span><span>(name&nbsp;=&nbsp;</span><span class="string">"error"</span><span>,&nbsp;location&nbsp;=&nbsp;</span><span class="string">"www.baidu.com"</span><span>,type=</span><span class="string">"redirect"</span><span>)}) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;method1()&nbsp;{
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;&#8220;error&#8221;;
    &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</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 &#8220;error&#8221;;
}
}</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;">时，返回</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;">时，返回</span> <span style="font-size: small;"><strong><span style="color: #0000ff;">www.baidu.com</span> </strong></span><br />
</p>
<img src ="http://www.blogjava.net/conans/aggbug/289508.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2009-08-02 22:28 <a href="http://www.blogjava.net/conans/articles/289508.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2开发环境搭建 </title><link>http://www.blogjava.net/conans/articles/283364.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Sat, 20 Jun 2009 08:16:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/283364.html</guid><description><![CDATA[<h2>
搭建最简单的开发环境
<a linkindex="10" name="1538" href="http://www.javaeye.com/wiki/struts2/1321-struts2-development-environment-to-build#top"><img alt="Top" src="http://www.javaeye.com/images/wiki/top.gif?1229402183" /></a>
</h2>
<div class="content">
首先我们来看看如何搭建最简单的J2EE项目的开发环境。
<br />
<br />
<strong>1. 我们需要建立的一个空的J2EE项目的目录结构</strong>
<br />
<br />
<img src="http://downpour.javaeye.com/upload/attachment/61763/09233f22-e160-3be6-9540-d1c89a5b9e09.gif" alt="" />
<br />
<br />
在这里，我简单解释一下这些目录的作用：
<br />
<br />
<strong>src(source folder)</strong>：存放所有的Java源代码。
<br />
<strong>conf(source folder)</strong>：存放所有的配置文件。
<br />
<strong>test(source folder)</strong>：存放所有的Java测试代码和调试代码。
<br />
<strong>web</strong>：web项目的根目录，下面有WEB-INF目录以及在此之下的classes和lib目录。classes目录将会成为所有的source folder的编译对象目录，而lib目录则存放项目所依赖的jar包。
<br />
<strong>lib</strong>：也存放jar包，这些jar包可能仅仅在开发调试时依赖，项目本身则不依赖这些jar文件。
<br />
<br />
<strong>2. 编写IDE相关的文件</strong>
<br />
<br />
在这里，你还能看到classpath文件和project文件。这两个文件是导入到eclipse中所必须的文件，是我为eclipse工程而写的文件。如果你使用其他IDE，可能需要自行编辑与其他IDE相关的项目文件。
<br />
<br />
在建立了这些目录结构后，你就可以将其导入到eclipse中作为eclipse的工程了。
<br />
<br />
<img src="http://downpour.javaeye.com/upload/attachment/61765/b0380d6d-2634-3ba1-bd41-100be3f3be07.gif" alt="" />
<br />
<br />
<strong>3. 加入相关调试所需要的jar包，并指定classpath</strong>
<br />
<br />
接下来，我们把Jetty所需要的jar包copy到lib目录下，并在IDE中指定classpath。
<br />
<br />
<img class="magplus" title="点击查看原始大小图片" src="http://downpour.javaeye.com/upload/attachment/61767/2b527db3-298b-3dbe-9500-5deee6ed7548.gif" alt="" height="457" width="650" />
<br />
<br />
<strong>4. 添加Jetty启动类</strong>
<br />
<br />
在test下建一个runtime的目录，并添加Jetty启动类。
<br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20runtime%3B%0A%0Aimport%20org.mortbay.jetty.Connector%3B%0Aimport%20org.mortbay.jetty.Server%3B%0Aimport%20org.mortbay.jetty.nio.SelectChannelConnector%3B%0Aimport%20org.mortbay.jetty.webapp.WebAppContext%3B%0A%0A%2F**%0A%20*%20Jetty%20Server%20starter.%20Use%20embedded%20mode.%0A%20*%20%0A%20*%20%40author%20Downpour%0A%20*%2F%0Apublic%20class%20JettyStarter%20%7B%0A%0A%09%2F**%0A%09%20*%20%40param%20args%0A%09%20*%20%40throws%20Exception%0A%09%20*%2F%0A%09public%20static%20void%20main(String%5B%5D%20args)%20throws%20Exception%20%7B%0A%09%09long%20begin%20%3D%20System.currentTimeMillis()%3B%0A%09%09Connector%20connector%20%3D%20new%20SelectChannelConnector()%3B%0A%09%09connector.setPort(Integer.getInteger(%22jetty.port%22%2C%208080).intValue())%3B%0A%0A%09%09WebAppContext%20webapp%20%3D%20new%20WebAppContext(%22web%22%2C%20%22%2Fstruts-sample%22)%3B%0A%09%09webapp.setDefaultsDescriptor(%22.%2Ftest%2Fruntime%2Fwebdefault.xml%22)%3B%0A%09%09%0A%09%09Server%20server%20%3D%20new%20Server()%3B%0A%09%09server.setConnectors(new%20Connector%5B%5D%20%7B%20connector%20%7D)%3B%0A%09%09server.setHandler(webapp)%3B%0A%09%09server.start()%3B%0A%09%09System.out.println(%22Jetty%20Server%20started%2C%20use%20%22%20%2B%20(System.currentTimeMillis()%20-%20begin)%20%2B%20%22%20ms%22)%3B%0A%09%7D%0A%7D%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span class="keyword">package</span><span>&nbsp;runtime;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">import</span><span>&nbsp;org.mortbay.jetty.Connector;&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">import</span><span>&nbsp;org.mortbay.jetty.Server;&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">import</span><span>&nbsp;org.mortbay.jetty.nio.SelectChannelConnector;&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">import</span><span>&nbsp;org.mortbay.jetty.webapp.WebAppContext;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="comment">/**</span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;Jetty&nbsp;Server&nbsp;starter.&nbsp;Use&nbsp;embedded&nbsp;mode.</span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;</span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;Downpour</span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;JettyStarter&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;args</span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;Exception</span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">long</span><span>&nbsp;begin&nbsp;=&nbsp;System.currentTimeMillis();&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connector&nbsp;connector&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;SelectChannelConnector();&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connector.setPort(Integer.getInteger(<span class="string">"jetty.port"</span><span>,&nbsp;</span><span class="number">8080</span><span>).intValue());&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WebAppContext&nbsp;webapp&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;WebAppContext(</span><span class="string">"web"</span><span>,&nbsp;</span><span class="string">"/struts-sample"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;webapp.setDefaultsDescriptor(<span class="string">"./test/runtime/webdefault.xml"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Server&nbsp;server&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Server();&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server.setConnectors(<span class="keyword">new</span><span>&nbsp;Connector[]&nbsp;{&nbsp;connector&nbsp;});&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server.setHandler(webapp);&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server.start();&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="string">"Jetty&nbsp;Server&nbsp;started,&nbsp;use&nbsp;"</span><span>&nbsp;+&nbsp;(System.currentTimeMillis()&nbsp;-&nbsp;begin)&nbsp;+&nbsp;</span><span class="string">"&nbsp;ms"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">package runtime;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.webapp.WebAppContext;
/**
* Jetty Server starter. Use embedded mode.
*
* @author Downpour
*/
public class JettyStarter {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
long begin = System.currentTimeMillis();
Connector connector = new SelectChannelConnector();
connector.setPort(Integer.getInteger("jetty.port", 8080).intValue());
WebAppContext webapp = new WebAppContext("web", "/struts-sample");
webapp.setDefaultsDescriptor("./test/runtime/webdefault.xml");
Server server = new Server();
server.setConnectors(new Connector[] { connector });
server.setHandler(webapp);
server.start();
System.out.println("Jetty Server started, use " + (System.currentTimeMillis() - begin) + " ms");
}
}
</pre>
<br />
<br />
如果此时，你在WEB-INF下有web.xml，那么你就可以执行上面这个Jetty的启动类。
<br />
<br />
<img class="magplus" title="点击查看原始大小图片" src="http://downpour.javaeye.com/upload/attachment/61769/2776a3d4-3879-3676-8518-56f022fbce41.gif" alt="" height="364" width="650" />
<br />
<br />
<strong>5. 启动、调试、测试</strong>
<br />
<br />
执行了Jetty的启动类后，可以看到启动界面的日志：
<br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=15%20%5Bmain%5D%20INFO%20org.mortbay.log%20-%20Logging%20to%20org.slf4j.impl.SimpleLogger(org.mortbay.log)%20via%20org.mortbay.log.Slf4jLog%0A15%20%5Bmain%5D%20INFO%20org.mortbay.log%20-%20jetty-6.1.7%0A1109%20%5Bmain%5D%20INFO%20org.mortbay.log%20-%20Started%20SelectChannelConnector%400.0.0.0%3A8080%0AJetty%20Server%20started%2C%20use%201547%20ms%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span class="number">15</span><span>&nbsp;[main]&nbsp;INFO&nbsp;org.mortbay.log&nbsp;-&nbsp;Logging&nbsp;to&nbsp;org.slf4j.impl.SimpleLogger(org.mortbay.log)&nbsp;via&nbsp;org.mortbay.log.Slf4jLog&nbsp;&nbsp;</span></span></li>
    <li><span><span class="number">15</span><span>&nbsp;[main]&nbsp;INFO&nbsp;org.mortbay.log&nbsp;-&nbsp;jetty-</span><span class="number">6.1</span><span>.</span><span class="number">7</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span><span class="number">1109</span><span>&nbsp;[main]&nbsp;INFO&nbsp;org.mortbay.log&nbsp;-&nbsp;Started&nbsp;SelectChannelConnector</span><span class="annotation">@0</span><span>.0.</span><span class="number">0.0</span><span>:</span><span class="number">8080</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>Jetty&nbsp;Server&nbsp;started,&nbsp;use&nbsp;<span class="number">1547</span><span>&nbsp;ms&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">15 [main] INFO org.mortbay.log - Logging to org.slf4j.impl.SimpleLogger(org.mortbay.log) via org.mortbay.log.Slf4jLog
15 [main] INFO org.mortbay.log - jetty-6.1.7
1109 [main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8080
Jetty Server started, use 1547 ms
</pre>
<br />
<br />
这表示你已经成功启动了Jetty作为你的Web服务器。当然，你可以使用Debug模式来执行Jetty类，这样就进入了调试模式，你可以在代码中设置断点进行调试。
<br />
<br />
在这里，还有一点需要简单提一下，默认情况下，Jetty会在windows上使用缓存，所以会把js，css等文件进行锁定，使你无法编辑。为了解决这个问题，需要设置一些默认参数。这里，我们可以使用google大法，已经有朋友为我们解决了这个问题：
<br />
<br />
<a linkindex="11" href="../../alwayscy/archive/2007/05/27/120305.html" target="_blank">http://www.blogjava.net/alwayscy/archive/2007/05/27/120305.html</a>
<br />
<br />
所以，我在runtime的同级目录建立了一个webdefault.xml文件，并且指定Jetty使用该文件作为默认的参数设定。
<br />
<br />
<strong>【小结】</strong>
<br />
在上面我介绍了我个人的开发调试环境，这种开发环境的好处可能有一下这些：
<br />
<br />
1. 开发环境不依赖于任何IDE或者相关的插件，只需要运行Java文件即可进行调试。（当然，你可能需要编写IDE相关的project文件来获取IDE的工程支持）
<br />
<br />
2. 开发环境不依赖于任何外部的Web服务器，与环境无关，所以无论将项目迁移到哪里，都可以直接运行。
<br />
<br />
3. 不需要开发人员额外学习如何搭建开发环境，开发环境已经内置，降低了开发人员的学习成本。
</div>
<h2>
完善Library的管理方式
<a linkindex="12" name="1539" href="http://www.javaeye.com/wiki/struts2/1321-struts2-development-environment-to-build#top"><img alt="Top" src="http://www.javaeye.com/images/wiki/top.gif?1229402183" /></a>
</h2>
<div class="content">
在上面搭建环境的过程中，我们发现，Library的管理存在着一定问题。这个问题主要表现为：
<br />
<br />
1.
不容易做Library的版本管理。如果Library的版本需要升级，那么我们不得不重新copy一份新的jar包，并且借助IDE重新指定项目的
classpath。这种劳动，对于一个项目还可以接受，如果你有10多个项目，那么jar包的复制工作会让你很头疼。
<br />
<br />
2.
每个项目都会有Library的副本。这一点让人非常恼火。实际上，对于一个公司或者一个项目组而言，使用的技术体系基本不变。然而，每个项目的
Library却是分开的。不仅如此，每个项目都要从svn中下载大量的相同的Library文件，给我们的硬盘造成极大的空间浪费。对于那些频繁使用
Branch的项目来说，这些Library的下载简直就是噩梦。
<br />
<br />
所以，我们需要一个<strong>集中式的Library管理方式</strong>。而这一点曾经在Javaeye的海阔天空版激烈得讨论过使用maven来进行管理还是自行管理。
<br />
<br />
<div class="quote_title">Readonly 写道</div>
<div class="quote_div">
<br />
共享类库可以用IDE reference project解决，公司内部项目给常用的lib建立一个project，从CVS上check
out，其他工程项目都依赖这个project就可以了，ant build也直接引用这个项目的jar就可以，项目体积照样只有几百K。 <br />
<br />
——一个讨厌ant，更加讨厌maven的人
<br />
</div>
<br />
<br />
我比较赞同Readonly老大的说法而倾向于自行管理。maven这样的高级货，偶实在是用不来啊。那么我们就来看看如何使用共享类库来进行Library管理。
<br />
<br />
<strong>
<br />
1. 首先建立一个共享类库</strong>
<br />
<br />
建立一个共享类库，将项目中需要共享的Library进行恰当的分类。同时，为每个加入到Library中的jar包进行统一的格式化的命名方
式。例如：spring/spring-2.5.5.jar等等。这样的好处在于，一旦jar包的版本有更新，可以加入新的jar包而保留原来的。在项目
中，就可以通过引用不同版本的jar包来对Library进行版本管理。
<br />
<br />
以下就是我个人建立的一个共享类库，大家可以参考：
<br />
<br />
<a href="svn://www.demo2do.com/library" target="_blank">svn://www.demo2do.com/library</a>
<br />
<br />
<strong>2. checkout共享类库，并将其导入到IDE中作为一个Library工程</strong>
<br />
<br />
<img src="http://downpour.javaeye.com/upload/attachment/61771/8cea5d64-2499-3e66-9154-88b740a47381.gif" alt="" />
<br />
<br />
<strong>3. 为你的项目指定classpath，引用的jar包存在于Library工程中</strong>
<br />
<br />
<img src="http://downpour.javaeye.com/upload/attachment/61775/2f7f3e8e-2450-3d5f-a2e9-84dff03c11f8.gif" alt="" />
<br />
<br />
在这里，我们可以看到，原来项目中的lib目录被删除，jar包也被删除。在项目中所引用的jar包是Library项目中的jar包。
<br />
<br />
<strong>【小结】</strong>
<br />
完成了上述所有的步骤之后，Library就被集中管理起来，而每个项目也不会再变得那么庞大。当然，开发环境的搭建完全取决于个人的习惯，所以使用各自喜欢的方式吧，不要让环境问题束缚你们的手脚。<br />
<br />
转自：http://www.javaeye.com/wiki/struts2/1321-struts2-development-environment-to-build<br />
</div>
<img src ="http://www.blogjava.net/conans/aggbug/283364.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2009-06-20 16:16 <a href="http://www.blogjava.net/conans/articles/283364.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LightURL——打造零配置的Struts2开发方式</title><link>http://www.blogjava.net/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.blogjava.net/conans/articles/231367.html</guid><description><![CDATA[<strong>背景</strong> <br />
<br />
Struts2已经日益成为Web层比较主流的开发框架，它来源于Webwork2，是一个非常优秀的MVC框架。在Webwork2设计之处，Annotation和Ruby on Rails还没有像现在那么火，所以整个框架在配置方面还是沿用了Web框架惯用的XML作为主要的配置方式。 <br />
<br />
随着时代的发展，对于Web程序员来说，如何简化配置成了一个很重要的课题。在这方面，Struts2也有一些探索。在Struts2的官方网站上，我们可以找到一些优秀的plugin来做这些工作： <br />
<br />
<a href="http://cwiki.apache.org/S2PLUGINS/codebehind-plugin.html" target="_blank">http://cwiki.apache.org/S2PLUGINS/codebehind-plugin.html</a> <br />
<br />
<a href="http://cwiki.apache.org/S2PLUGINS/smarturls-plugin.html" target="_blank">http://cwiki.apache.org/S2PLUGINS/smarturls-plugin.html</a> <br />
<br />
LightURL的目的是为了吸取这些优秀的plugin的优点，并支持更方便的配置方式。 <br />
<br />
<strong>安装</strong> <br />
<br />
1. 将struts2-lighturl-plugin.jar加入到classpath下 <br />
<br />
2. 配置你的web.xml <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/242838#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;Struts&nbsp;Filter&nbsp;--&gt; &nbsp;&nbsp;</span></li>
    <li><span>&lt;filter&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-name&gt;struts&lt;/filter-name&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-</span><span class="keyword">class</span><span>&gt;com.demo2do.lighturl.LightURLFilter&lt;/filter-</span><span class="keyword">class</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;/filter&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&lt;!--&nbsp;Struts&nbsp;URL&nbsp;Definition&nbsp;--&gt; &nbsp;&nbsp;</span></li>
    <li><span>&lt;filter-mapping&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;filter-name&gt;struts&lt;/filter-name&gt; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;url-pattern&gt;/*&lt;/url-pattern&gt; &nbsp;&nbsp;</span></li>
    <li><span>&lt;/filter-mapping&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">
&lt;!-- Struts Filter --&gt;
&lt;filter&gt;
&lt;filter-name&gt;struts&lt;/filter-name&gt;
&lt;filter-class&gt;com.demo2do.lighturl.LightURLFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;!-- Struts URL Definition --&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;struts&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</pre>
<br />
<br />
3. 需要指定你的action package所在位置和一些基本配置 <br />
<br />
这一步一般在struts.properties中完成。你可以建一个struts.properties的配置文件，并放到classpath下，并指定如下配置 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/242838#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>##&nbsp;action&nbsp;</span><span class="keyword">package</span><span>&nbsp;config &nbsp;&nbsp;</span></span></li>
    <li><span>lighturl.action.packages=com.demo2do.lighturl.action &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>##&nbsp;action&nbsp;mapping&nbsp;implementation&nbsp;</span><span class="keyword">class</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>struts.mapper.</span><span class="keyword">class</span><span>=com.demo2do.lighturl.LightURLActionMapper &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>##&nbsp;</span><span class="keyword">default</span><span>&nbsp;parent&nbsp;</span><span class="keyword">package</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>lighturl.action.</span><span class="keyword">default</span><span>.parent.</span><span class="keyword">package</span><span>=struts-config &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>##&nbsp;define&nbsp;your&nbsp;entity&nbsp;</span><span class="keyword">package</span><span>&nbsp;(optional) &nbsp;&nbsp;</span></span></li>
    <li><span>#&nbsp;lighturl.entity.</span><span class="keyword">package</span><span>=com.demo2do.lighturl.entity&nbsp;&nbsp;</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的所有配置即告完成，现在你已经可以使用所有lighturl所提供的特性。 <br />
<br />
<strong>Namespace, ActionName和URL映射</strong> <br />
<br />
lighturl所提供的最基本的特性是根据你的Action所在的package，确定namespace和actionName，并进行对应的URL映射。 <br />
<br />
举例说明，你在上面所讲述的struts.properties中，已经指定了你的action package <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/242838#"><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&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">lighturl.action.packages=com.demo2do.lighturl.action
</pre>
<br />
<br />
那么，如果你有以下的Action类，那么lighturl将根据如下的规则来确定每个Action类所对应的namespace，actionName和url映射关系 <br />
<br />
1. 根据lighturl.action.packages的配置的package到你的Action类的相对package来确定namespace，如果其中有驼峰法命名，那么转化成"-"连接的单词 <br />
<ul>
    <li>com.demo2do.lighturl.action.Index&nbsp; ----&gt; /
    <li>com.demo2do.lighturl.action.user.Search ----&gt; /user
    <li>com.demo2do.lighturl.action.blog.category.Index ----&gt; /blog/category
    <li>com.demo2do.lighturl.action.accoutDetail.View ----&gt; /account-detail </li>
</ul>
<br />
2. 将Action类的类名转化成actionName。如果碰到的Action类以"Action"结尾，则去掉末尾的"Action"，如果其中有驼峰法命名,那么转化成"-"连接的单词 <br />
<ul>
    <li>com.demo2do.lighturl.action.Index ----&gt; index
    <li>com.demo2do.lighturl.action.user.SearchAction ----&gt; search
    <li>com.demo2do.lighturl.action.blog.CategoryBlog ----&gt; category-blog </li>
</ul>
<br />
3. 将namespace与actionName拼起来，就成构成映射到具体Action类的url <br />
<ul>
    <li>http://host:port/app/user/index ---&gt; com.demo2do.lighturl.action.user.Index
    <li>http://host:port/app/blog/category-blog ---&gt; com.demo2do.lighturl.action.blog.CategoryBlog </li>
</ul>
<br />
上面的这种URL匹配方式，我称之为：<strong>package匹配</strong> <br />
<br />
<strong>特殊形式的URL</strong> <br />
<br />
应该说根据package来进行Action映射，可以解决绝大多数从url到action的映射配置问题。不过有的时候，我们可能需要支持一些特殊形式的url。LightURL在默认情况下，支持下列2种特殊形式的URL <br />
<br />
1. 支持将名为Index的Action直接映射到package上 <br />
<br />
这种匹配我称之为：<strong>Namespace匹配</strong>。这一个特性很直观。如果你在某个Action的package下面有一个名为Index的Action类，那么如果你直接访问这个package，那么你可以访问到这个类： <br />
<ul>
    <li>com.demo2do.lighturl.action.Index ---&gt; http://host:port/app/
    <li>com.demo2do.lighturl.action.user.Index ---&gt; http://host:port/app/user
    <li>com.demo2do.lighturl.action.blog.category.Index ---&gt; http://host:port/app/blog/category </li>
</ul>
<br />
2. 支持类似: /entity/${id}形式的URL <br />
<br />
这种匹配我通常称之为：<strong>entity匹配</strong>。这个特性也比较简单，如果你有某个entity，并且在你的Action package下有一个与entity同名的package。同时在这个package下有一个叫View的Action，那么上述形式的URL会被映射到该Action。 <br />
<ul>
    <li>com.demo2do.lighturl.action.user.View ---&gt; http://host:port/app/user/3456
    <li>com.demo2do.lighturl.action.blog.View ---&gt; http://host:port/app/user/1113 </li>
</ul>
<br />
你可以通过在struts.properties中指定你entity所在的package来对哪些url可以具备这些特性，如果你输入的url不在你所指定的package中含有entity，那么这个url将无法被识别。 <br />
针对有些情况，数据库的主键可能不是数字。此时，你可以通过自己实现com.demo2do.lighturl.config.EntityPrimaryKeyIdentifier的接口来指定你的url中id具备什么特点。默认的实现是将主键识别为数字。 <br />
<br />
<strong>使用Annotation来指定映射</strong> <br />
<br />
除了上述这些基本特性以外，还可以通过Annotaion来指定URL映射。目前情况下，LightURL所支持的Annotation有两种类型: <br />
<br />
1. URL完整匹配 <br />
<br />
URL完整匹配是指如果某个url完整匹配于Annotation中所指定的内容，那么这个URL将被映射到Annotation所在的Action类的method <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/242838#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.demo2do.lighturl.action.user; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.demo2do.lighturl.annotation.Action; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;Downpour </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;* </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Search&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">long</span><span>&nbsp;serialVersionUID&nbsp;=&nbsp;-1728616675239859226L; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/*&nbsp;(non-Javadoc) </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;com.opensymphony.xwork2.ActionSupport#execute() </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/all/search-user"</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;execute()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">super</span><span>.execute(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</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 />
例如，上述的Action类有一个Annotation，那么这个Action和method将被映射到对应的URL:http://host:port/app/all/search-user。 <br />
<br />
注意，此时，虽然从url上来看，这是一个没有什么规则的url，但是其所对应的namespace和actionName还是根据com.demo2do.lighturl.action.user.Search来进行计算的。 <br />
<br />
2. URL Template <br />
<br />
URL Template是指，url可以匹配Annotaion中指定的某种URL Template，并将其中的可变部分作为参数映射到Action中。 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/242838#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.demo2do.lighturl.action.blog; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.demo2do.lighturl.annotation.Action; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;Downpour </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;* </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Category&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">long</span><span>&nbsp;serialVersionUID&nbsp;=&nbsp;-1535992103374733252L; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;Long&nbsp;id; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;year; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;month; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;day; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/*&nbsp;(non-Javadoc) </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;com.opensymphony.xwork2.ActionSupport#execute() </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/blogs/${year}/${month}/${day}"</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;execute()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">super</span><span>.execute(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Action</span><span>(</span><span class="string">"/blog/${id}/edit"</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;edit()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">super</span><span>.execute(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;setters&nbsp;and&nbsp;getters </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</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 />
在上述的例子中，可以发现，在Annotation中所指定的内容是一个URL Template，如果你有一个url，可以匹配上面的URL Template，那么url将匹配到这个Action的method，并且将对应位置的值注入到Action中的同名参数中。 <br />
<br />
针对上面的例子： <br />
http://host:port/app/blogs/2008/08/07将被映射到这个Action的execute，并且2008，08和07分别映射到year，month和day中。 <br />
http://host:port/app/blog/2345/edit将被映射到Action的edit方法，并且2345映射到id中作为参数 <br />
<br />
<strong>URL的匹配顺序与重复配置的校验</strong> <br />
<br />
在上面的例子中，介绍了那么多的url映射到Action中的方式。他们之间可能会出现冲突，有些冲突，LightURL会在系统启动时为你检查出来，并强制要求你纠正它，而有些冲突，则通过优先级匹配的方式进行。 <br />
<br />
下列冲突将被认为是你必须在系统启动前就进行纠正的： <br />
1. Annotation中定义的URL Template互相之间冲突 <br />
<br />
例如：/blogs/${year}/${month}/${day}和/blogs/${category}/${id}/edit就是冲突的。 <br />
<br />
2. Annotation中定义的URL Template与其他Annotation中定义的完全匹配URL冲突 <br />
<br />
例如：/blogs/${year}/${month}和/blogs/category/index就是冲突的。 <br />
<br />
3. Annotation中定义的URL Template与形如/entity/${id}的url定义冲突 <br />
<br />
例如：/user/${id}形式的Annotation定义可能会与系统默认支持的冲突。 <br />
<br />
在其他情况下，如果你定义的URL映射互相直接有冲突，那么LightURL将根据某个顺序进行URL匹配，并找到第一个匹配的映射方式，然后放弃查找。这个顺序为： <br />
1. 首先进行<strong>Namespace匹配</strong>，如果url恰好能匹配某个namespace，并且其对应的package下有Index作为Action，那么直接进行匹配。 <br />
2. 其次查看所有的Annotation定义中，是否存在<strong>完整的URL匹配</strong>，如果找到，那么进行直接匹配。 <br />
3. 接着进行<strong>package匹配</strong>，将url分解成相应的namespace和actionName，与已有的配置进行匹配，如果找到，那么直接匹配。 <br />
4. 然后进行<strong>entity匹配</strong>，看看url是否形如:/entity/${id}，如果是，那么直接匹配。 <br />
5. 最后进行Annotation定义的<strong>Url Template匹配</strong>。 <br />
<br />
如果所有的五种情况都无法进行匹配，那么这个URL将无法被LightURL识别，继续交由Struts2进行后续处理。 <br />
<br />
<br />
上面所描述的内容都是Url到Action的映射。下面的部分，描述的是如何在Action执行完毕之后，转到相应的结果view。 <br />
<br />
<strong>Codebehind</strong> <br />
<br />
LightURL支持codebehind。有关codebehind的相关知识，可以参考struts2的相关文档： <br />
<a href="http://struts.apache.org/2.x/docs/codebehind-plugin.html" target="_blank">http://struts.apache.org/2.x/docs/codebehind-plugin.html</a> <br />
<br />
有了codebehind的支持，那么从Action转到类似jsp，ftl或者vm的view层组件就不需要任何配置，只要符合一定的命名规范，就可以直接进行转向。 <br />
<br />
<strong>ResultCode的识别</strong> <br />
<br />
但是在很多情况下，我们需要的是全方位的Result类型的支持。例如，有的时候我们需要返回JSON Result，有的时候，我们可能需要Redirect到一个新的Action。此时，我们不得不为此增加一些配置，或者借助Annotation来完成。 <br />
<br />
为此，LightURL提供了一种根据ResultCode进行识别的命名方式来匹配你所指定的Result。 <br />
<br />
以JSON Result为例，你可以这么写： <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/242838#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.demo2do.lighturl.action.user; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.demo2do.lighturl.entity.User; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;Downpour </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;* </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Index&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">long</span><span>&nbsp;serialVersionUID&nbsp;=&nbsp;-5017825114664788765L; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;User&nbsp;user; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/*&nbsp;(non-Javadoc) </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;com.opensymphony.xwork2.ActionSupport#execute() </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;execute()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="string">"j:user"</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;setters&nbsp;and&nbsp;getters </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</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会将这个resultCode识别成：请返回JSON Result，并且JSON的Result的root为user对象。 <br />
<br />
再例如： <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/242838#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;com.demo2do.lighturl.action.user; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.demo2do.lighturl.entity.User; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork2.ActionSupport; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;Downpour </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;* </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Index&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">long</span><span>&nbsp;serialVersionUID&nbsp;=&nbsp;-5017825114664788765L; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;User&nbsp;user; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/*&nbsp;(non-Javadoc) </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;com.opensymphony.xwork2.ActionSupport#execute() </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;execute()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="string">"r:/user/add-user"</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;setters&nbsp;and&nbsp;getters </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</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识别，并将他们的前缀分别定制为："r:"("redirect:")或者"j:"("json:")。 <br />
<br />
当然，你可以根据你自己的情况，实现你自己的ResultCode的识别程序，你只需要实现com.demo2do.lighturl.result.ResultCodeConfig接口即可。并在struts.properties中指定你希望LightURL进行ResultCode匹配的顺序。 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/topic/242838#"><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&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre class="java" style="display: none" name="code">lighturl.result.code.config=yourpackage.ResultCodeConfigImpl1,yourpackage.ResultCodeConfigImpl2
</pre>
<br />
<br />
这样，LightURL会根据你所指定的顺序，依次进行ResultCode的匹配，直到找到第一个匹配的Result Type为之。 <br />
<br />
当然，默认情况下，LightURL的匹配顺序为： <br />
<br />
codebehind -&gt; 你自定义的ResultCode识别实现 -&gt; json -&gt; redirect 
<img src ="http://www.blogjava.net/conans/aggbug/231367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-09-26 20:03 <a href="http://www.blogjava.net/conans/articles/231367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2教程－－第二章　Struts2的工作机制及分析 </title><link>http://www.blogjava.net/conans/articles/214089.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Thu, 10 Jul 2008 11:29:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/214089.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本章讲述Struts2的工作原理。读者如果曾经学习过Struts1.x或者有过Struts1.x的开发经验，那么千万不要想当然地以为这一章可以跳过。实际上Struts1.x与Struts2并无我们想象的血缘关系。虽然Struts2的开发小组极力保留Struts1.x的习惯，但因为Struts2的核心设计完全改变，从思想到设计到工作流程，都有了很大的不同。Struts2是Struts社区和W...&nbsp;&nbsp;<a href='http://www.blogjava.net/conans/articles/214089.html'>阅读全文</a><img src ="http://www.blogjava.net/conans/aggbug/214089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-07-10 19:29 <a href="http://www.blogjava.net/conans/articles/214089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Struts2与Struts1.x的深度比较</title><link>http://www.blogjava.net/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.blogjava.net/conans/articles/213756.html</guid><description><![CDATA[<p><span>Struts</span><span>作为</span><span>MVC 2</span><span>的</span><span>Web</span><span>框架，自推出以来不断受到开发者的追捧，得到广泛的应用。作为最成功的</span><span>Web</span><span>框架，</span><span>Struts</span><span>自然拥有众多的优点：</span><span>MVC 2</span><span>模型的使用、功能齐全的标志库（</span><span>Tag Library</span><span>）、开放源代码。</span></p>
<p><span>但是，正所谓</span><span>&#8220;</span><span>没有最好，只有更好</span><span>&#8221;</span><span>，</span><span>Struts1.x</span><span>自身也有不少的缺点：需要编写的代码过多，容易引起</span><span>&#8220;</span><span>类爆炸</span><span>&#8221;</span><span>、单元测试困难。这些缺点随着</span><span>Web</span><span>的发展越来越明显。这就促生了</span><span>Struts 2</span><span>，它的诞生能很好的解决上述问题。</span></p>
<p><span>在本文中，笔者将对</span><span>Struts2</span><span>和</span><span>Struts1.x</span><span>这两种框架进行详细的比较。比较将涉及到这两种框架的</span><span>Action</span><span>、验证、类型转换及如何开发等方面的内容。希望通过这样的比较，让读者了解这两种框架各自的特点，以便于在自己的项目中，根据实际情况，尽快的过渡到</span><span>Struts2</span><span>的时代。本文的内容基于</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>&nbsp;</strong></p>
<p><strong><span><span>一、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong><span>引言</span></strong><strong></strong></p>
<p><strong>&nbsp;</strong></p>
<p><span>Struts</span><span>的第一个版本是在</span><span>2001</span><span>年</span><span>5</span><span>月份发布的。它的最初设想是通过结合</span><span>JSP</span><span>和</span><span>Servlet</span><span>，使</span><span>Web</span><span>应用的视图和业务</span><span>/</span><span>应用逻辑得以清晰地分离开来。在</span><span>Struts</span><span>之前，最常见的做法是在</span><span>JSP</span><span>中加入业务和应用逻辑，或者在</span><span>Servlet</span><span>中通过</span><span>println()</span><span>来生成视图。</span></p>
<p><span>自从第一版发布以来，</span><span>Struts</span><span>实际上已成为业界公认的</span><span>Web</span><span>应用标准。它的炙手可热也为自己带来了改进和变更，所以不但要跟上对</span><span>Web</span><span>应用框架不断变化的需求，而且要与日渐增多竞争激烈的众多框架的特性相融合。</span></p>
<p><span>到最后，产生了几个下一代</span><span>Struts</span><span>的解决方案。其中两个最受瞩目的方案是</span><span>Shale</span><span>和</span><span>Struts Ti</span><span>。</span><span>Shale</span><span>是一个基于构件的框架，并在最近成为</span><span>Apache</span><span>的顶级项目。而</span><span>Struts Ti</span><span>则是在</span><span>Struts</span><span>的成功经验基础上继续坚持对前端控制器（</span><span>Front Controller</span><span>）和</span><span>MVC</span><span>（</span><span>model-view-controller</span><span>）模式进行改进。</span></p>
<p><span>WebWork</span><span>项目是在</span><span>2002</span><span>年</span><span>3</span><span>月发布的，它对</span><span>Struts</span><span>式框架进行了革命性改进，引进了不少新的思想、概念和功能，但和原</span><span>Struts</span><span>代码并不兼容。</span><span>WebWork</span><span>是一个成熟的框架，经过了好几次重大的改进与发布。</span></p>
<p><span>在</span><span>2005</span><span>年</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>，成为</span><span>Struts</span><span>真正的继承者。</span></p>
<p><span>最后要注意的是，并不是说</span><span>Struts</span><span>或</span><span>WebWork</span><span>项目已经停止开发了。由于人们对这两个项目的兴趣仍然很高，而且也有很多开发者仍然愿意使用它们，因此这两个项目还在继续开发中，继续修复</span><span>Bug</span><span>，改进功能和继续添加新功能。</span><strong></strong></p>
<p><strong>&nbsp;</strong></p>
<p><strong><span><span>二、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong><span>Action</span></strong><strong><span>的区别</span></strong><strong></strong></p>
<p><strong>&nbsp;</strong></p>
<p><span>对于有着丰富的</span><span>Struts1.x</span><span>开发经验的朋友来说，都十分的清楚</span><span>Action</span><span>是整个</span><span>Struts</span><span>框架的核心内容，当然</span><span>Struts2</span><span>也不例外。不过，</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>架构。这是什么意思呢？从开发者角度看，就是说需要显示给用户的数据可以直接从</span><span>Action</span><span>中获取，而不像</span><span>Struts1.x</span><span>那样，必须把相应的</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>必须继承</span><span>org.apache.struts.action.Action</span><span>或者其子类，表单数据封装在</span><span>FormBean</span><span>中。</span><span>Struts 2</span><span>无须继承任何类型或实现任何接口，表单数据包含在</span><span>Action</span><span>中，通过</span><span>Getter</span><span>和</span><span>Setter</span><span>获取（如下面的</span><span>ActionForStruts2</span><span>的代码示例）。</span></p>
<p><span>虽然，在理论上</span><span>Struts2</span><span>的</span><span>Action</span><span>无须实现任何接口或者是继承任何的类，但是，在实际编程过程中，为了更加方便的实现</span><span>Action</span><span>，大多数情况下都会继承</span><span>com.opensymphony.xwork2.ActionSupport</span><span>类，并且重载（</span><span>Override</span><span>）此类里的</span><span>String execute()</span><span>方法。如下所示：</span></p>
<p align="left"><span>package ActionDiffer;</span></p>
<p align="left"><span>&nbsp;import java.text.DateFormat;</span></p>
<p align="left"><span>&nbsp;import java.util.Date;</span></p>
<p align="left">&nbsp;</p>
<p align="left"><span>&nbsp;import com.opensymphony.xwork2.ActionSupport;</span></p>
<p align="left">&nbsp;</p>
<p align="left"><span>&nbsp;public class ActionForStruts2 extends ActionSupport&nbsp;{</span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>private String message;</span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp; </span></span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>public String getMessage()&nbsp;{</span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return message;</span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp; </span>} </span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp; </span></span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp; </span>@Override </span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>public String execute()&nbsp;{</span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>message = " This is hello from strtuts2. Now is: " + DateFormat.getInstance().format( new Date());</span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return SUCCESS;</span></p>
<p align="left"><span><span>&nbsp;&nbsp;&nbsp; </span>} </span></p>
<p align="left"><span>}</span></p>
<p><span>首先，从</span><span>ActionForStruts2</span><span>可以看出，返回的对象不是</span><span>ActionForward</span><span>，而是</span><span>String</span><span>。如果你不喜欢以字符串的形式出现在你的代码中，有个</span><span>Helper</span><span>接口</span><span>Action</span><span>可以以常量方式提供常见结果，如</span><span>&#8220;success&#8221;</span><span>、</span><span>&#8220;none&#8221;</span><span>、</span><span>&#8220;error&#8221;</span><span>、</span><span>&#8220;input&#8221;</span><span>和</span><span>&#8220;login&#8221;</span><span>。</span></p>
<p><span>另外，</span><span> </span><span>按照惯例，在</span><span>Struts1.x</span><span>中只有</span><span>&#8220;execute&#8221;</span><span>方法能调用</span><span>Action,</span><span>　但在</span><span>Struts2</span><span>中并非必要，任何声明为</span><span>public String methodName() </span><span>方法，都能通过配置来调用</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>过程中调用的方法（</span><span>&#8220;execute&#8221;</span><span>方法）是不带参数的。那如何获取所需要的对象呢？答案是使用</span><span>IoC</span><span>（反转控制，</span><span>Inversion of Control)</span><span>，也叫</span><span>&#8220;</span><span>依赖注入（</span><span>Dependency Injection</span><span>）</span><span>&#8221;</span><span>的模式（想更多地了解这方面信息请看</span><span>Martin Fowler</span><span>的文章</span><span><a href="http://www.martinfowler.com/articles/injection.html" target="_blank"><span>http://www.martinfowler.com/articles/injection.html</span></a></span><span>）。</span><span>Spring</span><span>框架使得这个模式流行起来，然而</span><span>Struts2</span><span>的前身（</span><span>WebWork</span><span>）也同时应用上了这个模式。</span></p>
<p><strong>&nbsp;</strong></p>
<p><strong><span><span>三、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong><span>IoC</span></strong></p>
<p><span>IoC(Inversion of Control</span><span>，以下译为控制反转），随着</span><span>Java</span><span>社区中轻量级容器（</span><span>Lightweight Contianer</span><span>）的推广而越来越为大家耳熟能详。在此，无需再多费唇舌来解释</span><span>&#8220;</span><span>什么是控制反转</span><span>&#8221;</span><span>和</span><span>&#8220;</span><span>为什么需要控制反转</span><span>&#8221;</span><span>。因为互联网上已经有非常多的文章对诸如此类的问题作了精彩而准确的回答。读者可以去读一下</span><span>Rod Johnson</span><span>和</span><span>Juergen Hoeller</span><span>合著的《</span><span><a href="http://www.wrox.com/books/0764558315.shtml"><span>Expert one-on-one J2EE Development without EJB</span></a></span><span>》或</span><span>Martin Fowler</span><span>所写的《</span><span><a href="http://www.martinfowler.com/articles/injection.html" target="_blank"><span>Inversion of Control Containers and the Dependency Injection pattern</span></a></span><span>》。</span></p>
<p><span>众所周知，</span><span>Struts2</span><span>是以</span><span>Webwork 2</span><span>作为基础发展出来。而在</span><span>Webwork 2.2</span><span>之前的</span><span>Webwork</span><span>版本，其自身有一套控制反转的实现，</span><span>Webwork 2.2</span><span>在</span><span><a href="http://www.springframework.org/"><span>Spring </span><span><span>框架</span></span></a></span><span>的如火如荼发展的背景下，决定放弃控制反转功能的开发，转由</span><span>Spring</span><span>实现。值得一提的是，</span><span>Spring</span><span>确实是一个值得学习的框架，因为有越来越多的开源组件（如</span><span><a href="http://ibatis.apache.org/"><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>为了更好地了解反转控制，下面来看一个例子，如何利用</span><span>IoC</span><span>在</span><span>Action</span><span>处理过程中可以访问到当前请求</span><span>HttpServerRequest</span><span>对象。</span></p>
<p><span>在例子中，使用的依赖注入机制是接口注入。就如其名称一样，接口注入需要的是已经被实现了的接口。这个接口包含了相应属性的</span><span>setter</span><span>，为</span><span>Action</span><span>提供值。例子中使用了</span><span>ServletRequestAware</span><span>接口，如下：</span></p>
<p align="left"><span>public interface ServletRequestAware {<br />
<span>&nbsp;&nbsp;&nbsp; </span>public void setServletRequest(HttpServletRequest request);<br />
}</span></p>
<p><span>当继承这个接口后，原本简单的</span><span>Action</span><span>看起来有点复杂了，但是这时可以获取</span><span>HttpServerRequest</span><span>对象来使用了。</span></p>
<p align="left"><span>public class IoCForStruts2 implements ServletRequestAware {<br />
<span>&nbsp;&nbsp; </span>private HttpServletRequest request;<br />
<span>&nbsp;&nbsp; </span>public void setServletRequest(HttpServletRequest request) {<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>this.request = request;<br />
<span>&nbsp;&nbsp; </span>}<br />
<span>&nbsp;&nbsp; </span>public String execute() throws Exception {<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// </span><span>可以开始使用</span><span>request</span><span>对象进行工作了</span><span><br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return Action.SUCCESS;<br />
<span>&nbsp;&nbsp; </span>}<br />
}</span></p>
<p><span>看起来现在这些属性是类级别的，并不是线程安全的，会出现问题。其实在</span><span>Struts2</span><span>里并没有问题，因为每个请求过来的时候都会产生一个新的</span><span>Action</span><span>对象实例，它并没有和其他请求共享一个对象，所以不需要考虑线程安全问题。</span></p>
<p>&nbsp;</p>
<p><strong><span><span>四、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong><span>拦截器</span></strong><strong></strong></p>
<p>&nbsp;</p>
<p><span>Interceptor</span><span>（以下译为拦截器），在</span><span>AOP</span><span>（</span><span>Aspect-Oriented Programming</span><span>）中用于在某个方法或字段被访问之前，进行拦截然后在之前或之后加入某些操作。拦截是</span><span>AOP</span><span>的一种实现策略。</span></p>
<p><span>在</span><span>Webwork</span><span>的中文文档的解释为</span><span>——</span><span>拦截器是动态拦截</span><span>Action</span><span>调用的对象。它提供了一种机制可以使开发者定义在一个</span><span>action</span><span>执行的前后执行的代码，也可以在一个</span><span>action</span><span>执行前阻止其执行。同时也提供了一种可以提取</span><span>action</span><span>中可重用的部分的方式。</span></p>
<p><span>Struts1.x</span><span>的标准框架中不提供任何形式的拦截器，虽一个名为</span><span>SAIF</span><span>的附加项目则实现了这样的功能，但它的适用的范围还很有限。</span></p>
<p><span>拦截器是</span><span>Struts2</span><span>的一个强有力的工具，有许多功能（</span><span>feature</span><span>）都是构建于它之上，如</span><span><a href="http://www.blogjava.net/max/archive/2006/11/01/78536.html"><span><span>国际化</span></span></a></span><span>、</span><span><a href="http://www.blogjava.net/max/archive/2006/11/07/79602.html"><span><span>转换器</span></span></a></span><span>，</span><span><a href="http://www.blogjava.net/max/archive/2006/11/14/81106.html"><span><span>校验</span></span></a></span><span>等。谈到拦截器，还有一个流行的词</span><span>——</span><span>拦截器链（</span><span>Interceptor Chain</span><span>，在</span><span>Struts2</span><span>中称为拦截器栈</span><span>Interceptor Stack</span><span>）。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时，拦截器链中的拦截器就会按其之前定义的顺序被调用。</span></p>
<p><span>Struts 2</span><span>的拦截器实现相对比较简单。当请求到达</span><span>Struts2</span><span>的</span><span>ServletDispatcher</span><span>时，</span><span>Struts 2</span><span>会查找配置文件，并根据其配置实例化相对的拦截器对象，然后串成一个列表（</span><span>list</span><span>），最后一一地调用列表中的拦截器，如图</span><span>1</span><span>所示。</span></p>
<p>&nbsp;</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>&#8220;</span><span>框架（</span><span>framework</span><span>）</span><span>&#8221;</span><span>，可扩展性是不可缺少的，因为世上没有放之四海而皆准的东西。虽然，</span><span>Struts 2</span><span>为我们提供如此丰富的拦截器实现，但是这并不意味我们失去创建自定义拦截器的能力，恰恰相反，在</span><span>Struts 2</span><span>自定义拦截器是相当容易的一件事。</span></p>
<p>&nbsp;</p>
<p><strong><span><span>五、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </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>为了对</span><span>Struts2</span><span>和</span><span>Strtus1.x</span><span>进行全面的比较，让读者了解这两种框架各自的优缺点，以便于在自己的项目中，根据实际情况，选择合适的框架，对它们两者进行比较，总结了如下表分析比较。</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>类</span></strong></p>
            </td>
            <td>
            <p align="left"><span>Struts1.x</span><span>要求</span><span>Action</span><span>类要扩展自一个抽象基类。</span><span>Struts1.x</span><span>的一个共有的问题是面向抽象类编程而不是面向接口编程。</span></p>
            </td>
            <td width="272">
            <p align="left"><span>Struts2</span><span>的</span><span>Action</span><span>类实现了一个</span><span>Action</span><span>接口，连同其他接口一起来实现可选择和自定义的服务。</span><span>Struts2</span><span>提供一个名叫</span><span>ActionSupport</span><span>的基类来实现一般使用的接口。当然，</span><span>Action</span><span>接口不是必须的。任何使用</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>线程模型</span></strong></p>
            </td>
            <td>
            <p align="left"><span>Struts1.x Action</span><span>类是单例类，因为只有一个实例来控制所有的请求。单例类策略造成了一定的限制，并且给开发带来了额外的烦恼。</span><span>Action</span><span>资源必须是线程安全或者同步的。</span></p>
            </td>
            <td width="272">
            <p align="left"><span>Struts2 Action</span><span>对象为每一个请求都实例化对象，所以没有线程安全的问题。（实践中，</span><span>servlet</span><span>容器给每一个请求产生许多丟弃的对象，并且不会导致性能和垃圾回收问题）。</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>类依赖于</span><span>servlet API</span><span>，当</span><span>Action</span><span>被调用时，以</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>，允许</span><span>Action</span><span>被独立的测试。</span><span>Struts2</span><span>的</span><span>Action</span><span>可以访问最初的请求</span><span>(</span><span>如果需要的话</span><span>)</span><span>。但是，尽可能避免或排除其他元素直接访问</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>这使得测试要依赖于容器）。第三方的扩展，如</span><span>Struts TestCase</span><span>，提供了一套</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>一样，所有的</span><span>ActionForm</span><span>必须扩展基类。因为其他的</span><span>JavaBean</span><span>不能作为</span><span>ActionForm</span><span>使用，开发者经常创建多余的类来捕获输入。</span><span>DynaBeans</span><span>可以被用来作为替代</span><span>ActionForm</span><span>的类来创建。但是，开发者可能是在重新描述</span><span>(</span><span>创建</span><span>)</span><span>已经存在的</span><span>JavaBean</span><span>（仍然会导致有冗余的</span><span>javabean</span><span>）。</span></p>
            </td>
            <td width="272">
            <p align="left"><span>Struts2</span><span>直接使用</span><span>Action</span><span>属性作为输入属性，消除了对第二个输入对象的需求。输入属性可能是有自己</span><span>(</span><span>子</span><span>)</span><span>属性的</span><span>rich</span><span>对象类型。</span><span>Action</span><span>属性能够通过</span><span>web</span><span>页面上的</span><span>taglibs</span><span>访问。</span><span>Struts2</span><span>也支持</span><span>ActionForm</span><span>模式。</span><span>rich</span><span>对象类型，包括业务对象，能够用作输入</span><span>/</span><span>输出对象。这种</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>表达式语言</span></strong><strong><span> </span></strong></p>
            </td>
            <td>
            <p align="left"><span>Struts1.x</span><span>整合</span><span>JSTL</span><span>，所以它使用</span><span>JSTL</span><span>的表达式语言。表达式语言有基本的图形对象移动，但是对集合和索引属性的支持很弱。</span></p>
            </td>
            <td width="272">
            <p align="left"><span>Struts2</span><span>使用</span><span>JSTL</span><span>，但是也支持一个更强大和灵活的表达式语言－－</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>使用&#8220;</span><span>ValueStack</span><span>&#8221;技术，使</span><span>taglib</span><span>能够访问值而不需要把你的页面（</span><span>view</span><span>）和对象绑定起来。</span><span>ValueStack</span><span>策略允许通过一系列名称相同但类型不同的属性重用页面（</span><span>view</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>ActionForm</span><span>属性经常都是</span><span>String</span><span>。</span><span>Struts 1.x</span><span>使用</span><span>Commons-Beanutils</span><span>来进行类型转换。转换每一个类，而不是为每一个实例配置。</span></p>
            </td>
            <td width="272">
            <p align="left"><span>Struts2</span><span>使用</span><span>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>ActionForm</span><span>的</span><span>validate</span><span>方法中手动校验，或者通过</span><span>Commons Validator</span><span>的扩展来校验。同一个类可以有不同的校验内容，但不能校验子对象。</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>校验框架使用为属性类类型定义的校验和内容校验，来支持</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>（生命周期），但是模块中的所有</span><span>Action</span><span>必须共享相同的生命周期。</span></p>
            </td>
            <td width="272">
            <p align="left"><span>Struts2</span><span>支持通过拦截器堆栈（</span><span>Interceptor Stacks</span><span>）为每一个</span><span>Action</span><span>创建不同的生命周期。堆栈能够根据需要和不同的</span><span>Action</span><span>一起使用。</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong><span><span>六、<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span></strong><strong><span>结论</span></strong><strong><span><br />
<br />
</span></strong></p>
<p align="left"><span>前面已经简要介绍了</span><span>Struts2</span><span>的起源，并详细对比了</span><span>Struts2</span><span>和</span><span>Struts1.x</span><span>的差异，读者</span><span>应该对</span><span>Struts2</span><span>的基础有所了解了</span><span>——</span><span>包括高层的框架概念和基础的请求流程，并理解</span><span>Struts1.x</span><span>和</span><span>Struts2</span><span>两者之间在</span><span>Action</span><span>方面的差别，</span><span>Struts2</span><span>加强了对拦截器与</span><span>IoC</span><span>的支持，而在</span><span>Struts1.x</span><span>中，这些特性是很难想象的。</span></p>
<p align="left"><span>同时，读者应该明白：</span><span>Struts2</span><span>是</span><span>WebWork</span><span>的升级，而不是</span><span>Struts 1.x</span><span>的升级。虽然</span><span>Struts 2</span><span>提供了与</span><span>Struts1.x</span><span>的兼容，但已经不是</span><span>Struts1.x</span><span>的升级。对于已有</span><span>Struts1.x</span><span>开发经验的开发者而言，</span><span>Struts1.x</span><span>的开发经验对于</span><span>Struts2</span><span>并没有太大的帮助；相反，对于已经有</span><span>WebWork</span><span>开发经验的开发者而言，</span><span>WebWork</span><span>的开发经验对</span><span>Struts2</span><span>的开发将有很好的借鉴意义。</span></p>
<img src ="http://www.blogjava.net/conans/aggbug/213756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-07-09 19:12 <a href="http://www.blogjava.net/conans/articles/213756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的struts2项目性能调优三步曲 </title><link>http://www.blogjava.net/conans/articles/212190.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Wed, 02 Jul 2008 12:10:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/212190.html</guid><description><![CDATA[前一段时间有反映说是一个使用了struts2的生产系统的页面显示速度太慢。登录后发现确实如此，于是进行了一番性能调优的研究和测试。<br />
一，根据struts2官方的性能调优说明进行了一些参数的修改。<br />
http://struts.apache.org/2.x/docs/performance-tuning.html<br />
http://cwiki.apache.org/WW/performance-tuning.html<br />
<br />
Turn off logging and devMode.(关闭logging和Devmode)<br />
这个当然没问题，但是全部关闭logging不现实，我只是关闭了struts2相关package的logging<br />
<br />
Do not use interceptors you do not need.<br />
把struts.xml中不需要的interceptor统统删除<br />
<br />
Use the correct HTTP headers (Cache-Control &amp; Expires).<br />
不确定应该如何修改<br />
<br />
Copy the static content from the Struts 2 jar when using the Ajax theme (Dojo) or the Calendar tag.<br />
关于这点，后面会提到<br />
<br />
Create a freemarker.properties file in your WEB-INF/classes directory.<br />
照做<br />
<br />
Create the freemarker.properties file and add the following setting (or whatever value you deem fitting):<br />
template_update_delay=60000<br />
照做<br />
<br />
Enable Freemarker template caching<br />
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.<br />
照做<br />
<br />
进行上述修改后，发现页面打开的速度并没有明显的提高.<br />
<br />
二，此时我已经基本锁定网页打开速度慢的原因与ajax(或者说是dojo)有关。因为dojo的js库大概有450K左右，先尝试使用gzip压缩javascript，减小传输量，看能否加快页面的加载速度<br />
在Tomcat的server.xml的connector中添加如下配置，激活gzip功能<br />
&nbsp;compression="on"<br />
&nbsp;compressionMinSize="2048"<br />
&nbsp;noCompressionUserAgents="gozilla, traviata"<br />
&nbsp;compressableMimeType="text/html,text/xml,text/javascript,application/x-javascript,application/javascript"<br />
进行上述修改后，发现页面打开的速度还是没有明显的提高.<br />
<br />
三，经过上述两个实验，觉得应该是struts2所封闭的dojo的性能问题了。于是引入JQuery.<br />
JQuery的js文件最小是55K, gzip后应该更小，页面的响应速度明显改善（一个数量级以上的提高），主要原因在于与服务器交互的处理上极大地提升了效率。而且页面处理代码更加简洁明了。<br />
<br />
最后，我删除了所有的&lt;s:head theme="ajax"/&gt;和 &lt;s:head/&gt;(如果页面中加入&lt;s:head /&gt;，那么在Struts2生成的html中后包含dojo.js)，使用JQuery来完成所有的Ajax和javascript功能。<br />
 <img src ="http://www.blogjava.net/conans/aggbug/212190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-07-02 20:10 <a href="http://www.blogjava.net/conans/articles/212190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2(Webwork2)一些实战开发技巧</title><link>http://www.blogjava.net/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.blogjava.net/conans/articles/210934.html</guid><description><![CDATA[<span style="font-size: medium; color: #ff6600">一． </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: 宋体">这一招在一些特殊的场合下非常管用．比如说，用户在第一个页面，选择了某个实体其中要显示出来的几个属性，那个这个时候用反射是非常不错的选择，少了大量</span> if <span style="font-family: 宋体">语句：</span> </p>
<div>
<div>
<div>Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>package&nbsp;com.leo.util; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>import&nbsp;java.lang.reflect.Method; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;</li>
    <li>public&nbsp;class&nbsp;HelloWorldBean&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;word; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;name; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;getName()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;name; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;setName(String&nbsp;name)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name&nbsp;=&nbsp;name; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;getWord()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;word; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;setWord(String&nbsp;word)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.word&nbsp;=&nbsp;word; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;HelloWorldBean()&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;=&nbsp;"superleo"; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;word&nbsp;=&nbsp;"Hello&nbsp;World!!!"; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;getProperty(String&nbsp;name)&nbsp;throws&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(name&nbsp;!=&nbsp;null&nbsp;&amp;&amp;&nbsp;!name.equals(""))&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Character&nbsp;ch&nbsp;=&nbsp;name.charAt(0); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;=&nbsp;Character.toUpperCase(ch)&nbsp;+&nbsp;name.substring(1,&nbsp;name.length()); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;cls&nbsp;=&nbsp;Class.forName("com.leo.util.HelloWorldBean"); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;meth&nbsp;=&nbsp;cls.getMethod("get"&nbsp;+&nbsp;name,&nbsp;null); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;retobj&nbsp;=&nbsp;meth.invoke(this,&nbsp;null); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(String)&nbsp;retobj; &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;RuntimeException(); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HelloWorldBean&nbsp;bean&nbsp;=&nbsp;new&nbsp;HelloWorldBean(); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean.setName("superleo"); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean.setWord("name"); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bean.getProperty("name")); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bean.getProperty("word")); &nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</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 &amp;&amp; !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: 宋体">，假设我们在</span> HelloAction <span style="font-family: 宋体">使用了这个</span> HelloWorldBean <span style="font-family: 宋体">，并且运行后，跳转到相应页面，你可以这样去取</span> HelloWorldBean <span style="font-family: 宋体">的</span> word <span style="font-family: 宋体">和</span> name <span style="font-family: 宋体">属性了：</span> </p>
<div>
<div>
<div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>&lt;%@&nbsp;page&nbsp;language="java"&nbsp;import="java.util.*"&nbsp;pageEncoding="UTF-8"%&gt;&nbsp;&nbsp;</li>
    <li>&lt;%@&nbsp;taglib&nbsp;prefix="s"&nbsp;uri="/struts-tags"%&gt;&nbsp;&nbsp;</span></li>
    <li>&lt;html&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;body&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h3&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;正常方法：&lt;s:property&nbsp;value="helloWorld.name"&nbsp;/&gt;&nbsp;&lt;br&nbsp;/&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;s:property&nbsp;value="helloWorld.word"&nbsp;/&gt;&nbsp;&lt;br&nbsp;/&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;反射方法：&lt;s:property&nbsp;value="helloWorld.getProperty('name')"&nbsp;/&gt;&nbsp;&lt;br&nbsp;/&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;s:property&nbsp;value="helloWorld.getProperty('word')"&nbsp;/&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h3&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/body&gt;&nbsp;&nbsp;</span></li>
    <li>&lt;/html&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" name="code">&lt;%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%&gt;
&lt;%@ taglib prefix="s" uri="/struts-tags"%&gt;
&lt;html&gt;
&lt;body&gt;
&lt;h3&gt;
正常方法：&lt;s:property value="helloWorld.name" /&gt; &lt;br /&gt;
&lt;s:property value="helloWorld.word" /&gt; &lt;br /&gt;
反射方法：&lt;s:property value="helloWorld.getProperty('name')" /&gt; &lt;br /&gt;
&lt;s:property value="helloWorld.getProperty('word')" /&gt;
&lt;/h3&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><span style="font-family: 宋体">对于公共属性，还可以将此方法移到父类。</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> <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: 宋体">这对显示</span> Hibernate 多表连接的查询结果非常管用。 </p>
<p><span style="font-family: 宋体">以前，在使用</span> Hibernate <span style="font-family: 宋体">的时候，因为涉及到多个表查询是很普遍的，每个表取一些字段，想显示在页面，比较好的办法是新建一个</span> VO <span style="font-family: 宋体">对象，专门用来显示查询的结果．但缺点就是，如果这样的查询很多，</span> VO <span style="font-family: 宋体">类会越来越多（如果不断的往一个</span> VO <span style="font-family: 宋体">增加字段的话，那么这个</span> VO <span style="font-family: 宋体">也越来越大，构造函数会特别夸张），咱们来看一个例子：</span> </p>
<div>
<div>
<div>Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>List&nbsp;list&nbsp;=&nbsp;session.createQuery("select&nbsp;new&nbsp;MyVO(a.name,&nbsp;b.name,&nbsp;c.id)&nbsp;from&nbsp;.....").list();&nbsp;&nbsp;</li>
</ol>
</div>
<p><span style="font-family: 宋体">这样返回的</span> List <span style="font-family: 宋体">直接就可以在页面上用</span> iterator <span style="font-family: 宋体">标签迭代了，但假如现在要取</span> 10 <span style="font-family: 宋体">呢？不仅</span> HQL <span style="font-family: 宋体">语句要修改，而且</span> MyVO <span style="font-family: 宋体">也要修改．下面是一种更好的做法：</span> </p>
<div>
<div>
<div>Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>List&nbsp;list&nbsp;=&nbsp;session.createQuery("select&nbsp;new&nbsp;Map(a.name&nbsp;as&nbsp;fristName,&nbsp;b.name&nbsp;as&nbsp;secondName,&nbsp;c.id&nbsp;as&nbsp;id&nbsp;from&nbsp;.....").list();&nbsp;&nbsp;</li>
</ol>
</div>
<p><span style="font-family: 宋体">这里改用</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: 宋体">&#8221;重新启了一个别名，这个非常重要，否则在页面显示时，很费劲．</span> </p>
<p><span style="font-family: 宋体">现在来看页面调用代码：</span> </p>
<div>
<div>
<div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>&lt;s:iterator&nbsp;value="list"&nbsp;id="maps"&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&nbsp;class="row1"&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="checkbox"&nbsp;name="ids"&nbsp;value="&lt;s:property&nbsp;value="#maps.get('id')"&nbsp;/&gt;"&nbsp;/&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;align="center"&gt;&lt;s:property&nbsp;value="#maps.get('fristName')"&nbsp;/&gt;&lt;/td&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;align="center"&gt;&lt;s:property&nbsp;value="#maps.get('secondName')"&nbsp;/&gt;&lt;/td&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/s:iterator&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" name="code">&lt;s:iterator value="list" id="maps"&gt;
&lt;tr class="row1"&gt;
&lt;input type="checkbox" name="ids" value="&lt;s:property value="#maps.get('id')" /&gt;" /&gt;
&lt;td align="center"&gt;&lt;s:property value="#maps.get('fristName')" /&gt;&lt;/td&gt;
&lt;td align="center"&gt;&lt;s:property value="#maps.get('secondName')" /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/s:iterator&gt;
</pre>
&nbsp;
<p><span style="font-family: 宋体">注意上面的页面中</span> Map <span style="font-family: 宋体">的取值就是当时</span> hql <span style="font-family: 宋体">语句中&#8220;</span> as <span style="font-family: 宋体">&#8221;后的别名．</span> </p>
<p><span style="font-family: 宋体">虽然相对于以往的</span> JSTL <span style="font-family: 宋体">来说，要写的标签代码更多了，但强大的</span> OGNL <span style="font-family: 宋体">表达式也让你在视图层拥有更强大的灵活性与扩展性．</span> </p>
<p><span style="font-family: 宋体">顺序无关，如果你使用了</span> <span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'">select new List(...)</span> <span style="font-family: 宋体">也能达到类似效果，但因为</span> List <span style="font-family: 宋体">是有序的，所以在页面显示非常不灵活，不推荐使用．</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: 宋体">这个问题具体原因不明，先看下面一段代码：</span> </p>
<div>
<div>
<div>Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>&lt;s:if&nbsp;test="user.name&nbsp;==&nbsp;'程序'"&gt; &nbsp;&nbsp;</li>
    <li>...&nbsp;&nbsp;</li>
</ol>
</div>
<pre style="display: none" name="code">&lt;s:if test="user.name == '程序'"&gt;
...
</pre>
<p><span style="font-family: 宋体">这样就算</span> user.name <span style="font-family: 宋体">等于&#8220;程序&#8221;也是无法通过的，需要修改成以下代码：</span> </p>
<div>
<div>
<div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>&lt;s:if&nbsp;test="user.name&nbsp;==&nbsp;"'程序"'"&gt;&nbsp;&nbsp;</li>
    <li>...&nbsp;&nbsp;</li>
</ol>
</div>
<pre style="display: none" name="code">&lt;s:if test="user.name == "'程序"'"&gt;
...
</pre>
<p><span style="font-family: 宋体">如果&#8220;程序&#8221;是你系统的一个常量，更推荐的作法是：</span> </p>
<div>
<div>
<div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>&lt;s:if&nbsp;test="user.name&nbsp;==&nbsp;@com.leo.util.Constants@TYPE&nbsp;"&gt;&nbsp;&nbsp;</li>
    <li>...&nbsp;&nbsp;</li>
</ol>
</div>
<pre style="display: none" name="code">&lt;s:if test="user.name == @com.leo.util.Constants@TYPE "&gt;
...
</pre>
&nbsp;
<p><span style="font-family: 宋体">我不知道原因是不是因为版本问题？希望有知道的，回复一下．</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: 宋体">这个也很常用，相信很多人都轻车熟路，那我们来回顾一下。假设</span> lists <span style="font-family: 宋体">装的都是</span> Group <span style="font-family: 宋体">对象，</span> Group <span style="font-family: 宋体">持有一个</span> List&lt;User&gt; <span style="font-family: 宋体">那个我们接下来可以：</span> </p>
<div>
<div>
<div>Html代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://superleo.javaeye.com/blog/199543#"><img alt="复制代码" src="http://superleo.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol>
    <li>&lt;ww:iterator&nbsp;value="lists"&nbsp;id="top"&gt;&nbsp;&nbsp;</li>
    <li>&lt;ww:iterator&nbsp;value="users"&nbsp;id="sub"&gt;&nbsp;&nbsp;</span></li>
    <li>组名：&lt;s:property&nbsp;value="#top.name"&nbsp;/&gt;，成员名：&lt;s:property&nbsp;value="#sub.name"&nbsp;/&gt;&nbsp;&nbsp;</span></li>
    <li>&lt;/ww:iterator&gt;&nbsp;&nbsp;</span></li>
    <li>&nbsp;&nbsp;应该组总数：&lt;s:property&nbsp;value="users.size"&nbsp;/&gt;&nbsp;&nbsp;</span></li>
    <li>&lt;/ww:iterator&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" name="code">&lt;ww:iterator value="lists" id="top"&gt;
&lt;ww:iterator value="users" id="sub"&gt;
组名：&lt;s:property value="#top.name" /&gt;，成员名：&lt;s:property value="#sub.name" /&gt;
&lt;/ww:iterator&gt;
应该组总数：&lt;s:property value="users.size" /&gt;
&lt;/ww:iterator&gt;
</pre>
<p><span style="font-family: 宋体">上面的写法有很多种，但效果都是一样的，有兴趣可以多看看</span> OGNL <span style="font-family: 宋体">。</span> </p>
<p>还有一些没有及时整理好，下次统一再给大家分享一下．</p>
<img src ="http://www.blogjava.net/conans/aggbug/210934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-06-26 19:55 <a href="http://www.blogjava.net/conans/articles/210934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2利用stream直接输出Excel </title><link>http://www.blogjava.net/conans/articles/210375.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Tue, 24 Jun 2008 11:41:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/210375.html</guid><description><![CDATA[<p>在利用网页展示查询结果，经常会遇到要求导出成Excel的需求。采用这种方法可以定制输出的格式和内容（还不支持合并单元格和公式），生成真正的Excel格式（不是csv）的Excel。<br />
一、struts.xml<br />
&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;!DOCTYPE struts PUBLIC<br />
&nbsp;&nbsp;&nbsp; "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"<br />
&nbsp;&nbsp;&nbsp; "http://struts.apache.org/dtds/struts-2.0.dtd"&gt;<br />
&nbsp;&nbsp; <br />
&lt;struts&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;constant name="struts.i18n.encoding" value="UTF-8"/&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;package name="demo" extends="struts-default"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action name="excel" method="execute" class="demo.ExcelAction"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;result name="excel" type="stream"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="contentType"&gt;application/vnd.ms-excel&lt;/param&gt;&nbsp;&nbsp;&nbsp; &lt;!-- 注意这里的ContentType --&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="inputName"&gt;excelStream&lt;/param&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 这里需要和Action里的变量名一致 --&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="contentDisposition"&gt;filename="standard.xls"&lt;/param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="bufferSize"&gt;1024&lt;/param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/result&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/action&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/package&gt;<br />
&lt;/struts&gt;</p>
<p>二、Struts2的 Action</p>
<p>package demo;<br />
public class ExcelAction {<br />
&nbsp;&nbsp;&nbsp; private InputStream excelStream; // 需要生成getter和setter</p>
<p>&nbsp;&nbsp;&nbsp; public String execute() throws Exception {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer excelBuf = new StringBuffer();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; excelBuf.append("BookName").append("\t").append("Year").append("\t").append("author").append("\n");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; excelBuf.append("Thinking in Java").append("\t").append("2001").append("\t").append("Eckel").append("\n");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; excelBuf.append("Spring in action").append("\t").append("2005").append("\t").append("Rod").append("\n");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String excelString = excelBuf.toString();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.debug("result excel String: " + excelString);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; excelStream = new ByteArrayInputStream(excelString.getBytes(), 0, excelString.length());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "excel";<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; // getter and setter<br />
&nbsp;&nbsp;&nbsp; ...<br />
}</p>
<p>三、Jsp页面</p>
<p>&lt;%@ taglib prefix="s" uri="/struts-tags"%&gt;<br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;<br />
&lt;html&gt;<br />
&nbsp;&lt;head&gt;<br />
&nbsp; &lt;s:head /&gt;<br />
&nbsp;&lt;/head&gt;</p>
<p>&nbsp;&lt;body&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;s:form action="" method="post"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;s:submit key="button.submit"/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/s:form&gt;<br />
&nbsp;&lt;/body&gt;<br />
&lt;/html&gt;</p>
<img src ="http://www.blogjava.net/conans/aggbug/210375.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-06-24 19:41 <a href="http://www.blogjava.net/conans/articles/210375.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再谈Struts2图片按钮标签的使用：图片根路径无法取得，使用传统方法 </title><link>http://www.blogjava.net/conans/articles/209893.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Sun, 22 Jun 2008 11:07:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/209893.html</guid><description><![CDATA[在前几天写了一个图片按钮的使用方法如下&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;s:submit type="image" value="user_doDelete.action" label="删除指定用户" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;src="myroot/images/btn/btn_delete.jpg" cssClass="button_image"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;onclick="return CheckSelectForDelete();" action="user" method="doDelete"/&gt;&lt;/td&gt;<br />
&nbsp;&nbsp;在这里面的src有个问题就是必须带着项目的root，如上例中的myroot，一旦项目的访问路径变了，就麻烦了，显示不出图片来了，传统的方法是加&lt;%=request.getContextPath()%&gt;,但是在Struts2标签中不能这么引用。<br />
在2.0.11的时候还可以用<br />
&nbsp;&nbsp;&nbsp;&nbsp;${pageContext.request.contextPath},但是必须使用theme=ajax，我还不想用，<br />
在2.1.2的时候ajax从标准标签库中分出去了，想用也不行了。<br />
现在只能不用Submit标签了，但是还想用它的一些功能，主要就是那个action,method了，通过分析生成的代码总结新的方法如下：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="image" alt="删除指定用户" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src="&lt;%=request.getContextPath() %&gt;/images/btn/btn_del.gif" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id="doDelete" name="action:user!doDelete"&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="button_image" onclick="return CheckSelectForDelete();"/&gt;<br />
无他，就是把标签中的action和method合并起来，加到name中去了其它的照旧。
<img src ="http://www.blogjava.net/conans/aggbug/209893.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-06-22 19:07 <a href="http://www.blogjava.net/conans/articles/209893.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring和struts2的整合</title><link>http://www.blogjava.net/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.blogjava.net/conans/articles/209888.html</guid><description><![CDATA[<table style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt">
            <div class="cnt">在Struts2中整合Spring的IoC支持是一件十分简单的事情。让我们一步一步来实现：<br />
            1）复制struts2-spring-plugin-x-x-x.jar和相应的spring.jar到/WEB-INF/lib目录下。<br />
            2）在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文件中进行常量配置<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>&lt;struts&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;constant name="struts.objectFactory" value="spring" /&gt;
            &lt;/struts&gt;
            </pre>
            </div>
            </div>
            3）配置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>&lt;listener&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener<span class="code-tag">&lt;/listener-class&gt;
            &lt;/listener&gt;
            </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>&lt;?xml version=<span class="code-quote">"1.0"</span> encoding="UTF-8"?&gt;
            &lt;!DOCTYPE beans PUBLIC
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "-//SPRING//DTD BEAN//EN"
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
            &lt;beans default-autowire="byName"&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="personManager" class="com.acme.PersonManager"/&gt;
            &lt;/beans&gt;
            </pre>
            </div>
            </div>
            当然你也可以拥有更多的Spring配置文件。在web.xml中进行下列设置，从而使Spring的ApplicationContext通过匹配所给定模式的文件来初始化对象<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>&lt;!-- 用来定位Spring XML文件的上下文配置 --&gt;
            &lt;context-param&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;contextConfigLocation<span class="code-tag">&lt;/param-name&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml&lt;/param-value&gt;
            &lt;/context-param&gt;
            </span>
            </pre>
            </div>
            </div>
            4）修改你的Struts配置文件<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>&lt;!DOCTYPE struts PUBLIC
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "http://struts.apache.org/dtds/struts-2.0.dtd"&gt;
            &lt;struts&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;include file="struts-default.xml"/&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;package name="default" extends="struts-default"&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action name="foo" class="com.acme.Foo"&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;result&gt;foo.ftl&lt;/result&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/action&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/package&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;package name="secure" namespace="/secure" extends="default"&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action name="bar" class="bar"&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;result&gt;bar.ftl&lt;/result&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/action&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/package&gt;
            &lt;/struts&gt;
            </pre>
            </div>
            </div>
            默认情况下，Spring从下面的文件中寻找为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>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
            &lt;!DOCTYPE beans PUBLIC
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "-//SPRING//DTD BEAN//EN"
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
            &lt;beans default-autowire="byName"&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="bar" class="com.my.BarClass" singleton="false"/&gt;
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...
            &lt;/beans&gt;
            </pre>
            </div>
            </div>
            5）好了，现在你的Struts2和Spring就能正常的一起工作了。有几个配置技术点需要详细说明下：装配模式。你可以通过设置修改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的名字匹配，如果匹配就自动装配。这是<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的属性的类型，在Spring注册的bean中查找，如果相同就自动装配。这需要你在Spring中仅注册了一个此类型的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>
            是否使用类缓存。你可以通过设置修改struts.properties中下列属性的值来改变是否使用Spring自身的类缓存机制。可以设定的值为true或false，默认为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.blogjava.net/conans/aggbug/209888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-06-22 19:00 <a href="http://www.blogjava.net/conans/articles/209888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2中的单Form多图片提交按钮(Submit)的使用 </title><link>http://www.blogjava.net/conans/articles/209883.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Sun, 22 Jun 2008 10:55:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/209883.html</guid><description><![CDATA[<p>在Struts2里面一个Form中如果有多个提交按钮，比如添加，更新，保存等，<br />
这些按钮使用一个Action，调用不同的方法，并且在调用前要执行一个JavaScript的检查。<br />
怎么用这个提交按钮？<br />
经过总结如下：<br />
先在form标签头指定Action的命名空间：<br />
&lt;s:form namespace="/system/usermanager" &gt;<br />
然后如下调用：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;s:submit type="image" id="FIND" value="FIND" label="按指定条件检索用户信息" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src="/issframe/images/btn/btn_find.jpg" cssClass="button_image"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; onclick="return CheckInputForRequired();" action="user" method="doSearch"/&gt;<br />
上面是一个图片提交按钮的示例，因为一般在项目中都是使用图片按钮:)<br />
在onclick中执行javascript，记得不要漏掉return。<br />
action就是你要调用的Action在Struts2的配置文件中定义的那个name<br />
例如：&lt;action name="user_*" class="com.system.action.ManagerUserAction" method="{1}"&gt;</p>
注意不包括通配符("_"或者"!"等)。<br />
mothed就是Action类中定义的对应的方法了。
<img src ="http://www.blogjava.net/conans/aggbug/209883.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-06-22 18:55 <a href="http://www.blogjava.net/conans/articles/209883.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>strust2实践总结</title><link>http://www.blogjava.net/conans/articles/209884.html</link><dc:creator>CONAN</dc:creator><author>CONAN</author><pubDate>Sun, 22 Jun 2008 10:55:00 GMT</pubDate><guid>http://www.blogjava.net/conans/articles/209884.html</guid><description><![CDATA[1：在action中定义的变量，在jsp页面中显示用：&lt;s:property value="变量名" /&gt; <br />
<br />
2：在页面中实现自动增加的序号用iterator的statuts的index属性 eg： <br />
<br />
&lt;s:iterator value="#request.inOutAccountList" id="data" status="listStat"&gt; <br />
<br />
&lt;s:property value="#listStat.index+1"/&gt; <br />
<br />
&lt;/s:iterator&gt; <br />
<br />
3:在action类中取得request和session对象的方法 <br />
<br />
Map session = ActionContext.getContext().getSession(); <br />
HttpServletRequest request = ServletActionContext.getRequest (); <br />
<br />
设置它们的值的方法 <br />
<br />
session.put("operation", "add"); <br />
request.setAttribute("name", name); <br />
<br />
页面中取得它们的值： <br />
<br />
&lt;s:property value="#session.operation"/&gt; <br />
&lt;s:property value="#request.name"/&gt; <br />
<br />
4:页面中奇偶行样式不一样的控制方法： <br />
<br />
&lt;tr class="&lt;s:if test='#listStat.odd == true '&gt;tableStyle-tr1&lt;/s:if&gt;&lt;s:else&gt;tableStyle-tr2&lt;/s:else&gt;" &gt; <br />
<br />
5:单选框和复选框的使用方法 <br />
<br />
1):可以设置默认选中值，注意list的值的设置，通过这种方式使key和value不一样，这种方法比较常用(checkboxlist or radio) <br />
<br />
&lt;s:radio name="uncarInsPolicy.policyStateCode" <br />
list="#{'5':'通过' , '2':'不通过'}" <br />
listKey="key" <br />
listValue="value" <br />
value='5' <br />
/&gt; <br />
<br />
2):这里的key和value的值是一样的(checkboxlist or radio) <br />
<br />
&lt;s:checkboxlist <br />
list="{'Red', 'Blue', 'Green'}" <br />
name="favoriteColor"/&gt; <br />
<br />
6:struts2 中的标签会生成类似由&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;构成的字串（具体什么标签生成什么，可以查看生成后的页面的源代码）如果不限制这些多余代码的生成，页面将变得无法控制，所以一般我们是不希望它生成多余的代码的，具体的设置方法如果，在struts.xml中统一配置 <br />
&lt;constant name="struts.ui.theme" value="simple"/&gt;加上该句即可 <br />
也可以通过在页面中将tag的theme属性设为"simple"取消其默认的表格布局 <br />
不过最好是：自定义一个theme，并将其设为默认应用到整个站点，如此一来就可以得到统一的站点风格 <br />
<br />
7：jsp页面中格式化日期的方法 <br />
<br />
&lt;s:date name="unCarInsModificationInfo.createTime" format="yyyy-MM-dd" nice="false"/&gt;这样就可以将日期格式化为yyyy－MM－dd的形式 <br />
<br />
8：默认情况下，当请求action发生时，Struts运行时（Runtime）根据struts.xml里的Action映射集(Mapping)，实例化action对应的类，并调用其execute方法。当然，我们可以通过以下两种方法改变这种默认调用 <br />
<br />
1）在classes/sturts.xml中新建Action，并指明其调用的方法 <br />
比如想调用action类中的 <br />
<br />
public String aliasAction() { <br />
message ="自定义Action调用方法"; <br />
return SUCCESS; <br />
} <br />
则在classes/sturts.xml中加入下面代码： <br />
&lt;action name="AliasHelloWorld" class="tutorial.HelloWorld" method="aliasAction"&gt; <br />
&lt;result&gt;/HelloWorld.jsp&lt;/result&gt; <br />
&lt;/action&gt; <br />
既可用action名调用该方法了 <br />
<br />
2）（比较常用） <br />
<br />
访问Action时，在Action名后加上&#8220;!xxx&#8221;（xxx为方法名）。 <br />
<br />
9：Struts 2.0有两个配置文件，struts.xml和struts.properties都是放在WEB-INF/classes/下。 <br />
struts.xml用于应用程序相关的配置 <br />
struts.properties用于Struts 2.0的运行时（Runtime）的配置 <br />
<br />
10:在action类中取得web下某一文件夹物理路径（绝对路径）的方法 <br />
filePath = ServletActionContext.getServletContext().getRealPath("/upLoadFiles") <br />
<br />
11：要想返回的页面不是一个直接JSP页面而是要先通过返回action中的方法读取相应的数据再返回到jsp页面，有两种方法 <br />
<br />
1）在struts.xml中这么设置 <br />
<br />
&lt;result name="list" type="redirect-action"&gt;sysmanage/UserBaseInfoAction!findUserBaseInfo.action&lt;/result&gt; <br />
<br />
2）在action中返回时直接调用这个方法即可 <br />
<br />
return findList（）； <br />
<br />
12：设置checkboxlist中默认值的方法 <br />
<br />
&lt;s:checkboxlist name="skills1" <br />
="Skills 1" <br />
list="{ 'Java', '.Net', 'RoR', 'PHP' }" <br />
value="{ 'Java', '.Net' }" /&gt; <br />
&lt;s:checkboxlist name="skills2" <br />
label="Skills 2" <br />
list="#{ 1:'Java', 2: '.Net', 3: 'RoR', 4: 'PHP' }" <br />
listKey="key" <br />
listValue="value" <br />
value="{ 1, 2, 3 }"/&gt; <br />
<br />
13：二级级连下拉框 <br />
<br />
&lt;s:set name="foobar" <br />
value="#{'Java': {'Spring', 'Hibernate', 'Struts 2'}, '.Net': {'Linq', ' ASP.NET 2.0'}, 'Database': {'Oracle', 'SQL Server', 'DB2', 'MySQL'}}" /&gt; <br />
&lt;s:doubleselect list="#foobar.keySet()" <br />
doubleName="technology" <br />
doubleList="#foobar[top]" <br />
label="Technology" /&gt; 
<img src ="http://www.blogjava.net/conans/aggbug/209884.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/conans/" target="_blank">CONAN</a> 2008-06-22 18:55 <a href="http://www.blogjava.net/conans/articles/209884.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>