﻿<?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-All in Blending-随笔分类-Struts</title><link>http://www.blogjava.net/javaniu/category/13924.html</link><description>Blending</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:00:07 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:00:07 GMT</pubDate><ttl>60</ttl><item><title>WebWork 学习笔记（六） </title><link>http://www.blogjava.net/javaniu/archive/2006/08/10/62851.html</link><dc:creator>Gary Niu</dc:creator><author>Gary Niu</author><pubDate>Thu, 10 Aug 2006 12:47:00 GMT</pubDate><guid>http://www.blogjava.net/javaniu/archive/2006/08/10/62851.html</guid><wfw:comment>http://www.blogjava.net/javaniu/comments/62851.html</wfw:comment><comments>http://www.blogjava.net/javaniu/archive/2006/08/10/62851.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaniu/comments/commentRss/62851.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaniu/services/trackbacks/62851.html</trackback:ping><description><![CDATA[
		<span id="BlogViewId">
				<div>
						<div>
								<p>Remote Form(远程表单)最大的特点就是可以不用刷新页面而进行提交.</p>
								<p>
										<strong>wiki翻译如下</strong>: </p>
								<div class="wiki-content">
										<p>远程表单允许提交表单但是不刷新页面. 表单提交的结果可以设置为任何页面上的元素的内容.</p>
										<h3>
												<a name="RemoteForm-Attributes">属性</a>
										</h3>
										<p>为了让表单具有ajax功能, 必须使用ww:form, 指定模板主题为 "ajax". 另外, 必须配合 ww:submit 才能一起工作. ww:submit组件相关的AJAX属性包括:</p>
										<table class="confluenceTable">
												<tbody>
														<tr>
																<th class="confluenceTh">名称</th>
																<th class="confluenceTh">描述</th>
														</tr>
														<tr>
																<td class="confluenceTd">resultDivId (required)</td>
																<td class="confluenceTd">要存放结果的Html元素的id (可以是表单的id或者页面上的任何id)</td>
														</tr>
														<tr>
																<td class="confluenceTd">notifyTopics</td>
																<td class="confluenceTd">表单提交后,对哪些Topic进行事件激发,可以多个,用逗号分割</td>
														</tr>
														<tr>
																<td class="confluenceTd">afterLoading</td>
																<td class="confluenceTd">表单提交后要执行的Javascript代码</td>
														</tr>
												</tbody>
										</table>
								</div>
								<p> </p>
								<p>Remote Form是由Form和Submit标签协作运行的,<strong>它有三个特性:</strong><br />1.可以用提交后获取的内容替换某个id元素的内容<br />2.提交后可以触发事件<br />3.提交后可以执行一段JavaScript</p>
								<p>我们来看第<strong>一个例子:</strong></p>
								<p>
								</p>
								<table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0">
										<tbody>
												<tr>
														<td>&lt;div id=’two’ style="border: 1px solid yellow;"&gt;&lt;b&gt;initial content&lt;/b&gt;&lt;/div&gt;<br />&lt;ww:form   id=’theForm2’    cssStyle="border: 1px solid green;"<br />        action=’/AjaxRemoteForm.action’    method=’post’     theme="ajax"&gt;<br />    &lt;input type=’text’ name=’data’ value=’WebWork User’&gt;<br />    &lt;ww:submit value="GO2" theme="ajax" resultDivId="two" /&gt;<br />&lt;/ww:form&gt; </td>
												</tr>
										</tbody>
								</table>
								<p>可以看到,form必须使用ajax模板,submit标签也是使用ajax模板(或者具有ajax模板功能的自定义模板),只有使用ajax模板,才具有提交不刷新页面的效果,否则就是普通的表单提交了.</p>
								<p>form没有特殊的属性,主要是submit的属性resultDivId,指定目标id为"two",这个id可以是页面上的任何一个元素的id,当然也可以是表单本身.点击提交按钮后,id为"two"的元素的内容被替换为表单提交的结果内容.</p>
								<p>另外,submit还有另外2个属性,其中之一是<strong>onLoadJS</strong>,如果在submit的属性中指定onLoadJS,例如</p>
								<p>&lt;ww:submit value="GO4" theme="ajax" onLoadJS="alert(’form submitted’);"/&gt;</p>
								<p>则表单提交后会执行相应的JavaScript代码.</p>
								<p>另外一个属性是<strong>notifyTopics,可以触发Topic为指定属性的事件</strong>,例如</p>
								<p>
								</p>
								<table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0">
										<tbody>
												<tr>
														<td>&lt;ww:div id="once" theme="ajax" cssStyle="border: 1px solid yellow;"<br />    href="/AjaxTest.action" delay="1000"<br />    listenTopics="scud1" loadingText="loading..."&gt;Initial Content&lt;/ww:div&gt;<br />&lt;br&gt;&lt;br&gt;<br />&lt;ww:form   id=’theForm2’  cssStyle="border: 1px solid green;"<br />        action=’/AjaxRemoteForm.action’   method=’post’   theme="ajax"&gt;<br />    &lt;input type=’text’ name=’data’ value=’WebWork User’&gt;<br />    &lt;ww:submit value="GO2" theme="ajax" notifyTopics="scud1" /&gt;<br />&lt;/ww:form&gt; </td>
												</tr>
										</tbody>
								</table>
								<br />
								<br />提交表单将会触发监听Topic为"scud1"的控件的事件,它们会重载自身的内容.可以参考前面Div 标签的说明.<p> </p><p><strong>补</strong>:2005-9-16: remote form 最新cvs上的版本已经可以在ie上运行.<br /><br /><span id="BlogViewId"></span></p><h2>开启Spring组合</h2><p> 在WebWork中开启Spring支持是非常简单的,把最新版本的Spring的jar放到你的classpath中,然后在webwork.properties里面设置如下选项:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>webwork.objectFactory = spring </td></tr></tbody></table><p>此时使用的类是: <strong>com.opensymphony.webwork.spring.WebWorkSpringObjectFactory</strong>,也可以指定为其他SpringObjectFactory.</p><p>缺省Spring的装配策略是 by name,可以修改webwork.properties改为其他方式,例如type,name,auto等</p><p><br /> <br /> 这时所有对象都首先来用Spring来创建.如果Spring没有创建这些对象,WebWork会自己创建这些对象. 然后,你需要在web.xml里面设置Spring的listener:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>  &lt;listener&gt;<br />      &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;<br />  &lt;/listener&gt; </td></tr></tbody></table><h2>Spring配置示例</h2><p> 这时,你可以添加一个标准的Spring配置文件:WEB-INF/applicationContext.xml,举例如下:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td><pre class="code-xml"><span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?&gt;</span><span class="code-tag">&lt;!DOCTYPE beans PUBLIC <span class="code-quote">"-//SPRING//DTD BEAN//EN"</span><span class="code-quote">"http://www.springframework.org/dtd/spring-beans.dtd"</span>&gt;</span><span class="code-tag">&lt;beans default-autowire=<span class="code-quote">"autodetect"</span>&gt;</span><span class="code-tag">&lt;bean id=<span class="code-quote">"personManager"</span> class=<span class="code-quote">"com.acme.PersonManager"</span>/&gt;</span>
            ...
            <span class="code-tag">&lt;/beans&gt;</span></pre></td></tr></tbody></table><br /><h2>使用Spring初始化Action </h2><p>一般来说,你在xwork.xml里面为每个Action指定类.当使用SpringObjectFactory的时候(如果按照上面的方法配置了), 这意味着WebWork会首先请求Spring创建这个Action并按照缺省的自动装配策略设定依赖的属性.SpringObjectFactory还会调用所有bean的处理器来处理事务,安全等方面的代理机制.不需要特殊的设置Spring就可以自动确定.对大多数的应用,这会配置你的Action 所需的服务和依赖,来达到你的所有要求.</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> <img height="16" alt="" src="http://wiki.opensymphony.com/images/icons/emoticons/check.gif" width="16" align="absMiddle" border="0" />我们<strong>强烈推荐</strong>你找到一种声明的方法来让spring知道该为你的Action提供什么.这包括把你的Action里的属性命名为在Spring配子文件里定义的Bean 的名字一致,这样可以实现基于名字的自动装配,还可以使用JDK5的标注来声明事务和安全层需要.如果你能找到方法让Spring知道你的Action需要什么而且不需要在applicationContext.xml里面进行外部配置的话,你就不需要在2个地方维护配置了.</td></tr></tbody></table><br /> <p>然而,有时你可能想要Spring来完全管理Bean.这是有实际意义的,例如,你如果想对你的Bean使用AOP或者Spring的相关技术,例如Acegi.为了达到这个目的,你仅仅要做的就是在xwork.xml里移除你的WebWork Action的类的属性,然后在applicationContext.xml里面配置这个Bean.<br /> <br /> 你的xwork.xml文件里面的action应该这样定义: </p><div class="code"><div class="codeContent"><pre class="code-xml"><font color="#000000"><span class="code-tag">&lt;!DOCTYPE xwork PUBLIC <span class="code-quote">"-//OpenSymphony Group//XWork 1.0//EN"</span><span class="code-quote">"http://www.opensymphony.com/xwork/xwork-1.1.dtd"</span>&gt;</span><span class="code-tag">&lt;xwork&gt;</span><span class="code-tag">  &lt;include file=<span class="code-quote">"webwork-default.xml"</span>/&gt;</span><span class="code-tag">  &lt;package name=<span class="code-quote">"default"</span> extends=<span class="code-quote">"webwork-default"</span>&gt;</span><span class="code-tag">    &lt;action name=<span class="code-quote">"foo" class="foo"</span>&gt;</span><span class="code-tag">      &lt;result&gt;</span>foo.ftl<span class="code-tag">&lt;/result&gt;</span><span class="code-tag">    &lt;/action&gt;</span><span class="code-tag">  &lt;/package&gt;</span><span class="code-tag">  &lt;package name=<span class="code-quote">"secure"</span> namespace=<span class="code-quote">"/secure"</span> extends=<span class="code-quote">"default"</span>&gt;</span><span class="code-tag">    &lt;action name=<span class="code-quote">"bar" class="bar"</span>&gt;</span><span class="code-tag">      &lt;result&gt;</span>bar.ftl<span class="code-tag">&lt;/result&gt;</span><span class="code-tag">    &lt;/action&gt;</span><span class="code-tag">  &lt;/package&gt;</span><span class="code-tag">&lt;/xwork&gt;</span></font></pre></div></div><p>Where you have a Spring bean defined in your <strong>applicationContext.xml</strong> named "bar". Note that the <em>com.acme.Foo</em> action did not need to be changed, because it can be autowired. </p><p>(你需要在你的applicationContext.xml里定义一个名字为"bar"的bean. 注意 com.acme.Foo不需要被改变,因为它是自动装配的.)</p><p><br /> <strong>记住:这个不是必须的</strong>.仅仅当你需要使用Spring的拦截器或者IoC来修饰Action以便覆盖 Webwork的缺省行为时,这才是必要的.要记住一点,WebWork的Spring组合会执行标准的IoC,使用你指定的自动装配策略,即使你没有明确第在Spring中映射每个Action.所以通常你不需要做这个,但是知道怎么做对你是有好处的,如果你需要的话.<br /></p><h2><br />和以前版本的区别</h2><p> 其实本质上是一样的,<strong>主要区别如下</strong>:</p><ul><li> 可以不配置SpringObjectFactoryListenter,直接在webwork.properties里指定. </li><li> 在webwork.properties里可以指定autoWire策略. </li><li><strike> SpringObjectFactory里面多了一个buildAction,用来根据前面提到的命名习惯查找action. (已经删除)</strike></li></ul><h2><br />其他 </h2><p>其实通过查看源码可以知道,还有几个其他的类,可以做其他的设置,例如SpringProxyableObjectFactory,SessionContextSpringProxyableObjectFactory等<br /><span id="BlogViewId">Tabbed Panels(选项卡)是一个具有多个选项页面的控件.在应用程序中很常见. </span></p><p>在WebWork中,还有<font color="#0000ff">另外一个tabbedPane</font>,和这个类似,不过它的使用方法和本控件不同,具体可以参考以前版本中的TabbedPaneTest.action例子.</p><p>首先,我们把wiki文档翻译一下:</p><div class="wiki-content"><p>此面板组件允许你有一个选项卡面板,每个选项页可以拥有本地的内容或者远程的内容(用户每次选择这个选项页都会刷新内容).</p><h3><a name="TabbedPanels-Attributesww:tabbedPanel">属性</a><a name="TabbedPanels-Attributesww:tabbedPanel"> - ww:tabbedPanel</a></h3><table class="confluenceTable"><tbody><tr><th class="confluenceTh">名称</th><th class="confluenceTh">描述</th></tr><tr><td class="confluenceTd">id (required)</td><td class="confluenceTd">组件标识</td></tr></tbody></table><h3><a name="TabbedPanels-Attributesww:panel">属性</a><a name="TabbedPanels-Attributesww:panel"> - ww:panel</a></h3><table class="confluenceTable"><tbody><tr><th class="confluenceTh">名称</th><th class="confluenceTh">描述</th></tr><tr><td class="confluenceTd">id (required)</td><td class="confluenceTd">标识ID</td></tr><tr><td class="confluenceTd">tabName (required)</td><td class="confluenceTd">选项文字,显示在选项页列表的头部</td></tr><tr><td class="confluenceTd">href (required if remote panel)</td><td class="confluenceTd">用来获取内容的网址</td></tr><tr><td class="confluenceTd">remote</td><td class="confluenceTd">true/false - 用来确定这是一个远程面板(ajax)还是一个本地面板 (内容会装入可视或隐藏的容器)</td></tr><tr><td class="confluenceTd">loadingText</td><td class="confluenceTd">新的远程内容被获取之前显示的文字</td></tr><tr><td class="confluenceTd">reloadingText</td><td class="confluenceTd">装载内容时对用户显示的文字,特别是取内容的时候要花费很长的时间 (仅对远程面板可用)</td></tr><tr><td class="confluenceTd">errorText</td><td class="confluenceTd">如果取内容时发生了错误,向用户显示的提示 (仅对远程面板可用)</td></tr><tr><td class="confluenceTd">showErrorTransportText</td><td class="confluenceTd">true/false - 当获取内容有问题的时候,是否把错误信息当作内容显示(仅对远程面板可用)</td></tr><tr><td class="confluenceTd">listenTopics</td><td class="confluenceTd">监听的Topic名称(多个逗号分割),将会导致此面板重新获取内容</td></tr></tbody></table><h3>额外的配置</h3><p>如果你在寻找"好看"的圆角效果, 这里有一个可用的配置. 这里假设选项卡的背景色是白色.如果你使用了不同的颜色,请修改 Rounded() 方法的参数.</p><div class="code"><div class="codeContent"><pre class="code-java">&lt;link rel=<span class="code-quote">"stylesheet"</span> type=<span class="code-quote">"text/css"</span> href="/<span" class="code-quote">"&lt;ww:url value="/webwork/tabs.css<span class="code-quote">"/&gt;"</span>&gt;
&lt;link rel=<span class="code-quote">"stylesheet"</span> type=<span class="code-quote">"text/css"</span> href="/<span" class="code-quote">"&lt;ww:url value="/webwork/niftycorners/niftyCorners.css<span class="code-quote">"/&gt;"</span>&gt;
&lt;link rel=<span class="code-quote">"stylesheet"</span> type=<span class="code-quote">"text/css"</span> href="/<span" class="code-quote">"&lt;ww:url value="/webwork/niftycorners/niftyPrint.css<span class="code-quote">"/&gt;"</span> media=<span class="code-quote">"print"</span>&gt;
&lt;script type=<span class="code-quote">"text/javascript"</span> src="/<span" class="code-quote">"&lt;ww:url value="/webwork/niftycorners/nifty.js<span class="code-quote">"/&gt;"</span>&gt;&lt;/script&gt;
&lt;script type=<span class="code-quote">"text/javascript"</span>&gt;
dojo.event.connect(window, <span class="code-quote">"onload"</span>, function() {
<span class="code-keyword">if</span> (!NiftyCheck())
<span class="code-keyword">return</span>;
Rounded(<span class="code-quote">"li.tab_selected"</span>, <span class="code-quote">"top"</span>, <span class="code-quote">"white"</span>, <span class="code-quote">"transparent"</span>, <span class="code-quote">"border #ffffffS"</span>);
Rounded(<span class="code-quote">"li.tab_unselected"</span>, <span class="code-quote">"top"</span>, <span class="code-quote">"white"</span>, <span class="code-quote">"transparent"</span>, <span class="code-quote">"border #ffffffS"</span>);
<span class="code-comment">// <span class="code-quote">"white"</span> 要替换为你的背景色
</span>    });
&lt;/script&gt;</span"></span"></span"></span"></pre></div></div></div><p> </p><p> </p><p>我们首先来分析一个例子,</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;ww:tabbedPanel id="test" theme="ajax"&gt;<br />                <br />    &lt;ww:panel id="one" tabName="one" theme="ajax"&gt;<br />          This is the first pane&lt;br/&gt;<br />       &lt;ww:form&gt;<br />         &lt;ww:textfield name="tt" label="Test Text"/&gt;  &lt;br/&gt;<br />         &lt;ww:textfield name="tt2" label="Test Text2"/&gt;<br />       &lt;/ww:form&gt;<br />    &lt;/ww:panel&gt;<br />                   <br />    &lt;ww:panel id="two" tabName="two" theme="ajax"&gt;<br />        This is the second panel<br />    &lt;/ww:panel&gt;<br />                    <br />&lt;/ww:tabbedPanel&gt; </td></tr></tbody></table><br />这个选项卡包含了2个选项页面,都是本地页面,使用ww:panel来定义页面内容,使用的模板都是ajax模板.<p>我们再来看如何定义远程页面:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;ww:tabbedPanel id="test2" theme="simple" &gt;<br />      &lt;ww:panel id="left" tabName="left" theme="ajax"&gt;<br />          This is the left pane&lt;br/&gt;<br />          &lt;ww:form &gt;<br />              &lt;ww:textfield name="tt" label="Test Text" /&gt;  &lt;br/&gt;<br />              &lt;ww:textfield name="tt2" label="Test Text2" /&gt;<br />          &lt;/ww:form&gt;<br />      &lt;/ww:panel&gt;<br />      &lt;ww:panel remote="true" href="/AjaxTest.action" id="ryh1" theme="ajax" tabName="remote one" /&gt;<br />      &lt;ww:panel id="middle" tabName="middle" theme="ajax"&gt;<br />          middle tab&lt;br/&gt;<br />          &lt;ww:form &gt;<br />              &lt;ww:textfield name="tt" label="Test Text44" /&gt;  &lt;br/&gt;<br />              &lt;ww:textfield name="tt2" label="Test Text442" /&gt;<br />          &lt;/ww:form&gt;<br />      &lt;/ww:panel&gt;<br />      &lt;ww:panel remote="true" href="/AjaxTest.action"  id="ryh21" theme="ajax" tabName="remote right" /&gt;<br />  &lt;/ww:tabbedPanel&gt;</td></tr></tbody></table><br />可以看到定义了四个选项页面,其中有2个是远程页面.<p>每次切换页面时,<font color="#ff0000"><font color="#0000ff">相应"远程页面"的内容都会刷新,本地页面是不</font></font><font color="#0000ff">刷新的.</font></p><p>同时远程页面<strong>也可以监听Topic</strong>,具体使用可以参考Remote A或者使用JavaScript进行调用.(<font color="#ff0000">注:beta1里面的相关程序有一些错误</font>)<br /><span id="BlogViewId"></span></p><div class="wiki-content"><p>远程链接标签允许对一个URL进行访问,但可以不刷新页面.</p><h3>属性</h3><table class="confluenceTable"><tbody><tr><th class="confluenceTh">名称</th><th class="confluenceTh">描述</th></tr><tr><td class="confluenceTd">id (required)</td><td class="confluenceTd">元件ID</td></tr><tr><td class="confluenceTd">href (required)</td><td class="confluenceTd">用来获取内容的URL</td></tr><tr><td class="confluenceTd">errorText</td><td class="confluenceTd">如果取内容时发生了错误,向用户显示的提示</td></tr><tr><td class="confluenceTd">showErrorTransportText</td><td class="confluenceTd">true/false - 当获取内容有问题的时候,是否把错误信息当作内容显示</td></tr><tr><td class="confluenceTd">notifyTopics</td><td class="confluenceTd">远程调用完成后,对那些Topic进行事件激发,可以多个,用逗号分割</td></tr><tr><td class="confluenceTd">afterLoading</td><td class="confluenceTd">远程调用完毕后,要执行的Javascript代码</td></tr></tbody></table></div><p></p><p><br /> <br />Remote A标签我觉得<strong>值得关注的特性</strong>是notifyTopics,也就是可以触发别的控件的事件,它可以是一个发令员.<br /> <br /> <br />首先我们来看Remote A标签的<strong>一个例子</strong></p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;ww:a   id="link1"   theme="ajax" href="/AjaxRemoteLink.action"<br />        showErrorTransportText="true"   errorText="An Error ocurred"&gt;Click Me&lt;/ww:a&gt; </td></tr></tbody></table><p><br /><strong>这个标签的含义</strong>:</p><ul><li> ID为link1 </li><li> 使用ajax模板 </li><li> 点击链接时访问的网址为"/AjaxRemoteLink.action" </li><li> 如果发生错误把错误当作内容处理 </li><li> 错误信息为"An Error ocurred"<br />  </li></ul><p><br />点击这个链接,页面会去访问"/AjaxRemoteLink.action",如果返回的结果是JavaScript,就会执行相应的JavaScript.</p><p><font color="#ff0000">如果返回的内容不是JavaScript,系统不会有任何动作,也不会触发事件</font>. (<font color="#3366ff">这个确实有点令人迷惑,也许会改进?如何改进哪?)</font></p><p>我们再来看一个<strong>可以触发事件的标签</strong>,这个是和DIV结合的,可以参考ajax例子中的lesson3中的例子:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td><p>&lt;ww:div  id="one"    cssStyle="border: 1px solid yellow;"<br />        href="/ajax/test1.jspa"        theme="ajax"<br />        listenTopics="mylink1_click" delay="1000"&gt;Initial Content&lt;/ww:div&gt;</p><p>&lt;ww:a     id="link1"   theme="ajax"   href="/ajax/urltestjs.jspa"    <br />  showErrorTransportText="true"   <br />  notifyTopics="mylink1_click"<br />  errorText="An Error ocurred"&gt;Update&lt;/ww:a&gt; </p></td></tr></tbody></table><br /><br />首先是一个要被触发的Div标签,它监听的Topic为"mylink1_click"(可以监听多个).然后是一个A标签,触发的Topic是 "mylink1_click",此处也可以是多个,但用户点击这个Remote A标签时,A标签会执行返回的JavaScript代码,也会触发Div标签重新装载它自身的内容.<p>如果标签还有<strong>afterLoading</strong>='alert("done")'的代码,在触发Div事件之前还会执行这个 afterLoading,可以阅读前面Div标签中关于afterLoading的说明.</p><p><br /><strong>意外</strong>:这个Remote A的功能就这么多,本来以为应该有一个点击后用指定的内容替换目标Div的内容,不过目前没有发现有直观的做法可以实现这个功能,也许有其他做法更合适吧.</p><p><br /><font color="#ff0000">注意</font>:撰写本文时,WebWork2.2还没有最后发布,在最后发布的版本里应该会有一些变化,请以最后发布的版本为准.<br /><span id="BlogViewId"></span></p><div class="wiki-content"><p>Remote DIV 标签和普通的Html的DIV标签工作方式是一样的,但是它可以通过标签内指定的一个网址来装载它的内容.</p><h3>属性</h3><table class="confluenceTable"><tbody><tr><th class="confluenceTh">名称</th><th class="confluenceTh">描述</th></tr><tr><td class="confluenceTd">id (必有)</td><td class="confluenceTd">DIV的ID</td></tr><tr><td class="confluenceTd">href (必有)</td><td class="confluenceTd">用来获取内容的网址</td></tr><tr><td class="confluenceTd">delay</td><td class="confluenceTd">第一次装载内容需要延迟多长时间 (毫秒)</td></tr><tr><td class="confluenceTd">updateFreq</td><td class="confluenceTd">多长时间重新取一次内容 (毫秒)</td></tr><tr><td class="confluenceTd">loadingText</td><td class="confluenceTd">装载内容中对用户显示的文字 (特别是取内容的时候要花费很长的时间</td></tr><tr><td class="confluenceTd">errorText</td><td class="confluenceTd">如果取内容时发生了错误,向用户显示的提示</td></tr><tr><td class="confluenceTd">showErrorTransportText</td><td class="confluenceTd">true/false - 当获取内容有问题的时候,是否把错误信息当作内容显示</td></tr><tr><td class="confluenceTd">listenTopics</td><td class="confluenceTd">监听的Topic名称(多个逗号分割), 将会导致此DIV重新获取内容</td></tr><tr><td class="confluenceTd">afterLoading</td><td class="confluenceTd">获取内容后要执行的Javascript代码</td></tr></tbody></table><h3>其他功能</h3><p>使用javascript代码我们还可以刷新内容,停止或者开始刷新组件.例如一个id是"remotediv1"的div组件:</p><p>开始刷新的javascript代码:</p><div class="codeContent">remotediv1.start(); </div><p>停止刷新的javascript代码:</p><div class="codeContent">remotediv1.stop(); </div><p>刷新内容的javascript代码:</p><div class="codeContent">remotediv1.bind(); </div></div><p> </p><p>翻译完毕(<font color="#ff0000">注:原文是会被随时修改的,请以原文为主</font>)</p><p>其中<u>href的地址</u>会自动加上Web App的前缀,如果你已经自己写上了,就不会在加了,所以要避免子目录和web app同名.</p><p><br /><strong>Remote DIV标签我觉得最值得关注的特性包括</strong>:</p><ul><li> 可以自己重新装载自己的内容 </li><li> 可以监听Topic,也就是别的动作可以引发更新内容的行为 </li><li> JavaScript代码可以控制它的行为<br /> <br />  </li></ul><p>首先我们来看Remote Div标签的最<strong>简单的一个例子</strong>example1.jsp:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;%@ page contentType="text/html;charset=UTF-8" language="java" %&gt;<br /> &lt;%@ taglib prefix="ww" uri="/webwork" %&gt;<br /> &lt;html&gt;<br /> &lt;head&gt;<br />     &lt;title&gt;Ajax Examples&lt;/title&gt;<br />     &lt;jsp:include page="../commonInclude.jsp"/&gt;<br /> &lt;/head&gt;<br /> &lt;body&gt;<br /> &lt;ww:div id="once"  theme="ajax"   cssStyle="border: 1px solid yellow;"    <br />  href="/AjaxTest.action"   delay="5000"   loadingText="loading..."&gt;Initial Content&lt;/ww:div&gt;<br /> &lt;/body&gt;&lt;/html&gt; </td></tr></tbody></table><br /><strong>注</strong>:了解commonInclude.jsp,请阅读"AJAX之介绍".<p><br />我们再来看example1.jsp这个文件,内容非常简单,使用了一个ww:div标签,设置了一个id,使用的是ajax这个模板(如果你想定义自己的模板,请务必参考ajax模板的编写方法),设置读取内容的url为"/AjaxTest.action",设置延迟5000毫秒后读取内容,装载内容时显示的文本设置为"loading...",div显示时的初始内容时"Initial Content".</p><p>是的,很简单,在打开网页5秒后,标签会自动去访问"/AjaxTest.action",并把获取的内容设置为Div的内容.</p><p><br />我们再来看一个<strong>定时自动刷新</strong>的例子:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;ww:div  id="twoseconds"    cssStyle="border: 1px solid yellow;"   href="/AjaxTest.action"<br />         theme="ajax" delay="2000"  updateFreq="3000" errorText="There was an error"&gt;Initial Content&lt;/ww:div&gt; </td></tr></tbody></table><p>这个标签产生的结果每3秒钟刷新一次DIV的内容,和上面的差不多,只是多了一个updateFreq设置.</p><p>此标签还有一个<strong>afterLoading属性</strong>,使用方法如下:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;ww:div  ......   afterLoading=’alert("done")’&gt;Initial Content&lt;/ww:div&gt; </td></tr></tbody></table><p>或者</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;ww:div  ......   afterLoading="alert(\"done\")"&gt;Initial Content&lt;/ww:div&gt; </td></tr></tbody></table><br /><br /><p><font color="#ff0000">注意</font>:目前使用afterLoading="alert(’done’)"的方法好像有点问题,好像是dojo内部处理引发的问题.</p><p> </p><p><strong>监听Topic</strong>是通过JavaScript代码或者其他部件来触发的,使用JavaScript的示例如下:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;ww:div   id="once"    theme="ajax"     cssStyle="border: 1px solid yellow;"  href="/ajax/test1.jspa"<br />         delay="5000"  loadingText="loading..."    listenTopics="scud1"   &gt;Initial Content&lt;/ww:div&gt; </td></tr></tbody></table><br /><p>这个Div标签将监听Topic为"scud1"的事件.</p><p>我们可以使用一个普通按钮来触发事件:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;script type="text/javascript"&gt;<br />  function scud1() { dojo.event.topic.publish( "scud1", "alert(’test’);" ); }<br /> &lt;/script&gt;<br /> &lt;INPUT type="button" onclick="scud1()" value="click"&gt; </td></tr></tbody></table><br /><p>点击这个按钮,将会导致Div标签重新装入内容. 注意一个Div标签可以监听多个Topic,用逗号分割即可.</p><p>至于使用其他部件触发事件的代码,我们将会在使用Remote A Tag时用到.<br /><span id="BlogViewId">在WebWork2.2中,引入了Dojo ( <a href="http://dojotoolkit.org/" target="_blank">http://dojotoolkit.org</a> ) 和DWR ( <a href="http://getahead.ltd.uk/dwr/" target="_blank">http://getahead.ltd.uk/dwr/</a> ) 两个新的部件来支持AJAX功能. </span></p><p>其中主要增加的特性包括:</p><ul><li><strong>Remote Div Tag</strong> -- 远程区域块标签,通过异步调用获取内容,来动态更新Div.可以循环更新. </li><li><strong>Remote A Tag</strong>  --远程链接标签,点击链接时进行一个远程异步调用,可以动态更新Div的内容. </li><li><strong>Tabbed Panelds</strong> --选项卡页面,和普通程序中的选项卡一样,可以有多个选项页面,每个页面的内容都可以设置(本地或者从远程获取),点击一个选项页,切换页面. </li><li><strong>Remote Form</strong> --远程表单,也就是提交但不刷新的表单,点击提交按钮,页面不刷新,通过远程异步调用,更新目标区域的内容. </li><li><strong>Form Validation</strong> --表单校验,在表单中的每个控件输入数据都可以进行即时的校验,主要使用的是DWR.这个在前面已经演示过了. </li></ul><p><br /><font color="#ff0000">目前这几个控件在IE上表现的都有一些问题</font>:</p><ol><li>目前Remote Form在IE下不工作,在FireFox下正常工作. </li><li>目前动态刷新在IE上好像都有缓存问题,在FireFox下没有问题.(如果在结果页面增加清除缓存的代码,可以解决这个问题)<br />  </li></ol><p>因为以前没有使用过AJAX,所以后面的文字基本是把webwork wiki上的文档翻译一下,然后按照webwork自带的ajax的教程使用并说明一下.</p><p>建议使用这几个标签之前,了解一下Dojo的工作原理,这样才能知其所以然.</p><p>清除缓存的代码:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;% <br />    response.setHeader("Pragma", "no-cache");<br />    response.setHeader("Cache-Control", "no-cache");<br />    response.setDateHeader("Expires", 0);<br />%&gt; </td></tr></tbody></table><br />或者用html的meta来试试,不过那就包含在内容里了.<p><br />为了使用WebWork的AJAX组件,我们需要在页面里面根据Dojo的做法包含一些代码,例如ajax例子里面的<strong>commonInclude.jsp文件</strong>:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td><p>&lt;%@ taglib prefix="ww" uri="/webwork" %&gt;<br />&lt;!--// START SNIPPET: common-include--&gt;<br />&lt;script language="JavaScript" type="text/javascript"&gt;<br />    // Dojo configuration<br />    djConfig = {<br />        baseRelativePath: "&lt;ww:url includeParams="none" value="/webwork/dojo/"/&gt;",<br />        isDebug: false<br />    };<br />&lt;/script&gt;</p><p>&lt;script language="JavaScript" type="text/javascript"<br />        src="&lt;ww:url includeParams="none" value="/webwork/dojo/dojo.js" /&gt;"&gt;&lt;/script&gt;<br />&lt;script language="JavaScript" type="text/javascript"<br />        src="&lt;ww:url includeParams="none" value="/webwork/CommonFunctions.js" /&gt;"&gt;&lt;/script&gt;</p><p>&lt;script language="JavaScript" type="text/javascript"&gt;<br />    dojo.require("dojo.io.BrowserIO");<br />    dojo.require("dojo.event.topic");<br />    dojo.require("webwork.widgets.Bind");<br />    dojo.require("webwork.widgets.BindDiv");<br />    dojo.require("webwork.widgets.BindButton");<br />    dojo.require("webwork.widgets.BindAnchor");<br />&lt;/script&gt;<br />&lt;!--// END SNIPPET: common-include--&gt; </p></td></tr></tbody></table><p><br /></p><p>这个文件里面对Dojo进行了设置,包含dojo.js,并且引入了webwork实现的这几个装饰件的代码,在后面的每个例子中,都要包含这个文件,因此后面的介绍中将省略这个文件的介绍,要想了解更多信息,可以参考Dojo的文档.</p><p> </p><p>注:AJAX对于WebWork来说还是一个新的特性,肯定会存在一些问题,我们要努力地去<a href="http://forum.opensymphony.com/" target="_blank">开发论坛</a>上提意见 :)</p><p> </p><p><font color="#ff0000">注</font>:2005-9-16 remote form 最新cvs上的版本已经可以在ie上运行.</p></div>
				</div>
		</span>
<img src ="http://www.blogjava.net/javaniu/aggbug/62851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaniu/" target="_blank">Gary Niu</a> 2006-08-10 20:47 <a href="http://www.blogjava.net/javaniu/archive/2006/08/10/62851.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebWork 学习笔记（五） </title><link>http://www.blogjava.net/javaniu/archive/2006/08/10/62850.html</link><dc:creator>Gary Niu</dc:creator><author>Gary Niu</author><pubDate>Thu, 10 Aug 2006 12:43:00 GMT</pubDate><guid>http://www.blogjava.net/javaniu/archive/2006/08/10/62850.html</guid><wfw:comment>http://www.blogjava.net/javaniu/comments/62850.html</wfw:comment><comments>http://www.blogjava.net/javaniu/archive/2006/08/10/62850.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaniu/comments/commentRss/62850.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaniu/services/trackbacks/62850.html</trackback:ping><description><![CDATA[在webwork中,com/opensymphony/webwork/default.properties是很重要的文件,它对webwork的参数进行了配置,其中包含了webwork支持的所有配置,如果你想覆盖其中的配置,只需要建立一个webwork.properties放在你的项目中(一般放在源码目录下,发布时的位置是WEB-INF/classes下). 
<p>让我们来看看在webwork 2.2中这个文件发生了什么变化.</p><p><br /><strong>1.可以配置webwork.objectFactory</strong></p><p></p><table class="code" style="WIDTH: 613px; HEIGHT: 60px" cellspacing="1" cellpadding="1" width="613" align="center" border="0"><tbody><tr><td># if specified, the default object factory can be overridden here<br /> #webwork.objectFactory = com.opensymphony.xwork.spring.SpringObjectFactory </td></tr></tbody></table><br /> 这个ObjectFactory是一个功能很大的类,默认webwork使用的是com.opensymphony.xwork.ObjectFactory,如果你想自己实现一个或者使用Spring的机制,可以配置这个属性.不过在没有更详细的文档出来之前,一定要小心使用.<p>SpringObjectFactory类中主要覆写了ObjectFactory的buildBean,并没有替换其他函数.</p><p><strong>2.webwork.mapper.class</strong></p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td># extension for actions<br /> webwork.mapper.class=com.opensymphony.webwork.dispatcher.mapper.DefaultActionMapper<br /> webwork.action.extension=action </td></tr></tbody></table><p><br />可以看到,增加了一行webwork.mapper.class.</p><p><br />DefaultActionMapper以及同目录下RestfulActionMapper相当于以前的普通action url路径处理和CoolUriServletDispatcher映射方式处理,在webwork2.2中,如果想使用CoolUriServletDispatcher的方式,在此处修改这个属性为RestfulActionMapper即可.</p><p>当然,你可以实现自己的ActionMapper,实现自己的想法,很多人都喜欢自己来处理url,那就自己写一个,不错的想法.</p><p><strong>3.webwork.tag.altSyntax=true</strong><br />altSyntax语法默认为打开了,参考前面的文章</p><p><strong>4.webwork.i18n.reload</strong></p><p></p><table class="code" style="WIDTH: 623px; HEIGHT: 73px" cellspacing="1" cellpadding="1" width="623" align="center" border="0"><tbody><tr><td> # when set to true, resource bundles will be reloaded on _every_ request.<br /> # this is good during development, but should never be used in production<br /> webwork.i18n.reload=false </td></tr></tbody></table><p>如果设置为true,每次资源文件都会被重载,方便调试.发布后一定要记得改为false.</p><p><strong>5.webwork.ui.templateSuffix</strong></p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> #sets the default template type. Either ftl, vm, or jsp<br /> webwork.ui.templateSuffix=ftl </td></tr></tbody></table><br />Tag模板的默认配置为freemarker的ftl了,以前是vm的.<p><br /><strong>6.webwork.dispatcher.parametersWorkaround</strong></p><p></p><table class="code" style="WIDTH: 615px; HEIGHT: 60px" cellspacing="1" cellpadding="1" width="615" align="center" border="0"><tbody><tr><td> # workaround for some app servers that don’t handle HttpServletRequest.getParameterMap()<br /> # often used for WebLogic, Orion, and OC4J<br /> webwork.dispatcher.parametersWorkaround = false </td></tr></tbody></table><span id="BlogViewId"><div><div><p>ParameterNameAware 是XWork中新增的一个接口,是由Bob Lee (<a href="mailto:crazybob@google.com">crazybob@google.com</a>)提供的,主要的用途是限制Action仅接收一定规则的参数,用来防止无意义的参数或者破坏?不过我想我暂时用不到这个接口,不过还是介绍一下如何使用吧.</p><p>首先我们写一个Action,实现ParameterNameAware接口,这个接口只有一个方法,就是public boolean acceptableParameterName(String name).</p><p>我们的<strong>Action如下</strong>:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>package com.jscud.ww2test.parametername; 
<p>import com.opensymphony.xwork.ActionSupport;<br />import com.opensymphony.xwork.interceptor.ParameterNameAware;</p><p>/**<br /> * @author scud <a href="http://www.jscud.com/">http://www.jscud.com</a><br /> */<br />public class ParameterNameTestAction extends ActionSupport implements ParameterNameAware<br />{<br />    private String name1;<br />    private String name2;<br />    private String name3;</p><p>    public String execute()<br />    {<br />        return SUCCESS;<br />    }</p><p>    /**<br />     * 当前参数名是否允许.<br />     * @param name 参数名<br />     * @return 是否允许<br />     */<br />    public boolean acceptableParameterName(String name)<br />    {<br />        if (name.equals("name1") || name.equals("name2"))<br />        {<br />            return true;<br />        }<br />                <br />        return false;<br />    }</p><p>    public String getName1()<br />    {<br />        return name1;<br />    }</p><p>    public void setName1(String name1)<br />    {<br />        this.name1 = name1;<br />    }</p><p>    public String getName2()<br />    {<br />        return name2;<br />    }</p><p>    public void setName2(String name2)<br />    {<br />        this.name2 = name2;<br />    }</p><p>    public String getName3()<br />    {<br />        return name3;<br />    }</p><p>    public void setName3(String name3)<br />    {<br />        this.name3 = name3;<br />    }<br />}</p> </td></tr></tbody></table><br /><br />可以看到,这个Action实现了ParameterNameAware接口,并且设置只接收"name1"和"name2"两个参数,而我们在action有三个用来保存用户输入值的对象:name1,name2和name3.<p>我们的<strong>action定义</strong>如下:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;package name="parameternametest" extends="webwork-default" namespace="/parametername"&gt;<br />  &lt;action name="index" class="com.jscud.ww2test.parametername.ParameterNameTestAction"&gt;<br />   &lt;result name="success" type="dispatcher"&gt;<br />    &lt;param name="location"&gt;/parametername/index.jsp&lt;/param&gt;<br />   &lt;/result&gt;<br />  &lt;/action&gt;<br /> &lt;/package&gt; </td></tr></tbody></table><br /><font color="#ff0000">不需要定义任何额外的拦截器,这个接口是在ParametersInterceptor被检测的.</font><p><strong>目标页面</strong>如下:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;%@ page contentType="text/html; charset=UTF-8" %&gt;<br /> &lt;%@ taglib uri="webwork" prefix="ww" %&gt;<br /> &lt;html&gt;<br /> &lt;head&gt;<br />     &lt;title&gt;Test ParamaterName&lt;/title&gt;<br /> &lt;/head&gt;<br /> &lt;body&gt;<br /> <br /> &lt;ww:form name="test" action="index" method="post" namespace="/parametername" &gt;<br /> &lt;ww:textfield name="name1"  label="Name1" /&gt;&lt;br&gt;<br /> &lt;ww:textfield name="name2"  label="Name2" /&gt;&lt;br&gt;<br /> &lt;ww:textfield name="name3"  label="Name3" /&gt;&lt;br&gt;<br /> &lt;ww:submit value="Submit" /&gt;<br /> &lt;/ww:form&gt;<br /> &lt;br/&gt;<br /> <br /> Show Message:<br /> &lt;br/&gt;<br /> Name1 is:&lt;ww:property value="name1" /&gt;&lt;br/&gt;<br /> Name2 is:&lt;ww:property value="name2" /&gt;&lt;br/&gt;<br /> Name3 is:&lt;ww:property value="name3" /&gt;&lt;br/&gt;<br /> &lt;/body&gt;<br /> &lt;/html&gt; </td></tr></tbody></table><br /><p> 运行程序,<strong>我们可以发现</strong>,name3的值没有得到设置,我们在页面中也自然得不到name3的值了.</p></div></div></span><br /><span id="BlogViewId"><p>在xwork中,package的定义中增加了global-exception-mappings,action的定义中增加了exception-mapping,要想使用这2个特性,<font color="#ff0000">必须使用xwork-1.1.dtd才行</font>.</p><p>DTD中,<strong>global-exception-mappings是这样定义</strong>的,</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;!ELEMENT global-exception-mappings (exception-mapping+)&gt; </td></tr></tbody></table><p>也就是说如果要使用,至少包含一个异常映射.</p><p><strong>exception-mapping的定义</strong>如下:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;!ELEMENT exception-mapping (#PCDATA|param)*&gt;<br />&lt;!ATTLIST exception-mapping<br />    name CDATA #IMPLIED<br />    exception CDATA #REQUIRED<br />    result CDATA #REQUIRED<br />&gt; </td></tr></tbody></table><br />可以看到有3个属性:名称,异常类型,和结果.<p><br />经过一番查看,发现xwork-default.xml中还没有定义相关的拦截器,搜索了一下,发现了<strong>ExceptionMappingInterceptor</strong>,看来它是把异常翻译为相应的结果的.<br />(在最后发行版本中,应该会定义的.目前只好我们自己定义了.)</p><p>首先我们虚拟一个程序,假设程序会抛出几种程序</p><p><strong>Action定义如下</strong>:</p><p></p><table class="code" style="WIDTH: 535px; HEIGHT: 543px" cellspacing="1" cellpadding="1" width="535" align="center" border="0"><tbody><tr><td>package com.jscud.ww2test.exceptionmap;<br /> <br /> import com.opensymphony.xwork.ActionSupport;<br /> <br /> /**<br />  * @author scud <a href="http://www.jscud.com/">http://www.jscud.com</a><br />  *<br />  */<br /> public class ExpMappingAction extends ActionSupport<br /> {<br />     private int type;<br /> <br />     public String execute() throws NoRightException,NotFoundException<br />     {<br />         if(type==1)<br />         {<br />             throw new NoRightException();<br />         }<br />         else if(type ==99)<br />         {<br />             throw new NotFoundException();<br />         }<br />         else if(type==60) //其他异常<br />         {<br />             throw new IllegalArgumentException(); <br />         }<br />         <br />         return SUCCESS;<br />     }<br />     <br />     public int getType()<br />     {<br />         return type;<br />     }<br />     <br />     public void setType(int type)<br />     {<br />         this.type = type;<br />     }<br /> } </td></tr></tbody></table><br /><p> 从Action可以看出,程序至少会抛出3种异常,我们如果使用异常映射,就要考虑到抛出的所有异常.</p><p>程序中用到的NoRightException,NotFoundException是为了演示而建立的2个简单异常,无任何特殊代码,继承自Exception.</p><p>我们的<strong>Xwork.xml中的定义</strong>如下:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td><p> &lt;package name="exceptionmapping" extends="webwork-default" namespace="/exceptionmap"&gt;<br /> <br />  &lt;interceptors&gt;<br />   &lt;interceptor name="exceptionmapping" class="com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor"/&gt;<br />   <br />   &lt;interceptor-stack name="myDefaultStack"&gt;<br />       &lt;interceptor-ref name="defaultStack"/&gt;<br />       &lt;interceptor-ref name="exceptionmapping"/&gt;<br />   &lt;/interceptor-stack&gt;<br />  &lt;/interceptors&gt;</p><p>  &lt;default-interceptor-ref name="myDefaultStack"/&gt;</p><p><br />  &lt;global-results&gt;<br />   &lt;result name="noright" type="dispatcher"&gt;<br />    &lt;param name="location"&gt;/exceptionmap/noright.jsp&lt;/param&gt;<br />   &lt;/result&gt;<br />   &lt;result name="exception" type="dispatcher"&gt;<br />    &lt;param name="location"&gt;/exceptionmap/exception.jsp&lt;/param&gt;<br />   &lt;/result&gt;<br />  &lt;/global-results&gt;<br /> <br />  &lt;global-exception-mappings&gt;<br />   &lt;exception-mapping name="noright" exception="com.jscud.ww2test.exceptionmap.NoRightException" result="noright"/&gt;<br />   &lt;exception-mapping name="exception" exception="java.lang.Exception" result="exception"/&gt;<br />  &lt;/global-exception-mappings&gt;<br /> <br />  &lt;action name="index" class="com.jscud.ww2test.exceptionmap.ExpMappingAction"&gt;<br />   &lt;exception-mapping  name="notfound" exception="com.jscud.ww2test.exceptionmap.NotFoundException" result="notfound"/&gt;<br />   &lt;result name="success" type="dispatcher"&gt;<br />    &lt;param name="location"&gt;/exceptionmap/index.jsp&lt;/param&gt;<br />   &lt;/result&gt;<br />   &lt;result name="notfound" type="dispatcher"&gt;<br />    &lt;param name="location"&gt;/exceptionmap/notfound.jsp&lt;/param&gt;<br />   &lt;/result&gt;<br />  &lt;/action&gt;<br />  <br /> &lt;/package&gt;</p> </td></tr></tbody></table><br /><p>首先定义了一个exceptionmapping拦截器,用来指向ExceptionMappingInterceptor.<br />然后定义一个拦截器Stack,包含defaultStack和exceptionmapping,注意,exceptionmapping是在Stack的最后面,否则会发生不可预期的结果.</p><p>可以看到global-exception-mappings段包含了2个异常映射,一个为NoRight的处理,另外一个为对应java.lang.Exception的映射.</p><p>在Action的定义中包含了一个exception-mapping,对应NotFound异常.</p><p>没有看到IllegalArgumentException的对应结果?? 拦截器对没有定义的异常会依次找这个异常的父类,一级一级向上查找,例如IllegalArgumentException的最终父节点是 Exception,就会转向到Exception对应的结果. 如果一个异常有多个层次关系上的父类,那个关系最近就找谁.</p><p><strong>演示页面</strong>如下:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;%@ page contentType="text/html; charset=GBK" %&gt;<br /> &lt;%@ taglib uri="webwork" prefix="ww" %&gt;<br /> &lt;html&gt;<br />   &lt;head&gt;<br />     &lt;title&gt;exception mapping&lt;/title&gt;<br />   &lt;/head&gt;<br /> &lt;body&gt;<br /> <br /> &lt;br&gt;<br /> Exception 1:<br /> &lt;a href="/index.jspa?type=1"&gt;Exception 1&lt;/a&gt;<br /> &lt;br&gt;&lt;br&gt;<br /> <br /> Exception 99:<br /> &lt;a href="/index.jspa?type=99"&gt;Exception 99&lt;/a&gt;<br /> &lt;br&gt;&lt;br&gt;<br /> <br /> Other Exception:<br /> <br /> &lt;a href="/index.jspa?type=60"&gt;Exception 60&lt;/a&gt;<br /> &lt;br&gt;&lt;br&gt;<br /> <br /> Normal:<br /> &lt;a href="/index.jspa"&gt;No Exception&lt;/a&gt;<br /> &lt;br&gt;&lt;br&gt;<br /> <br /> &lt;/body&gt;<br /> &lt;/html&gt; </td></tr></tbody></table><br /><p> notfound.jsp,exception.jsp,noright.jsp是三个最简单的jsp页面,自己编写即可.</p><p>运行程序,发现根据异常类型会转向相应的异常页面. </p></span><img src ="http://www.blogjava.net/javaniu/aggbug/62850.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaniu/" target="_blank">Gary Niu</a> 2006-08-10 20:43 <a href="http://www.blogjava.net/javaniu/archive/2006/08/10/62850.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebWork 学习笔记（四） </title><link>http://www.blogjava.net/javaniu/archive/2006/08/10/62847.html</link><dc:creator>Gary Niu</dc:creator><author>Gary Niu</author><pubDate>Thu, 10 Aug 2006 12:40:00 GMT</pubDate><guid>http://www.blogjava.net/javaniu/archive/2006/08/10/62847.html</guid><wfw:comment>http://www.blogjava.net/javaniu/comments/62847.html</wfw:comment><comments>http://www.blogjava.net/javaniu/archive/2006/08/10/62847.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaniu/comments/commentRss/62847.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaniu/services/trackbacks/62847.html</trackback:ping><description><![CDATA[
		<span id="BlogViewId">
				<strong>1.ServletDispatcher 被FilterDispatcher替代<br /></strong> <br /> <font color="#ff0000"> ServletDispatcher被标记为deprecated. </font><p><font color="#ff0000"><font color="#0000ff">(FreemarkerServlet和WebWorkVelocityServlet也被标记为deprecated)</font><br /></font>  <br />  新的Web.xml部分配置如下:<br />  </p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>    &lt;filter&gt;<br />        &lt;filter-name&gt;webwork&lt;/filter-name&gt;<br />        &lt;filter-class&gt;com.opensymphony.webwork.dispatcher.FilterDispatcher&lt;/filter-class&gt;<br />    &lt;/filter&gt; 
<p>    &lt;filter-mapping&gt;<br />        &lt;filter-name&gt;webwork&lt;/filter-name&gt;<br />        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />    &lt;/filter-mapping&gt;</p><p>    &lt;listener&gt;<br />        &lt;listener-class&gt;com.opensymphony.webwork.lifecycle.LifecycleListener&lt;/listener-class&gt;<br />    &lt;/listener&gt;</p><p>    &lt;servlet&gt;<br />        &lt;servlet-name&gt;JspSupportServlet&lt;/servlet-name&gt;<br />        &lt;servlet-class&gt;com.opensymphony.webwork.views.JspSupportServlet&lt;/servlet-class&gt;<br />        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />    &lt;/servlet&gt; </p></td></tr></tbody></table><p>其中filter代替了过去的ServletDispatcher,也增加了不少功能. </p><p>其中的LifecycleListener部分是为了使用XWork的IOC功能而设置的监听器,如果不使用,应该是可以去掉的.</p><p>其中的JspSupportServlet是为了支持在Freemarker和Velocity中进行的一些设置,如果去掉这个,一些功能就不能在ftl文件里面使用了,例如webwork的tag支持.</p><p><br />如果想单独使用Freemarker的文件(不通过action),还可以在web.xml配置FreeMarkerServlet,类似</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;servlet&gt;<br />   &lt;servlet-name&gt;freemarker&lt;/servlet-name&gt;<br />   &lt;servlet-class&gt;com.opensymphony.webwork.views.freemarker.FreemarkerServlet&lt;/servlet-class&gt;<br />   &lt;load-on-startup&gt;10&lt;/load-on-startup&gt;<br /> &lt;/servlet&gt;<br /> <br /> &lt;servlet-mapping&gt;<br />   &lt;servlet-name&gt;freemarker&lt;/servlet-name&gt;<br />   &lt;url-pattern&gt;*.ftl&lt;/url-pattern&gt;<br /> &lt;/servlet-mapping&gt;<br /></td></tr></tbody></table><br /><br /><strong><font color="#ff0000">注意</font></strong>:如果仅使用ftl文件作为action的结果页面,使用freemarker结果类型即可,不需要配置FreeMarkerServlet.<p>如果想使用DWR进行客户端校验,还需要配置:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td><p>    &lt;servlet&gt;<br />        &lt;servlet-name&gt;dwr&lt;/servlet-name&gt;<br />        &lt;servlet-class&gt;uk.ltd.getahead.dwr.DWRServlet&lt;/servlet-class&gt;<br />        &lt;init-param&gt;<br />            &lt;param-name&gt;debug&lt;/param-name&gt;<br />            &lt;param-value&gt;true&lt;/param-value&gt;<br />        &lt;/init-param&gt;<br />    &lt;/servlet&gt;</p><p>    &lt;servlet-mapping&gt;<br />        &lt;servlet-name&gt;dwr&lt;/servlet-name&gt;<br />        &lt;url-pattern&gt;/dwr/*&lt;/url-pattern&gt;<br />    &lt;/servlet-mapping&gt;<br /></p></td></tr></tbody></table><br />DWR还有一些参数配置,可以根据实际修改.<p><font color="#ff0000">使用FilterDispatcher还有一些其他影响</font>,具体可以参考Webwork的文档</p><ul><li>不能使用jsp:include,ww:include了,可以使用action chaining 或者ww:action标签代替. </li><li>Velocity中的JSP tag仿真不能用了,仅支持原生的Velocity tag了 </li></ul><p>当然如果你需要以上的功能,还是依然可以使用ServletDispatcher来配置的,不过这是不推荐的了.</p><p><br /><strong>2.默认使用alt syntax语法,当然可以配置 </strong></p><p>如果用新的方法的话字符串不需要加单引号了,不过要引用变量就要用%{名字}的方式了.<br /> <br /> 例如原来这样写的语句:<br /> Message:&lt;ww:text name="key"/&gt;<br /> &lt;br&gt;&lt;br&gt;<br /> Message:&lt;ww:text name="’name’"/&gt;<br /> <br /> 开启alt syntax后就要这样写:<br /> Message:&lt;ww:text name="%{key}"/&gt;<br /> &lt;br&gt;&lt;br&gt;<br /> Message:&lt;ww:text name="name"/&gt;<br /> <br /><span id="BlogViewId">WebWork2.2中去掉了原来的JavaScript支持,使用AJAX和DWR进行客户端校验. </span></p><p>DWR最新版本为1.0RC3a(2005-8-29),Webwork里面带的是0.6的版本.</p><p>如果使用客户端校验,<strong>首先在Web.xml里配置DWR</strong>:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td><p>    &lt;servlet&gt;<br />        &lt;servlet-name&gt;dwr&lt;/servlet-name&gt;<br />        &lt;servlet-class&gt;uk.ltd.getahead.dwr.DWRServlet&lt;/servlet-class&gt;<br />        &lt;init-param&gt;<br />            &lt;param-name&gt;debug&lt;/param-name&gt;<br />            &lt;param-value&gt;true&lt;/param-value&gt;<br />        &lt;/init-param&gt;<br />    &lt;/servlet&gt;</p><p>    &lt;servlet-mapping&gt;<br />        &lt;servlet-name&gt;dwr&lt;/servlet-name&gt;<br />        &lt;url-pattern&gt;/dwr/*&lt;/url-pattern&gt;<br />    &lt;/servlet-mapping&gt; </p></td></tr></tbody></table><br /><br /><strong>validators.xml</strong>的写法和原来一样,不过就是不能用原来的JavaScript的校验了(如果使用默认的validator,不需要这个文件)<p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td><p> &lt;validators&gt; <br />     &lt;validator name="required" <br />         class="com.opensymphony.xwork.validator.validators.RequiredFieldValidator"/&gt;<br />         <br />     &lt;validator name="requiredstring"<br />         class="com.opensymphony.xwork.validator.validators.RequiredStringValidator"/&gt;<br /> <br />     &lt;validator name="stringlength" <br />      class="com.opensymphony.xwork.validator.validators.StringLengthFieldValidator"/&gt;      <br /> &lt;/validators&gt;</p> </td></tr></tbody></table><br /><strong>对action的校验规则写法也是和原来一样</strong>,例如增加新闻的校验如下:<p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN" "<a href="http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd">http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd</a>"&gt;<br /> &lt;validators&gt;<br />  &lt;field name="news.title"&gt;<br />   &lt;field-validator type="requiredstring"&gt;<br />    &lt;message&gt;请输入标题&lt;/message&gt;<br />   &lt;/field-validator&gt;<br />  &lt;/field&gt; <br />  &lt;field name="news.content"&gt;<br />   &lt;field-validator type="requiredstring"&gt;<br />    &lt;message&gt;请输入内容&lt;/message&gt;<br />   &lt;/field-validator&gt;<br />  &lt;/field&gt;<br />  <br /> &lt;/validators&gt;  </td></tr></tbody></table><br /><br /><br /><strong>在页面的Form标签中写上validate="true"</strong> (注意使用的是alt syntax语法)表示需要进行客户端校验,<br />如果不写validate="true"则不需要进行客户端校验,仅进行服务器端校验,这就和DWR无关了,和以前的客户端校验一样.<p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;ww:form action="doAddNews" method="post" name="doAddNews" validate="true"&gt; </td></tr></tbody></table><br /> <br /> <br /><strong>还需要在WEB-INF下面增加一个dwr.xml配置DWR</strong>,如果使用webwork自带的dwr,格式如下<p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br /> &lt;!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 0.4//EN" "<a href="http://www.getahead.ltd.uk/dwr/dwr.dtd">http://www.getahead.ltd.uk/dwr/dwr.dtd</a>"&gt;<br /> &lt;dwr&gt;<br />     &lt;allow&gt;<br />         &lt;create creator="new" javascript="validator" class="com.opensymphony.webwork.validators.DWRValidator"/&gt;<br />         &lt;convert converter="bean" match="com.opensymphony.xwork.ValidationAwareSupport"/&gt;<br />     &lt;/allow&gt;<br /> &lt;/dwr&gt; </td></tr></tbody></table><br /><br />如果使用DWR 1.0r3a(用新的版本不知道有没有问题),格式如下:<p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "<a href="http://www.getahead.ltd.uk/dwr/dwr10.dtd">http://www.getahead.ltd.uk/dwr/dwr10.dtd</a>"&gt;<br />&lt;dwr&gt;<br /> &lt;allow&gt;<br />  &lt;create creator="new" javascript="validator" &gt;<br />  &lt;param name="class" value="/com.opensymphony.webwork.validators.DWRValidator" /&gt;<br />  &lt;/create&gt;<br />  &lt;convert converter="bean" match="com.opensymphony.xwork.ValidationAwareSupport"/&gt;<br /> &lt;/allow&gt;<br />&lt;/dwr&gt; </td></tr></tbody></table><p>(注:一定要使用匹配dwr和dwr.xml,否则会报错)</p><p><br />通过<strong>查看页面Html源码,</strong>我们可以看到页面中包含了/webwork和/dwr的路径,这些路径由Webwork和DWR自动生成文件返回,避免了在每个项目中复制重复的文件.</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;script src="/ww22test/webwork/validationClient.js"&gt;&lt;/script&gt;<br />&lt;script src="/ww22test/dwr/interface/validator.js"&gt;&lt;/script&gt;<br />&lt;script src="/ww22test/dwr/engine.js"&gt;&lt;/script&gt;<br />&lt;script src="/ww22test/webwork/template/xhtml/validation.js"&gt;&lt;/script&gt; </td></tr></tbody></table><br /><br />其中字段使用onblur来进行调用校验:<p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td>&lt;input type="text" name="news.title" value="" id="doAddNews_news.title" onblur="validate(this);"/&gt; </td></tr></tbody></table><br />至此,Webwork的客户端校验可以运行起来了.<p><font color="#ff0000">(实际操作中,DWR的校验可能还会有些问题,等待开发人员来进行修正了)</font></p><p><font color="#ff0000"><strong>BUG发现</strong>:</font></p><p>目前发现当表单元素的名字没有.的时候(例如是"name"),DWR校验器工作正常,而如果类似上面的表单元素名字类似news.title,校验器工作不正常.<br /><br /><span id="BlogViewId"><span class="postbody"><span style="FONT-WEIGHT: bold">名词定义</span>: <br />简单页面:不通过action访问,直接访问文件的url.例如直接访问的jsp,或者直接访问的ftl. <br /><br /><span style="FONT-WEIGHT: bold">需求想法</span>: <br />在一个网站中,有很多页面,其中很多页面仅仅是简单的页面,没有程序处理等.不过为了国际化,这些页面就需要进行i18n的工作. <br /><br /><br /><span style="FONT-WEIGHT: bold">1.按照正常的想法</span>,应该是每个页面都要写一个action,然后结果定义为这个页面,通过访问action来对页面进行国际化.或者是写一个action,根据参数的不同,转向目标页面. <br />或者要定义很多action或者很多参数 或者用一个程序带不同的参数来访问. 总之是麻烦,不直观. <br /><br /><span style="FONT-WEIGHT: bold">2.实现自己的一个tag来装载国际化信息</span>.这样很简单.不过只能用在jsp里. 如果想使用freemarker的话,通过一些简单处理,也可以使用这个功能. <br />这个思路很简单,可以不依赖任何其他组件. <br /><br /><span style="FONT-WEIGHT: bold">3.WebWork 2.1.7</span><br />如果是在Jsp中,可以通过 <br /><br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td class="code"><div style="FONT-FAMILY: ’Courier New’,Courier,monospace"><br /><br />        &lt;ww:i18n name="message"&gt; <br />          &lt;ww:text name="name"/&gt; <br />        &lt;/ww:i18n&gt; <br />       </div><br /></td></tr></tbody></table><span class="postbody"><br /><br />来实现简单页面的国际化. 无法在freemarker的简单页面中直接使用. (可以在action的结果页面中使用) <br /><br /><br /><span style="FONT-WEIGHT: bold">4.WebWork 2.2 Beta</span> (<span style="COLOR: red">在最后发布的版本中,可能会有变化!!!</span>) <br /><br />在简单页面Jsp中,可以直接使用ww:text,例如 <br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td class="code"><div style="FONT-FAMILY: ’Courier New’,Courier,monospace"><br /><br />        &lt;ww:text name="name"/&gt;        <br />       </div><br /></td></tr></tbody></table><span class="postbody"><br /><br />(<span style="COLOR: red">注意</span>:在webwork.properties中需要包含资源文件 webwork.custom.i18n.resources=message ,如果有多个,就用逗号分割) <br /><br />在FreeMarker的简单文件中,也可以直接使用ww:text. <br /><br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td class="code"><div style="FONT-FAMILY: ’Courier New’,Courier,monospace"><br /><br />        &lt;@ww.<span style="COLOR: rgb(0,0,0)">text</span> name="name"/&gt; <br />       </div><br /></td></tr></tbody></table><span class="postbody"><br /><br />当前是在web.xml里面配置了FreeMarker的处理引擎.如: <br /><br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td class="code"><div style="FONT-FAMILY: ’Courier New’,Courier,monospace"><br /><br />        &lt;servlet&gt; <br />          &lt;servlet-name&gt;freemarker&lt;/servlet-name&gt; <br />          &lt;servlet-<span style="FONT-WEIGHT: bold; COLOR: rgb(153,0,102)">class</span>&gt;com.<span style="COLOR: rgb(0,0,0)">opensymphony</span>.<span style="COLOR: rgb(0,0,0)">webwork</span>.<span style="COLOR: rgb(0,0,0)">views</span>.<span style="COLOR: rgb(0,0,0)">freemarker</span>.<span style="COLOR: rgb(0,0,0)">FreemarkerServlet</span>&lt;/servlet-<span style="FONT-WEIGHT: bold; COLOR: rgb(153,0,102)">class</span>&gt; <br />          &lt;load-on-startup&gt;<span style="COLOR: rgb(0,0,0)">10</span>&lt;/load-on-startup&gt; <br />        &lt;/servlet&gt; <br />        <br />        &lt;servlet-mapping&gt; <br />          &lt;servlet-name&gt;freemarker&lt;/servlet-name&gt; <br />          &lt;url-pattern&gt;*.<span style="COLOR: rgb(0,0,0)">ftl</span>&lt;/url-pattern&gt; <br />        &lt;/servlet-mapping&gt; <br />       </div></td></tr></tbody></table></span><span id="BlogViewId">其实这个I18nInterceptor很简单,而且实际应用中根据实际需求需要进行变通,所以这个I18nInterceptor并不是很实用,当然还是提供了一定的参考作用的. </span></p><p><strong>首先我们来看一下如何使用这个拦截器</strong>.</p><p>首先我们<strong>需要有一个Action</strong>,为了演示,其实最简单的Action就可以,例如</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> public class I18nIcAction extends ActionSupport<br /> {    <br />     public String execute()<br />     {<br />         return SUCCESS;<br />     }<br /> } </td></tr></tbody></table><br /><strong>展示的页面</strong>例子如下:<p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td> &lt;%@ page contentType="text/html; charset=UTF-8" %&gt;<br /> &lt;%@ taglib uri="webwork" prefix="ww" %&gt;<br /> &lt;html&gt;<br /> &lt;head&gt;<br />     &lt;title&gt;Test I18n Interceptor&lt;/title&gt;<br />     &lt;meta http-equiv="pragma" content="no-cache"&gt;<br />     &lt;meta http-equiv="cache-control" content="no-cache"&gt;<br />     &lt;meta http-equiv="expires" content="0"&gt;<br /> &lt;/head&gt;<br />   <br /> &lt;body&gt;<br /> Choose: &lt;a href="/?locale=en"&gt;English Page&lt;/a&gt; ,<br />   &lt;a href="/?locale=zh_CN"&gt;Chinese Page&lt;/a&gt;<br /> &lt;br&gt;&lt;br&gt;<br /> Content:&lt;ww:text name="desc"/&gt;<br /> &lt;/body&gt;<br /> &lt;/html&gt; </td></tr></tbody></table><p><br /></p><p>其中我们使用"locale"作为locale的参数名,页面里面有2个选项:英文和中文.</p><p><strong>对应的资源文件</strong>有2个(或者3个,如果包括缺省一个的话):</p><p>英文的I18nIcAction_en.properties内容为:<br /> desc=english<br /> <br />中文的I18nIcAction_zh_CN.properties内容为:<br /> <span class="Code">desc=\u7b80\u4f53\u4e2d\u6587</span><br /> <br />接下来我们<strong>在xwork.xml里面定义</strong>我们的action和拦截器:</p><p></p><table class="code" cellspacing="1" cellpadding="1" width="80%" align="center" border="0"><tbody><tr><td><p> &lt;package name="i18nic" extends="webwork-default" namespace="/i18nic"&gt;<br />  &lt;interceptors&gt;<br />   &lt;interceptor name="i18n" class="com.opensymphony.xwork.interceptor.I18nInterceptor"&gt;<br />       &lt;param name="parameterName"&gt;locale&lt;/param&gt;<br />       &lt;param name="attributeName"&gt;ww_locale&lt;/param&gt;<br />   &lt;/interceptor&gt;<br />   <br />   &lt;interceptor-stack name="i18nStack"&gt;<br />       &lt;interceptor-ref name="i18n"/&gt;<br />       &lt;interceptor-ref name="defaultStack"/&gt;<br />   &lt;/interceptor-stack&gt;<br />  &lt;/interceptors&gt;</p><p>  &lt;default-interceptor-ref name="i18nStack"/&gt;</p><p>     &lt;action name="index" class="com.jscud.ww2test.i18nic.I18nIcAction"&gt;<br />      &lt;result name="success" type="dispatcher"&gt;<br />    &lt;param name="location"&gt;/i18nic/index.jsp&lt;/param&gt;<br />   &lt;/result&gt;<br />     &lt;/action&gt;<br /> &lt;/package&gt; </p></td></tr></tbody></table><br /> <br />所有的工作都好了,<strong>发布并运行访问</strong> /i18nic/index.action,一切和预想的一样.<p><br /><u>通过查看I18nInterceptor的源码,我们可以看到这个拦截器的工作原理是这样的</u>:</p><ol><li>如果参数中指定了locale,那么拦截器分析参数,并把locale保存到session中. </li><li>在后面的action中,拦截器从session中获取这个locale,并设置action的locale,从而保持用户的设置. </li><li>在后续页面还可以继续切换locale. </li></ol><p> </p><p><u>从源码分析结果来看,这样做也会有一些实际的问题</u>:</p><ol><li>session过期后,用户不知道发生了什么,系统使用缺省的locale. </li><li>只能影响通过action操作的页面 </li></ol><p> </p><p>在实际使用中,我们也要考虑如何解决后面2个问题,例如通过cookie,或者把用户的配置保存在数据库里等,这些实现就要结合实际代码进行实现了,完全可以不需要这个I18nInterceptor就可以实现,当然也很简单.</p><p></p></span>
		<br />
<img src ="http://www.blogjava.net/javaniu/aggbug/62847.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaniu/" target="_blank">Gary Niu</a> 2006-08-10 20:40 <a href="http://www.blogjava.net/javaniu/archive/2006/08/10/62847.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebWork 学习笔记（三）</title><link>http://www.blogjava.net/javaniu/archive/2006/08/10/62757.html</link><dc:creator>Gary Niu</dc:creator><author>Gary Niu</author><pubDate>Thu, 10 Aug 2006 03:38:00 GMT</pubDate><guid>http://www.blogjava.net/javaniu/archive/2006/08/10/62757.html</guid><wfw:comment>http://www.blogjava.net/javaniu/comments/62757.html</wfw:comment><comments>http://www.blogjava.net/javaniu/archive/2006/08/10/62757.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaniu/comments/commentRss/62757.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaniu/services/trackbacks/62757.html</trackback:ping><description><![CDATA[
		<b>注册验证类型</b>
		<br />
		<font face="Arial" size="3">
				<br />
		</font>
		<font face="Arial" size="3">一个验证类型一般是由一个类来提供。这个类必须实现<span style="background: white none repeat scroll 0%; font-size: 10pt; font-family: &quot;Courier New&quot;; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" lang="EN-US">com.opensymphony.xwork.validator.Validator，无需直接实现Validator接口，也可以从抽象类开始<br /><br />验证类在使用之前必须要在</span><span style="background: white none repeat scroll 0%; font-size: 10pt; font-family: &quot;Courier New&quot;; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" lang="EN-US">com.opensymphony.xwork.validator</span><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: black;" lang="EN-US">.<span style="background: white none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"> ValidatorFactory中注册，两种方法：<br /></span></span></font>
		<ul>
				<li>
						<font face="Arial" size="3">
								<span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: black;" lang="EN-US">
										<span style="background: white none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">使用ValidatorFactory的静态方法：</span>
								</span>
								<span style="background: white none repeat scroll 0%; font-size: 10pt; font-family: &quot;Courier New&quot;; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" lang="EN-US">registerValidator(String</span>
								<span style="background: white none repeat scroll 0%; font-size: 10pt; font-family: &quot;Courier New&quot;; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" lang="EN-US">
										<span style="color: black;">name,</span>
										<span style="color: black;">String</span>
										<span style="color: black;">className)</span>
								</span>
						</font>
				</li>
		</ul>
		<ul>
				<li>
						<font face="Arial" size="3">
								<span style="background: white none repeat scroll 0%; font-size: 10pt; font-family: &quot;Courier New&quot;; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" lang="EN-US">
										<span style="color: black;">使用配置文件：validators.xml，并把它放在classpath中</span>
								</span>
						</font>
				</li>
		</ul>
		<span style="background: white none repeat scroll 0%; font-size: 10pt; font-family: &quot;Courier New&quot;; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" lang="EN-US">
				<span style="color: black;">
						<font face="Arial" size="3">开启Action验证功能<br />在配置文件中提定拦截器，如下：<br />&lt;interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/&gt;<br /><br /></font>
				</span>
		</span>
<img src ="http://www.blogjava.net/javaniu/aggbug/62757.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaniu/" target="_blank">Gary Niu</a> 2006-08-10 11:38 <a href="http://www.blogjava.net/javaniu/archive/2006/08/10/62757.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebWork 学习笔记（二） </title><link>http://www.blogjava.net/javaniu/archive/2006/08/10/62732.html</link><dc:creator>Gary Niu</dc:creator><author>Gary Niu</author><pubDate>Thu, 10 Aug 2006 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/javaniu/archive/2006/08/10/62732.html</guid><wfw:comment>http://www.blogjava.net/javaniu/comments/62732.html</wfw:comment><comments>http://www.blogjava.net/javaniu/archive/2006/08/10/62732.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaniu/comments/commentRss/62732.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaniu/services/trackbacks/62732.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; tab-stops: right 415.3pt">
				<span lang="EN-US">
						<br />Action</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据</span>
				<span lang="EN-US">FormBean</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的不同可以分为二类，</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; tab-stops: right 415.3pt">
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一类是</span>
						<span lang="EN-US">Field-Driven</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（字段驱动的）</span>
						<span lang="EN-US">Action<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; tab-stops: right 415.3pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">   </span>Action</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将直接用自己的字段来充当</span>
				<span lang="EN-US">FormBean</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的功能，我们的例子就是使用这种方式。它一般用在页面表单比较简单的情况使用，而且可以直接用域对象作为</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的字段，这样就不用在另写</span>
				<span lang="EN-US">FormBean</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，减少了重复代码。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; tab-stops: right 415.3pt">
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">另一类是</span>
						<span lang="EN-US">Model-Driven</span>
				</b>
				<b style="mso-bidi-font-weight: normal">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（模型驱动的）</span>
						<span lang="EN-US">Action<o:p></o:p></span>
				</b>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt; tab-stops: right 415.3pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它很像</span>
				<span lang="EN-US">Struts</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span>
				<span lang="EN-US">FormBean</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，但在</span>
				<span lang="EN-US">WebWork</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，只要普通</span>
				<span lang="EN-US">Java</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象就可以充当模型部分。</span>
				<span lang="EN-US">Model-Driven</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（模型驱动的）</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要求我们的</span>
				<span lang="EN-US">Action</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现</span>
				<span lang="EN-US">com.opensymphony.xwork. ModelDriven</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口，它有一个方法：</span>
				<span lang="EN-US">Object getModel();</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，我们用这个方法返回我们的模型对象就可以了。<br /><br /><br /><strong>Model-Driven<br /></strong><br />1. Action要实现<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-highlight: white">ModelDriven.getModel()接口<br />2. 页面中的变化<br /></span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">&lt;form name="register" action="registerModel.action" method="post"&gt;</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 2">       </span>Username:&lt;input type="text" name="username"&gt;&lt;br&gt;</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 2">       </span>Password:&lt;input type="text" name="password"&gt;&lt;br&gt;</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 2">       </span>Email:&lt;input type="text" name="email"&gt;&lt;br&gt;</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 2">       </span>Age:&lt;input type="text" name="age"&gt;&lt;br&gt;</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 2">       </span>&lt;input type="submit" name="Submit"&gt;&lt;br&gt;<span style="mso-tab-count: 1">   </span></span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 1">    </span>&lt;/form&gt;</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt; tab-stops: right 415.3pt">
				<br />3. xwork.xml配置变化<br /></p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: #0000e1; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">&lt;action</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="COLOR: #0000e1">name=</span>
						<span style="COLOR: navy">"registerModel"</span>
						<span style="COLOR: #0000e1">class=</span>
						<span style="COLOR: navy">"example.register.RegisterActionModel"</span>
						<span style="COLOR: #0000e1">&gt;</span>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 2">       </span>
						<span style="COLOR: #0000e1">&lt;result</span>
						<span style="COLOR: #0000e1">name=</span>
						<span style="COLOR: navy">"success"</span>
						<span style="COLOR: #0000e1">type=</span>
						<span style="COLOR: navy">"dispatcher"</span>
						<span style="COLOR: #0000e1">&gt;</span>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 5pt; TEXT-INDENT: -5pt; TEXT-ALIGN: left; mso-char-indent-count: -.5; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 4">           </span>
						<span style="COLOR: #0000e1">&lt;param</span>
						<span style="COLOR: #0000e1">name=</span>
						<span style="COLOR: navy">"location"</span>
						<span style="COLOR: #0000e1">&gt;</span>
						<span style="COLOR: black">/register-result-model.jsp</span>
						<span style="COLOR: #0000e1">&lt;/param&gt;</span>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 2">       </span>
						<span style="COLOR: #0000e1">&lt;/result&gt;</span>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 2">      <font color="#ff3300"><strong></strong></font></span>
						<font color="#ff3300">
								<strong>
										<span style="COLOR: #0000e1">&lt;interceptor-ref</span>
										<span style="COLOR: #0000e1">name=</span>
										<span style="COLOR: navy">"model-driven"</span>
										<span style="COLOR: #0000e1">/&gt;</span>
								</strong>
						</font>
				</span>
				<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left">
				<font color="#ff3300">
						<strong>
								<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
										<span style="mso-tab-count: 2">       </span>
										<span style="COLOR: #0000e1">&lt;interceptor-ref</span>
										<span style="COLOR: #0000e1">name=</span>
										<span style="COLOR: navy">"params"</span>
										<span style="COLOR: #0000e1">/&gt;</span>
								</span>
								<span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt">
										<o:p>
										</o:p>
								</span>
						</strong>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="FONT-SIZE: 10pt; BACKGROUND: white; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt; mso-highlight: white">
						<span style="mso-tab-count: 1">    </span>
						<span style="COLOR: #0000e1">&lt;/action&gt;<br /><br /><font color="#000000"><font size="4"><strong>ActionContext<br /></strong></font><br />从Action里直接获取Request或Session的一些信息或对Response的响应操作<br /><br /></font></span>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span lang="EN-US">
						<font face="Times New Roman" size="3">ActionContext context = ActionContext.getContext();<br /></font>
				</span>
				<span lang="EN-US">
						<font face="Times New Roman" size="3">Map params = context.getParameters();<br /></font>
				</span>
				<span lang="EN-US">
						<font face="Times New Roman" size="3">String username = (String) params.get(“username”);</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<br />在每次执行Action之前都会创建新的ActionContext，ActionContext是线程安全的，也就是说在同一个线程里ActionContext里的属性是唯一的，这样我的Action就可以在多线程中使用。<br /><br /><font size="4"><strong><font color="#000000">ServletActionContext</font><br /></strong></font></p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt; tab-stops: right 415.3pt">
				<br /> 直接继承自ActionContext还提供了直接与JavaSevlet相关对象访问的功能，如：<br />1 <span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">HttpServletRequest <br /><br /><span lang="EN-US">例：HttpServletRequest request = ServletActionContext. getRequest();</span></span></p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt; tab-stops: right 415.3pt">
				<br />2 <span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">HttpServletResponse</span><br />3 <span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">ServletContext</span><br />4 <span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">ServletConfig</span><br />5 <span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">PageContext</span><br />6 HttpSession<br /><span lang="EN-US"><br />例：HttpSession session = ServletActionContext. getRequest().getSession();</span></p>
<img src ="http://www.blogjava.net/javaniu/aggbug/62732.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaniu/" target="_blank">Gary Niu</a> 2006-08-10 10:26 <a href="http://www.blogjava.net/javaniu/archive/2006/08/10/62732.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebWork 学习笔记（一）</title><link>http://www.blogjava.net/javaniu/archive/2006/08/10/62713.html</link><dc:creator>Gary Niu</dc:creator><author>Gary Niu</author><pubDate>Thu, 10 Aug 2006 01:12:00 GMT</pubDate><guid>http://www.blogjava.net/javaniu/archive/2006/08/10/62713.html</guid><wfw:comment>http://www.blogjava.net/javaniu/comments/62713.html</wfw:comment><comments>http://www.blogjava.net/javaniu/archive/2006/08/10/62713.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaniu/comments/commentRss/62713.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaniu/services/trackbacks/62713.html</trackback:ping><description><![CDATA[将%WEBWORK_HOME%\lib\default目录下所有jars放在WEB-INF\lib<br /><br />1 配置<span lang="EN-US" style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: 宋体; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">ServletDispatcher<br /><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;servlet&gt;<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;servlet-name&gt;webwork&lt;/servlet-name&gt;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;servlet-class&gt;com.opensymphony.webwork.dispatcher.ServletDispatcher&lt;/servlet-class&gt;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;/servlet&gt;<br /></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;servlet-mapping&gt;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;servlet-name&gt;webwork&lt;/servlet-name&gt;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;url-pattern&gt;*.action&lt;/url-pattern&gt;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;/servlet-mapping&gt;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><o:p><br />2 使用TagLib</o:p></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">&lt;%@ taglib prefix="ww" uri="webwork" %&gt;<br /><o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><br />3 配置xwork.xml<br /><br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"<br />"<a href="http://www.opensymphony.com/xwork/xwork-1.0.dtd">http://www.opensymphony.com/xwork/xwork-1.0.dtd</a>"&gt;<br />&lt;xwork&gt;<br /> &lt;include file="webwork-default.xml" /&gt;</p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> &lt;package name="default" extends="webwork-default"&gt;<br />  &lt;action name="hello" class="test.HelloWorldAction"&gt;<br />   &lt;result name="success" type="dispatcher"&gt;<br />    &lt;param name="location"&gt;/greetings.jsp&lt;/param&gt;<br />   &lt;/result&gt;<br />  &lt;/action&gt;<br /> &lt;/package&gt;<br />&lt;/xwork&gt;<br /><br /><strong>关于Action</strong><br /><br /></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">public interface Action extends Serializable {<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'"><span style="mso-spacerun: yes">    </span><o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'"><span style="mso-spacerun: yes">    </span>public static final String SUCCESS = "success";<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'"><span style="mso-spacerun: yes">    </span>public static final String NONE = "none";<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'"><span style="mso-spacerun: yes">    </span>public static final String ERROR = "error";<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'"><span style="mso-spacerun: yes">    </span>public static final String INPUT = "input";<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'"><span style="mso-spacerun: yes">    </span>public static final String LOGIN = "login";<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'"><span style="mso-spacerun: yes">    </span><o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'"><span style="mso-spacerun: yes">    </span>public String execute() throws Exception;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: 'Times New Roman'">}<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><br /> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><font size="3"><span lang="EN-US"><font face="Times New Roman">excute()</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法是</span><span lang="EN-US"><font face="Times New Roman">Action</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类里最重要的部分，它执行返回</span><span lang="EN-US"><font face="Times New Roman">String</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型的值，在</span><span lang="EN-US"><font face="Times New Roman">Action</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中返回的值一般使用它上面定义的标准静态字符常量。</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它与</span><span lang="EN-US"><font face="Times New Roman">xwork</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置文件里</span><span lang="EN-US"><font face="Times New Roman">result</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标签</span><span lang="EN-US"><font face="Times New Roman">name</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值是相对应的。它用来决定</span><span lang="EN-US"><font face="Times New Roman">execute</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（）方法执行完成之后，调用哪一种返回结果。字符常量的含义如下：</span></font></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><font size="3"><span lang="EN-US"><font face="Times New Roman">SUCCESS</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span><span lang="EN-US"><font face="Times New Roman">Action</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">正确的执行完成，返回相应的视图；</span></font></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><font size="3"><span lang="EN-US"><font face="Times New Roman">NONE</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：表示</span><span lang="EN-US"><font face="Times New Roman">Action</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">正确的执行完成，但并不返回任何视图；</span></font></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><font size="3"><span lang="EN-US"><font face="Times New Roman">ERROR</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：表示</span><span lang="EN-US"><font face="Times New Roman">Action</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">执行失败，返回到错误处理视图；</span></font></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><font size="3"><span lang="EN-US"><font face="Times New Roman">INPUT</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span><span lang="EN-US"><font face="Times New Roman">Action</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的执行，需要从前端界面获取参数，</span><span lang="EN-US"><font face="Times New Roman">INPUT</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就是代表这个参数输入的界面，一般在应用中，会对这些参数进行验证，如果验证没有通过，将自动返回到该视图；</span></font></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><font size="3"><span lang="EN-US"><font face="Times New Roman">LOGIN</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span><span lang="EN-US"><font face="Times New Roman">Action</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">因为用户没有登陆的原因没有正确执行，将返回该登陆视图，要求用户进行登陆验证。</span></font></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><br /> </p></span><img src ="http://www.blogjava.net/javaniu/aggbug/62713.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaniu/" target="_blank">Gary Niu</a> 2006-08-10 09:12 <a href="http://www.blogjava.net/javaniu/archive/2006/08/10/62713.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>