﻿<?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-java</title><link>http://www.blogjava.net/angel159/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 09:41:37 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 09:41:37 GMT</pubDate><ttl>60</ttl><item><title>java容器List和set的分析</title><link>http://www.blogjava.net/angel159/archive/2008/12/17/246814.html</link><dc:creator>angelspider</dc:creator><author>angelspider</author><pubDate>Wed, 17 Dec 2008 03:06:00 GMT</pubDate><guid>http://www.blogjava.net/angel159/archive/2008/12/17/246814.html</guid><wfw:comment>http://www.blogjava.net/angel159/comments/246814.html</wfw:comment><comments>http://www.blogjava.net/angel159/archive/2008/12/17/246814.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/angel159/comments/commentRss/246814.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/angel159/services/trackbacks/246814.html</trackback:ping><description><![CDATA[<div>&nbsp;</div>
<div>
<div class="blogstory"><span id="Post.ascx_ViewPost_PreviousAndNextEntriesUp">
<h3><a href="http://blog.csdn.net/wantgoworld/archive/2006/10/20/1342954.aspx" target="_blank"></a>&nbsp;</h3>
</span>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 容器类可以大大提高编程效率和编程能力，在Java2中，所有之容器都由SUN公司之JoshuaBloch进行了重新设计，丰富了容器类库之功能。 </p>
<div class="Vpn911"></div>
<p>&nbsp;</p>
<p style="text-indent: 2em">Java2容器类类库之用途是&#8220;保存对象&#8221;，它分为两类： </p>
<p class="Vpn911">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 2em">Collection----一组独立之元素，通常这些元素都服从某种规则。List必须保持元素特定之顺序，而Set不能有重复元素。 </p>
<p class="Vpn911">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 2em">Map----一组成对之&#8220;键值对&#8221;对象，即其元素是成对之对象，最典型之应用就是数据字典，并且还有其它广泛之应用。另外，Map可以返回其所有键组成之Set和其所有值组成之Collection，或其键值对组成之Set，并且还可以像数组一样扩展多维Map，只要让Map中键值对之每个&#8220;值&#8221;是一个Map即可。 <font color="#ffffff"></font></p>
<p style="text-indent: 2em">1.迭代器 </p>
<div class="Vpn911"></div>
<p>&nbsp;</p>
<p style="text-indent: 2em">迭代器是一种设计模式，它是一个对象，它可以遍历并选择序列中之对象，而开发人员不需要了解该序列之底层结构。迭代器通常被称为&#8220;轻量级&#8221;对象，因为创建它之代价小。 </p>
<p style="text-indent: 2em">Java中之Iterator功能比较简单，并且只能单向移动： </p>
<div class="Vpn911"></div>
<p>&nbsp;</p>
<p style="text-indent: 2em">(1)使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator之next()方法时，它返回序列之第一个元素。 </p>
<p class="Vpn911">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 2em">(2)使用next()获得序列中之下一个元素。 </p>
<div class="Vpn911"></div>
<p>&nbsp;</p>
<p style="text-indent: 2em">(3)使用hasNext()检查序列中是否还有元素。 </p>
<div class="Vpn911"></div>
<p>&nbsp;</p>
<p style="text-indent: 2em">(4)使用remove()将迭代器新返回之元素删除。 </p>
<div class="Vpn911"></div>
<p>&nbsp;</p>
<p style="text-indent: 2em">Iterator是Java迭代器最简单之实现，为List设计之ListIterator具有更多之功能，它可以从两个方向遍历List，也可以从List中插入和删除元素。 <font color="#ffffff"></font></p>
<p style="text-indent: 2em">2.List之功能方法 </p>
<div class="Vpn911"></div>
<p>&nbsp;</p>
<p style="text-indent: 2em">List(interface):次序是List最重要之特点；它确保维护元素特定之顺序。List为Collection添加了许多方法，使得能够向List中间插入与移除元素(只推荐LinkedList使用)。一个List可以生成ListIterator，使用它可以从两个方向遍历List，也可以从List中间插入和删除元素。 </p>
<p class="Vpn911">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 2em">ArrayList:由数组实现之List。它允许对元素进行快速随机访问，但是向List中间插入与移除元素之速度很慢。ListIterator只应该用来由后向前遍历ArrayList，而不是用来插入和删除元素，因为这比LinkedList开销要大很多。 </p>
<div class="Vpn911"></div>
<p>&nbsp;</p>
<p style="text-indent: 2em">LinkedList:对顺序访问进行了优化，向List中间插入与删除得开销不大，随机访问则相对较慢(可用ArrayList代替)。它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()，这些方法(没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。 </p>
<p class="Vpn911">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 2em">3.Set之功能方法 </p>
<p class="Vpn911">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 2em">Set(interface):存入Set之每个元素必须是唯一之，因为Set不保存重复元素。加入Set之Object必须定义equals()方法以确保对象之唯一性。Set与Collection有完全一样之接口。Set接口不保证维护元素之次序。 <font color="#ffffff"></font></p>
<p style="text-indent: 2em">HashSet:为快速查找而设计之Set。存入HashSet之对象必须定义hashCode()。 </p>
<p style="text-indent: 2em">TreeSet:保持次序之Set，底层为树结构。使用它可以从Set中提取有序之序列。 </p>
<p class="Vpn911">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-indent: 2em">LinkedHashSet:具有HashSet之查询速度，且内部使用链表维护元素之顺序(插入之次序)。于是在使用迭代器遍历Set时，结果会按元素插入之次序显示。 <font color="#ffffff"></font></p>
<p style="text-indent: 2em">HashSet采用散列函数对元素进行排序，这是专门为快速查询而设计之；TreeSet采用红黑树之数据结构进行排序元素；LinkedHashSet内部使用散列以加快查询速度，同时使用链表维护元素之次序，使得看起来元素是以插入之顺序保存之。需要注意之是，生成自己之类时，Set需要维护元素之存储顺序，因此要实现Comparable接口并定义compareTo()方法。</p>
</div>
</div>
<img src ="http://www.blogjava.net/angel159/aggbug/246814.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/angel159/" target="_blank">angelspider</a> 2008-12-17 11:06 <a href="http://www.blogjava.net/angel159/archive/2008/12/17/246814.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Strust组件—RequestProcessor类详解 </title><link>http://www.blogjava.net/angel159/archive/2008/12/17/246799.html</link><dc:creator>angelspider</dc:creator><author>angelspider</author><pubDate>Wed, 17 Dec 2008 03:04:00 GMT</pubDate><guid>http://www.blogjava.net/angel159/archive/2008/12/17/246799.html</guid><wfw:comment>http://www.blogjava.net/angel159/comments/246799.html</wfw:comment><comments>http://www.blogjava.net/angel159/archive/2008/12/17/246799.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/angel159/comments/commentRss/246799.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/angel159/services/trackbacks/246799.html</trackback:ping><description><![CDATA[<div>&nbsp;</div>
<div>&nbsp;<a href="http://ltc603.javaeye.com/blog/69279" target="_blank"><font color="#e9650e">Strust组件—RequestProcessor类详解 </font></a></div>
<div>Struts框架只允许应用中存在一个ActionServlet类,但是可以存在多个客户化的RequestProcessor类,每个子应用模块都可以有单独的RequestProcessor类, <br />
<br />
ActionServlet主要负责初始化,以及介绍请求并找到合适的RequestRrocessor,之后真正干活的是RequestProecssor和Action. <br />
上回说到ActionServlet的process方法最终会调用RequestProcessor类的process方法.下面介绍这个方法. <br />
<strong><span style="color: red">一.RequestProcessor的process方法</span></strong></div>
<div>&nbsp;Java代码 <br />
public void process(HttpServletRequest request,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse response)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws IOException, ServletException {</div>
<div><span class="comment"><font color="#008200">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;Wrap&nbsp;multipart&nbsp;requests&nbsp;with&nbsp;a&nbsp;special&nbsp;wrapper&nbsp;</font></span><span>&nbsp;&nbsp;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request = processMultipart(request);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Identify the path component we will use to select a mapping<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String path = processPath(request, response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (path == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (log.isDebugEnabled()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.debug("Processing a '" + request.getMethod() +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "' for path '" + path + "'");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Select a Locale for the current user if requested<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processLocale(request, response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Set the content type and no-caching headers if requested<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processContent(request, response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processNoCache(request, response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // General purpose preprocessing hook<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!processPreprocess(request, response)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.processCachedMessages(request, response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Identify the mapping for this request<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionMapping mapping = processMapping(request, response, path);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mapping == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Check for any role required to perform this action<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!processRoles(request, response, mapping)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Process any ActionForm bean related to this request<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionForm form = processActionForm(request, response, mapping);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processPopulate(request, response, form, mapping);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Validate any fields of the ActionForm bean, if applicable<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!processValidate(request, response, form, mapping)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (InvalidCancelException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionForward forward = processException(request, response, e, form, mapping);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processForwardConfig(request, response, forward);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IOException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw e;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (ServletException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw e;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Process a forward or include specified by this mapping<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!processForward(request, response, mapping)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!processInclude(request, response, mapping)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create or acquire the Action instance to process this request<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Action action = processActionCreate(request, response, mapping);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (action == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Call the Action instance itself<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionForward forward =<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processActionPerform(request, response,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; action, form, mapping);</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Process the returned ActionForward instance<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processForwardConfig(request, response, forward);</div>
<div>&nbsp;&nbsp;&nbsp; } </div>
<div>1)<span style="color: red"> 调用processMultipart()方法</span> <br />
如果HTTP请求方式为post,并且contentType为&#8221;multipart/form-data&#8221;开头,标准的HttpServletRequest对象将被重新包装,以方便处理&#8221;multipart&#8221;类型的HTTP请求.如果请求方式为get,或正congtentType属性不是&#8221;mulitipart&#8221;,就直接返回原始的HttpServletRequest对象. <br />
<br />
<span style="color: red">2) 调用processPath()方法</span> <br />
获得请求的URI的路径,这一信息可用于选择合适的Struts Action组件. <br />
<br />
<span style="color: red">3) 调用processLocale方法</span> <br />
当ControllerConfig对象的locale属性为true,将读取用户请求中包含的Locale信息,然后把Locale实例保存在session范围内. <br />
<br />
<span style="color: red">4) 调用processContendType(contentType)方法</span> <br />
读取ControllerConfig对象的conttentType属性,然后调用response.setContentType(contentType)方法,设置响应结果的文档类型和字符编码</div>
<div>processContent()方法如下 </div>
<div>&nbsp;protected void processContent(HttpServletRequest request,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse response) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String contentType = moduleConfig.getControllerConfig().getContentType();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (contentType != null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.setContentType(contentType);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;&nbsp;&nbsp; } </div>
<div><span style="color: red">5) 调用processNoCache()方法</span> </div>
<div>读取ControllerConfig对象的nocache属性,如果nocache属性为true,在响应结果中将加入特定的头参数:Pragma,Cache-Control和Expires, <br />
防止页面被存储在客户的浏览器的缓存中,processNoCache方法的代码如下: </div>
<div>protected void processNoCache(HttpServletRequest request,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse response) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (moduleConfig.getControllerConfig().getNocache()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.setHeader("Pragma", "No-cache");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.setHeader("Cache-Control", "no-cache,no-store,max-age=0");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; response.setDateHeader("Expires", 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;</div>
<div><span style="color: red">6)调用processPreprocess()方法</span> <br />
该方法不执行任何操作.直接返回true.子类可以覆盖这个方法. <br />
执行客户化的预处理请求操作. <br />
<br />
<span style="color: red">7)调用processMapping()方法</span> <br />
寻找和用户请求的URI匹配的ActionMapping,如果不存在这样的ActionMapping,则向用户返回恰当的错误信息. <br />
<br />
<span style="color: red">8)调用processRoles()方法</span> <br />
先判断是否为Action配置了安全角色,如果配置了安全角色,就调用isUserInRole()方法判断当前用户是否具备必需的角色,如果不具备,就结束请求处理流程.,向用户返回恰当的错误消息. <br />
<br />
<span style="color: red">9)调用processActionForm()方法</span> <br />
先判断是否为ActionMapping配置了ActionForm,如果配置了ActionForm,就先从ActionForm的存在范围内（request或session）寻找改ActionForm实例,如果不存在,就创建一个实例,接下来把它保存在合适的范围内,保存时使用的属性key为ActionMapping的name属性。 <br />
<br />
<span style="color: red">10）调用processPopulate()方法</span> <br />
如果为ActionMapping配置了ActionForm，就先调用ActionForm的reset（）方法，再把请求中的表单数据组装到ActionForm中。 <br />
<br />
<span style="color: red">11）调用processValidate（）方法</span> <br />
如果为ActionMapping配置了ActionForm，并且ActionMapping的validate属性为true，就调用ActionForm的validate（）方法，如果validate方法返回的ActionErrors对象中包含ActionMessage对象，说明表单验证失败。就把ActionErrors对象放在request范围内，再把请求转发到ActionMapping的input属性指定的Web组件。如果ActionForm的validate方法执行表单验证成功，就继续执行下面的处理流程。 <br />
<br />
<span style="color: red">12）调用processForward()方法</span> <br />
判断是否在ActionMapping中配置了forward属性。如果配置了这个属性，就调用RequestDispatcher的forward方法，请求处理流程结束。否则进行下一步。 <br />
<br />
<span style="color: red">13）调用processInclude()方法</span> <br />
判断是否在ActionMapping中配置了include属性。如果配置了这个属性，就调用RequestDispatcher的include方法，请求处理流程结束。否则进行下一步。 <br />
<br />
<span style="color: red">14）调用processActionCreate（）方法</span> <br />
先判断是否在Action缓存中存在这个Action实例，如果没有就新建一个Action实例，把它放在Action缓存中。可以看出Action也是只有一个实例在运行的。 <br />
<br />
<span style="color: red">15）调用processActionPerform</span> <br />
该方法调用Action实例的execute方法，该方法位于try/catch中，以及捕获异常。processActionPerform（）方放代码如下。 <br />
<br />
&nbsp;protected ActionForward<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processActionPerform(HttpServletRequest request,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse response,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Action action,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionForm form,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ActionMapping mapping)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws IOException, ServletException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (action.execute(mapping, form, request, response));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (processException(request, response,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e, form, mapping));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
} </div>
<div><br />
<span style="color: red">16)调用processActionForward方法</span> <br />
把你的Action的excute方法返回的ActionFoward对象作为参数传给它，processActionForward对象包的请求转发信息来执行请求转发或重定向。 <br />
<br />
在RequestProcessor类的process方法中，会访问ControllerConfig、ActionMappig和ActionForward实力的属性，ControllerConfig类和struts配置文件的&lt;controlle&gt;r元素对应，ActionMapping类和&lt;action&gt;元素对应，ActionForward和&lt;forward&gt;元素对应，process方法通过访问这三个类实例的属性来获得相关的配置信息。 <br />
写了这么多，RequestProcessor干得事够多的吧。 <br />
<span style="color: red"><strong>二．扩展RequestProcessor类</strong></span> <br />
如果想修改RequestProcessor的一些默认功能,改易覆盖RequestProcessor基类中的相关方法. <br />
Public class CustomRequestProcessor extends RequestProcessor{<br />
&nbsp; protected void processPreprocess (HttpServletRequest request,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpServletResponse response) { <br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<br />
}<br />
}</div>
<div>在struts配置文件中，&lt;controller&gt;元素的processorClass属性用于配置你自己的RequestProcessor类</div>
<div>&lt;/controller <br />
contentType＝&#8220;text/html:charset=&#8221;GB2312&#8221;<br />
locale=&#8221;true&#8221; nocache=&#8221;true&#8221; processorCalss=&#8221;com.test.CustomRequestProcessor&#8221;/&gt;</div>
<br />
<br />
<hr />
<font style="font-size: 12px; line-height: 15px">[广告] </font><font style="font-size: 12px; line-height: 15px">金秋最</font><a style="font-size: 12px; color: blue; line-height: 15px; text-decoration: underline" href="http://popme.163.com/link/003985_1010_7027.html" target="_blank">关注楼盘-房不胜房</a> 
<img src ="http://www.blogjava.net/angel159/aggbug/246799.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/angel159/" target="_blank">angelspider</a> 2008-12-17 11:04 <a href="http://www.blogjava.net/angel159/archive/2008/12/17/246799.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Strust组件—Action类详解 </title><link>http://www.blogjava.net/angel159/archive/2008/12/17/246797.html</link><dc:creator>angelspider</dc:creator><author>angelspider</author><pubDate>Wed, 17 Dec 2008 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/angel159/archive/2008/12/17/246797.html</guid><wfw:comment>http://www.blogjava.net/angel159/comments/246797.html</wfw:comment><comments>http://www.blogjava.net/angel159/archive/2008/12/17/246797.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/angel159/comments/commentRss/246797.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/angel159/services/trackbacks/246797.html</trackback:ping><description><![CDATA[<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;
<div class="tit">
<div class="blog_title">
<div class="date" align="center">&nbsp;<a href="http://ltc603.javaeye.com/blog/69353" target="_blank"><font color="#e9650e"><u><strong>Strust组件—Action类详解</strong> </u></font></a></div>
<h3 class="" title=""><a href="http://ltc603.javaeye.com/blog/69353" target="_blank"><font color="#e9650e"></font></a>&nbsp;</h3>
</div>
<div class="blog_content">Action类是用户请求和业务逻辑之间的桥梁，每个Action充当客户的一项业务代理。在RequestProcessor类预处理请求时，在创建了Action的实例后，就调用自身的processActionPerform（）方法，该方法在调用Action类的execute（）。 <br />
Action的excute（）方法调用模型的业务方法，完成用户请求，然后根据执行结果把请求转发给其他合适的WEB组件。 <br />
<br />
<span style="color: red">一、Action类缓存</span> <br />
<br />
struts应用的生命周期中RequestProcessor只保证一个Action实例,所有的客户请求都共享这个实例.所有请求可以同时执行它的excute（）方法。RequestProcessor类包含一个HashMap，作为存放所有Action实例的缓存。每个Action实例在缓存中存放的key为Action类名。在RequestProcessor类的processActionCreate()方法中，首先检查在HashMap中是否存在Action实例，如果有直接使用，否则创建一个新的。创建Action实力的代码位于同步代码块中，以保证只有一个线程创建Action实例，然后放在HashMap中。供其他线程使用。 <br />
如下代码
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" href="http://ltc603.javaeye.com/blog/69353#" target="_blank" on_click="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"><img alt="复制代码" src="http://ltc603.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword"><strong><font color="#7f0055">protected</font></strong></span><span>&nbsp;Action&nbsp;processActionCreate(HttpServletRequest&nbsp;request, &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response, &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionMapping&nbsp;mapping) &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">throws</font></strong></span><span>&nbsp;IOException&nbsp;{ &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Acquire&nbsp;the&nbsp;Action&nbsp;instance&nbsp;we&nbsp;will&nbsp;be&nbsp;using&nbsp;(if&nbsp;there&nbsp;is&nbsp;one) </font></span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;className&nbsp;=&nbsp;mapping.getType(); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">if</font></strong></span><span>&nbsp;(log.isDebugEnabled())&nbsp;{ &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.debug(</span><span class="string"><font color="#0000ff">"&nbsp;Looking&nbsp;for&nbsp;Action&nbsp;instance&nbsp;for&nbsp;class&nbsp;"</font></span><span>&nbsp;+&nbsp;className); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;:TODO:&nbsp;If&nbsp;there&nbsp;were&nbsp;a&nbsp;mapping&nbsp;property&nbsp;indicating&nbsp;whether </font></span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;an&nbsp;Action&nbsp;were&nbsp;a&nbsp;singleton&nbsp;or&nbsp;not&nbsp;([true]), </font></span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;could&nbsp;we&nbsp;just&nbsp;instantiate&nbsp;and&nbsp;return&nbsp;a&nbsp;new&nbsp;instance&nbsp;here? </font></span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Action&nbsp;instance&nbsp;=&nbsp;</span><span class="keyword"><strong><font color="#7f0055">null</font></strong></span><span>; &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">synchronized</font></strong></span><span>&nbsp;(actions)&nbsp;{ &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Return&nbsp;any&nbsp;existing&nbsp;Action&nbsp;instance&nbsp;of&nbsp;this&nbsp;class </font></span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance&nbsp;=&nbsp;(Action)&nbsp;actions.get(className); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">if</font></strong></span><span>&nbsp;(instance&nbsp;!=&nbsp;</span><span class="keyword"><strong><font color="#7f0055">null</font></strong></span><span>)&nbsp;{ &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">if</font></strong></span><span>&nbsp;(log.isTraceEnabled())&nbsp;{ &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.trace(</span><span class="string"><font color="#0000ff">"&nbsp;&nbsp;Returning&nbsp;existing&nbsp;Action&nbsp;instance"</font></span><span>); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">return</font></strong></span><span>&nbsp;(instance); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Create&nbsp;and&nbsp;return&nbsp;a&nbsp;new&nbsp;Action&nbsp;instance </font></span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">if</font></strong></span><span>&nbsp;(log.isTraceEnabled())&nbsp;{ &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.trace(</span><span class="string"><font color="#0000ff">"&nbsp;&nbsp;Creating&nbsp;new&nbsp;Action&nbsp;instance"</font></span><span>); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">try</font></strong></span><span>&nbsp;{ &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance&nbsp;=&nbsp;(Action)&nbsp;RequestUtils.applicationInstance(className); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;:TODO:&nbsp;Maybe&nbsp;we&nbsp;should&nbsp;propagate&nbsp;this&nbsp;exception </font></span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;instead&nbsp;of&nbsp;returning&nbsp;null. </font></span><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword"><strong><font color="#7f0055">catch</font></strong></span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error( &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getInternal().getMessage(</span><span class="string"><font color="#0000ff">"actionCreate"</font></span><span>,&nbsp;mapping.getPath()), &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.sendError( &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse.SC_INTERNAL_SERVER_ERROR, &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getInternal().getMessage(</span><span class="string"><font color="#0000ff">"actionCreate"</font></span><span>,&nbsp;mapping.getPath())); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">return</font></strong></span><span>&nbsp;(</span><span class="keyword"><strong><font color="#7f0055">null</font></strong></span><span>); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance.setServlet(</span><span class="keyword"><strong><font color="#7f0055">this</font></strong></span><span>.servlet); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actions.put(className,&nbsp;instance); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong><font color="#7f0055">return</font></strong></span><span>&nbsp;(instance); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre class="java" style="display: none; font-family: 宋体" name="code">  protected Action processActionCreate(HttpServletRequest request,
HttpServletResponse response,
ActionMapping mapping)
throws IOException {
// Acquire the Action instance we will be using (if there is one)
String className = mapping.getType();
if (log.isDebugEnabled()) {
log.debug(" Looking for Action instance for class " + className);
}
// :TODO: If there were a mapping property indicating whether
// an Action were a singleton or not ([true]),
// could we just instantiate and return a new instance here?
Action instance = null;
synchronized (actions) {
// Return any existing Action instance of this class
instance = (Action) actions.get(className);
if (instance != null) {
if (log.isTraceEnabled()) {
log.trace("  Returning existing Action instance");
}
return (instance);
}
// Create and return a new Action instance
if (log.isTraceEnabled()) {
log.trace("  Creating new Action instance");
}
try {
instance = (Action) RequestUtils.applicationInstance(className);
// :TODO: Maybe we should propagate this exception
// instead of returning null.
} catch (Exception e) {
log.error(
getInternal().getMessage("actionCreate", mapping.getPath()),
e);
response.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
getInternal().getMessage("actionCreate", mapping.getPath()));
return (null);
}
instance.setServlet(this.servlet);
actions.put(className, instance);
}
return (instance);
}</pre>
<br />
<br />
<span style="color: red">二．创建支持多线程的Action</span> <br />
1.什么是线程安全的代码 <br />
在多线程环境下能正确执行的代码就是线程安全的。 <br />
安全的意思是能正确执行，否则后果是程序执行错误，可能出现各种异常情况。 <br />
<br />
2.如何编写线程安全的代码 <br />
很多书籍里都详细讲解了如何这方面的问题，他们主要讲解的是如何同步线程对共享资源的使用的问题。主要是对synchronized关键字的各种用法，以及锁的概念。 <br />
Java1.5中也提供了如读写锁这类的工具类。这些都需要较高的技巧，而且相对难于调试。 <br />
<br />
但是，线程同步是不得以的方法,是比较复杂的,而且会带来性能的损失。等效的代码中，不需要同步在编写容易度和性能上会更好些。 <br />
我这里强调的是什么代码是始终为线程安全的、是不需要同步的。如下: <br />
1)常量始终是线程安全的，因为只存在读操作。 <br />
2)对构造器的访问(new 操作)是线程安全的，因为每次都新建一个实例，不会访问共享的资源。 <br />
3)最重要的是:局部变量是线程安全的。因为每执行一个方法，都会在独立的空间创建局部变量，它不是共享的资源。局部变量包括方法的参数变量。 <br />
<br />
Servlet是在多线程环境下的。即可能有多个请求发给一个servelt实例，每个请求是一个线程。 struts下的action也类似，同样在多线程环境下，你也必须编写线程安全的Action类。 <br />
保证线程安全的原则就是仅仅使用局部变量，谨慎使用实例变量（拥有状态的实例,尤其是拥有业务对象状态的实例）. 如果要用到那些有状态的实例,唯一和最好的办法是在Action类中，仅仅在Action类的execute()方法中使用局部变量,对于每个调用execute()方法的线程,JVM会在每个线程的堆栈中创建局部变量,因此每个线程拥有独立的局部变量，不会被其他线程共享.当线程执行完execute()方法后，它的局部变量就会被销毁. <br />
如果Action类的实例变量是必须的话，需要采用JAVA同步机制（synchronized）对访问共享资源的代码块进行同步 <br />
<br />
<br />
<span style="color: red">三、Struts的几种Action</span> <br />
Struts提供了一些现成的Action类，直接使用可以大大节省时间，如下 <br />
ForwardAction <br />
可以转发到其他web组件，仅仅提供一个转发功能，不作处理。 <br />
IncludeAction <br />
包含其他web组件。 <br />
DiapatchAction <br />
通常一个Action只完成一个操作，用这个Action可以完成一组相关的操作。 <br />
LookupDispatchAction <br />
他是DiapatchAction的子类，也可以定义多个方法，但主要用于一个表单里有多个按钮，而这些按钮又有一个共同的名字的场合。 <br />
SwitchAction <br />
用于子模块之间的切换。 <br />
<br />
<br />
<span style="color: red">四．ActionForward类</span> <br />
Action类的excute（）方法返回一个ActionForward对象，它代表了web资源的逻辑抽象，这里的web资源可以是jsp页面、Java servlet、或Action。 <br />
从excute返回ActionForward可以有两种方法。 <br />
1） 动态创建一个ActionForward实例 <br />
return new ActionForward（&#8221;Failure&#8221;，&#8221;login.jsp&#8221;,true）； <br />
2) 调用ActionMappin实例的findForward方法 <br />
这个方法先从action级别找，然后在&lt;global-forwards /&gt;级别找 <br />
return mapping.findForward(&#8220;Failure&#8221;); </div>
</div>
<div class="date"><font size="3">2007-08-03 16:58</font></div>
<div class="date"><font size="3"></font>&nbsp;</div>
<div class="date"><font size="3"></font>&nbsp;</div>
<div class="date"><font size="3">struts 的几个action</font></div>
<table class="FCK__ShowTableBorders" style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt">
            <p><font size="3">除了基本的Action 之外， Struts 还提供了几个其他类型的Action ，这些Action 大大<br />
            丰富了Struts 的功能。下面介绍如下儿个常用的Action 。<br />
            &#8226; DispatchAction: 能同时完成多个Action 功能的Action 。<br />
            &#8226; ForwardActon: 该类用来整合Struts 和其他业务逻辑组件，通常只对请求作有效<br />
            性检查。<br />
            &#8226; IncludeAction: 用于引入其他的资源和页面。<br />
            &#8226; LookupDispatchAction: DispatchAction 的子类，根据按钮的key ，控制转发给action<br />
            的方法。<br />
            &#8226; MappingDispatchAction: DispatchAction 的子类，一个action 可映射出多个Action<br />
            地址。<br />
            &#8226; SwitchAction: 用于从一个模块转换至另一个模块，如果应用分成多个模块时，</font></p>
            <p><font size="3">就可以使用SwitchAction 完成模块之间的切换。<br />
            下面对常用的Action 进行介绍。<br />
            <strong>3.11.1 DispatchAction 及其子类</strong><br />
            DispatchAction 是仅次于Action，使用最频繁的Action。用于同一个表单中有两个提<br />
            交按钮时，但提交需要的逻辑处理完全不同的情况。如图3.28 所示为登录页面。<br />
            图3.28 两个提交按钮的表单页<br />
            该页面包含了两个提交按钮，但提交按钮需要执行的逻辑却不一样。最容易想到的<br />
            解决方法是，为每个按钮增加JavaScipt脚本，提交两个按钮时候分别提交给不同的Action<br />
            处理。这是最容易想到，也最麻烦的方式。<br />
            Struts 提供了DispatchAction，可支持多个逻辑处理。对于上面的示例，表单需要两<br />
            个逻辑处理:增加和修改。下面是示例所使用的Action 类的源代码:<br />
            public class LoginAction extends DispatchAction<br />
            {<br />
            II 第一个处理逻辑<br />
            public ActionForward add(ActionMapp工ng mapping , ActionForm form ,<br />
            HttpServletRequest request , HttpServletResponse response)<br />
            throws Exception<br />
            System.out.println( "增加") ;<br />
            request. setAt tribute ("method" , "增加") ;<br />
            return mapping.findForward("success");<br />
            II第二个处理逻辑<br />
            public ActionForward modify(ActionMapping mapping , ActionForm form ,<br />
            HttpServletRequest request , HttpServletResponse response)<br />
            throws Exception<br />
            System.out.println(" 修改") ;<br />
            request. setAttribute ("method&#8220;,</font><font size="3">"修改") ;<br />
            return mapping.findForward("success"};<br />
            上面的Action 非常简单，其两个逻辑处理也非常简单。该Action 并没有重写execute<br />
            方法，而是书写了两个自定义的方法:add 和modi句。这两个方法除了方法名与execute<br />
            </font></p>
            <p><font size="3">方法不同之外，其他的参数列表及异常的处理完全相同。这两个方法正是execute 方法<br />
            的替代，用于完成业务逻辑的处理。<br />
            问题的关键是: Struts 如何区别不同表单提交与方法之间的对应关系?因为当使用<br />
            DispatchAction 要求表单提交时，会额外多传递一个参数，该参数用于区分到底调用<br />
            Action 中的哪个方法。<br />
            这个参数名在struts-config.xml 文件中指定。注意下面action 的配置代码:<br />
            &lt;action path="/login" type="lee.LoginAct工on ll name="1og inForm"<br />
            scope="request" validate="true" input="/login.jsp" parameter="method"&gt;<br />
            &lt;forward name="success" path="/welcome.jsp"/&gt;<br />
            &lt;fact工on&gt;<br />
            在该action 的配置中，增加了parameter属性，该属性用于指定参数名，即Struts 将<br />
            根据该参数的值调用对应的方法。为了让请求增加method 的参数，对上面的JSP 页面代<br />
            码进行简单修改，可在JSP 页面中增加一个隐藏域，使该隐藏域的名字为method。下面<br />
            是JSP 页面的表单代码:<br />
            &lt;html:form action="login.do"&gt;<br />
            &lt;table border="O" width="100"&gt;<br />
            &lt;tr&gt;<br />
            &lt;th align="left"&gt;&lt;bean:message key="username"/&gt;&lt;/th&gt;<br />
            &lt;td align="left"&gt;&lt;html:text property="username" size="15"/&gt;&lt;/td&gt;<br />
            &lt;/tr&gt;<br />
            &lt;tr&gt;<br />
            &lt;th align="left"&gt;&lt;bean:message key="pass"/&gt;&lt;/th&gt;<br />
            &lt;td align="left"&gt;&lt;html:text property="pass" s ize="15"/&gt;&lt;/td&gt;<br />
            &lt;/tr&gt;<br />
            &lt;tr&gt;<br />
            &lt;td&gt;<br />
            &lt;input type="hidden" name="method" value="add"/&gt;<br />
            &lt;input type="submit" value='&lt;bean:message key="button.add"/&gt;' onClick=<br />
            method.value='add'''/&gt;<br />
            &lt;input type="submit" value='&lt;bean:message key="button.modify"/&gt;'<br />
            onClick="method.value='modify'''/&gt;<br />
            &lt;input type="reset" value='&lt;bean:message key="button.reset"/&gt;'/&gt;<br />
            &lt;ltd&gt;<br />
            &lt;/tr&gt;<br />
            &lt;/table&gt;<br />
            &lt;/html:form&gt;<br />
            从上面的代码中可以看到，页面中增加了method 的隐藏域，该隐藏域的默认值为<br />
            add，当单击页面中的【修改】按钮时，该隐藏域的值将变成modify，单击【添加】按<br />
            钮时，该隐藏域的值变成add。这个隐藏域就是额外传递的参数值，用于告诉Dispatch<br />
            调用哪个方法来处理请求。<br />
            如果method 参数的值为add，将调用add 方法;如果method 参数的值为modify，<br />
            则调用modify 方法。因此在单击不同按钮时，DispatchAction将可自动调用对应的方法<br />
            来完成处理。<br />
            <strong>1. 使用MappingDispatchAction</strong><br />
            MappingDispatchAction可将同一个Action 的不同方法映射成多个Action URI ，这种</font></p>
            <p><font size="3">Action 的写法与DispatchAction 非常相似，同样不需要重写execute 方法，而是将书写多<br />
            个自定义的方法。这些方法除了方法名与execute 方法不同外，其他的参数列表及异常<br />
            处理完全一样。<br />
            下面是本示例所使用的Action 的源代码:<br />
            public class LoginAct工on extends MappingDispatchAction<br />
            II 第一个处理逻辑<br />
            public ActionForward add(ActionMapping mapping , ActionForm form ,<br />
            HttpServletRequest request , HttpServletResponse respo口se)<br />
            throws Exception<br />
            System.out.println("增加") ;<br />
            request.setAttribute( method" , "增加") ;<br />
            return mapping.findForward("success");<br />
            }<br />
            II 第二个处理逻辑<br />
            public ActionForward modify(ActionMapping mapping , ActionForm form ,<br />
            HttpServletRequest request , HttpServletResponse response)<br />
            throws Exception<br />
            System.out.println("修改") ;<br />
            request.setAttribute( mnethod" "修改") ;<br />
            return mapping.findForward("success");<br />
            该Action 与前面的DispatchAction 没有太大的区别，仅仅改变它的父类:<br />
            MappingDispatchAction，但变化在于该Action 的配置，看下面关于该Action 的配置代码:<br />
            &lt;1- 配置第一个Action. 实现类是lee.LoginAction , parameter 为add--&gt;<br />
            &lt;action path="/add" type="lee.LoginAction" name="loginForm"<br />
            scope="request" val idate="true" input="login.jsp" parameter="add"&gt;<br />
            &lt;forward name="success" path="/welcome.jsp"l&gt;<br />
            &lt;/action&gt;<br />
            &lt;! 配置第二个Action. 实现类是lee.LoginAction , parameter 为modify--&gt;<br />
            &lt;action path="/modify" type="lee.LoginAction" name="loginForm"<br />
            scope工"request" validate="true" input="login.jsp阴parameter="modify"&gt;<br />
            &lt;forward name="success" path="/welcome.jsp"l&gt;<br />
            &lt;/action&gt;<br />
            在这种情况下，两个action 使用的是同一个Action 处理类，只是调用的方法不同，同<br />
            样也可达到上面的效果。当然也需要为页面中的两个按钮增加相应的JavaScript脚本，当<br />
            单击不同按钮时，表单可提交到不同的action，下面是JSP 页面三个按钮的源代码:<br />
            &lt;td&gt;<br />
            &lt;input type="submit" value='&lt;bean:message key="button.add"/&gt;'<br />
            onClick="document.loginForm.action='add.do'''/&gt;<br />
            &lt;input type="submit" value='&lt;bean:message key="button.modify"I&gt;'<br />
            onClick="document.loginForm.action='modify.do'''I&gt;<br />
            &lt;input type="reset" value='&lt;bean:message key="button.reset"I&gt;'I&gt;<br />
            &lt;ltd&gt;<br />
            其中，前面两个提交按钮都增加了onClick 方法，即单击该按钮时，会改变表单的提<br />
            交地址。</font></p>
            <p><font size="3">注意:使用MappingDispatchAction 并没有带来太大的优势，系统完全可以书写两个<br />
            Action ，分别定义两个不同的action 映射，而其他部分没有区别。<br />
            </font><font size="3"><strong>2. f吏用LookupDispatchAction<br />
            </strong>LookupDispatchAction也是DispatchAction 的一种，但它的处理更加简单。该Action<br />
            也可包含多个处理方法，它可让处理方法与按钮直接关联，无须使用任何的JavaScript<br />
            脚本。<br />
            使用LookupDispatchAction时，提交按钮必须使用Struts 的html 标签，下面是该示<br />
            例按钮部分的源代码:<br />
            &lt;td&gt;<br />
            &lt;html:submit property="method"&gt;<br />
            &lt;bean:message key="button.add"l&gt;<br />
            &lt;/html:submit&gt;<br />
            &lt;html:submit property="method"&gt;<br />
            &lt;bean:message key="button.modify"l&gt;<br />
            &lt;/html:submit&gt;<br />
            &lt;input type="reset" value='&lt;bean:message key="button.reset"I&gt;'I&gt;<br />
            &lt;ltd&gt;<br />
            代码中两个提交按钮分别增加了property 属性，该属性的值为method。而在action<br />
            的配置中，也使用parameter作为参数，看下面的action 配置代码:<br />
            &lt;action path="/login" type="lee.LoginAction" name="loginForm"<br />
            scope="request" validate="true" input="/login.jsp" parameter="method"&gt;<br />
            &lt;forward name="success" path="/welcome.jsp"l&gt;<br />
            &lt;/action&gt;<br />
            这段配置代码表明:该action 也根据method 参数来区分请求分别调用哪个方法，此<br />
            时无须使用method 的隐藏域，而是将按钮的property 设为method。通过这种方式可以<br />
            避免书写JavaScript脚本。<br />
            因此可通过重写getKeyMethodMap方法完成按钮与Action 中方法的关联，下面是<br />
            该Action 的源代码:<br />
            public class LoginAction extends LookupDispatchAction<br />
            {<br />
            II 用于关联按钮和方法<br />
            protected Map getKeyMethodMap()<br />
            Map map = new HashMap();<br />
            II如果按钮标题的key 为button.add. 则提交该按钮时对应add 方法<br />
            map .put ("button. add" , "add");<br />
            II如果按钮标题的key 为button.modify. 则提交该按钮时对应modify 方法<br />
            map.put ("button.modify" , "modify") ;<br />
            return map;<br />
            }<br />
            II 第一个处理逻辑<br />
            public ActionForward add(ActionMapping mapping, ActionForm form ,<br />
            HttpServletRequest request , HttpServletResponse response)<br />
            throws Exception<br />
            System.out.println(" 增加II) i<br />
            request.setAttribute("method" , "增加") ;<br />
            return mapping.findForward(" success") ;<br />
            }<br />
            第二个处理逻辑<br />
            public ActionForward modify(ActionMapping mapping , ActionForm form ,<br />
            HttpServletRequest request , HttpServletResponse response)<br />
            throws Exception<br />
            System.out.println("修改II) ;<br />
            request.setAttribute(" method" , " 修改") ;<br />
            return mapping.findForward("success");<br />
            LookupDispatchAction必须重写getKeyMethodMap方法，该方法返回一个Map 对象，<br />
            并在该对象内保存了按钮标题与方法之间的对应。<br />
            <strong>3.11.2 使用ForwardAction</strong><br />
            如果需要从一个页面或资源转换到另一个资源时，直接使用页面或资源路径的超级<br />
            链接定位并不是好的做法，这使得控制器没有机会处理相关的请求事直。<br />
            使用ForwardAction可以完成请求的转发，当控制器调用ForwardAction的performO<br />
            方法时，它会使用属性parameter 所设定的路径进行forward 的动作。下面是一个设定<br />
            ForwardAction的例子:<br />
            &lt;actlon-mapplngs&gt;<br />
            &lt;action path="/welcome"<br />
            type="org.apache.struts.actions.ForwardAction"<br />
            parameter="/welcome.jsp"/&gt;<br />
            &lt;/action-mappings&gt;<br />
            该action 仅仅完成转发，并没有执行其他的额外动作。<br />
            页面控制转发的代码如下:<br />
            &lt;a href="welcome.do"&gt;转入&lt;/a&gt;<br />
            当单击转入超级链接时，将可以转向ForwardAction parameter指向的资源。<br />
            <strong>3.11.3 使用IncludeAction</strong><br />
            IncludeAction的用法与ForwardAction的用法比较相似，区别在于ForwardAction将<br />
            跳转到action 定义的资源，而IncludeAction用于引入该action 对应的资源。<br />
            下面是IncludeAction定义的源代码:<br />
            &lt;actio口-mapplngs&gt;<br />
            &lt;action path="/welcome"<br />
            type="org.apache. struts.actions. IncludeAction"<br />
            parameter="/welcome.jsp"/&gt;<br />
            &lt;/action-mappings&gt;</font></p>
            <p><font size="3">该action 用于经welcome.jsp 作为资源导入。<br />
            页面中负责加载该action 所导入资源的代码如下:<br />
            &lt;jsp:include page="welcome.do"/&gt;&lt;br&gt;<br />
            上面的代码将会把welcome action 定义的资源导入该页面。<br />
            <strong>3.11.4 使用SwitchAction</strong><br />
            SwitchAction 主要用于模块之间的切换。当一个应用之中存在多个模块时，使用<br />
            SwitchAction在不同模块之间的action 之间切换还是相当方便的。<br />
            在下面的web.xml 中，力日载了Struts 的两个配置文件，其中一个作为系统的一个模<br />
            块加载，该web.xml 的配置代码如下:<br />
            &lt;servlet&gt;<br />
            &lt;! 定义Struts 的核心控制器--&gt;<br />
            &lt;servlet-name&gt;action&lt;/servlet-name&gt;<br />
            &lt;servlet-class&gt;org.apache.struts.action.ActionServlet&lt;/servlet-class&gt;<br />
            &lt;'一指定Struts 的第一个配置文件--&gt;<br />
            &lt;lnlt-param&gt;<br />
            &lt;param-name&gt;config&lt;/param-name&gt;<br />
            &lt;param-value&gt;/WEB-INF/struts-con工fg.xml&lt;/param-value&gt;<br />
            &lt;/inlt-param&gt;<br />
            &lt;!一指定Struts 的第二个配置文件，作为wawa 模块配置一〉<br />
            &lt;lnlt-param&gt;<br />
            &lt;param-name&gt;config/wawa&lt;/param-name&gt;<br />
            &lt;param-value&gt;/WEB-INF/struts-configl.xml&lt;/param-value&gt;<br />
            &lt;/init-param&gt;<br />
            &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;<br />
            &lt;/servlet&gt;<br />
            该应用包括了一个wawa 的模块，并在struts-config1.xml 文件中配置一个action，该<br />
            action 的配置代码如下:<br />
            &lt;action-mapp工ngs&gt;<br />
            &lt;action path="/welcome" forward="/welcome.jsp"/&gt;<br />
            &lt;/action-mappings&gt;<br />
            该action 的定义非常简单，仅完成页面的转向。如果现在需要从应用的页面请求该<br />
            action，可以使用如下SwitchAction。<br />
            定义SwitchAction也相当简单，只需要定义path、type 属性即可。下面是SwitchAction<br />
            的定义代码:<br />
            &lt;action-mappings&gt;<br />
            &lt;action path="/moduleSwitch" type="org.apache.struts.actions.SwithcActio丑"/&gt;<br />
            &lt;/action-mappings&gt;<br />
            在使用SwitchAction 时，必须在请求中带两个参数:第一个是prefix，用来指定模<br />
            块宅称:另一个是page，用来指定相模块中的资源路径。下面是页面中超级链接对wawa<br />
            模块的welcome action 请求，页面的超级链接代码如下:<br />
            &lt;a href=doduleSwitch.do?prefix=/wawa&amp;page=/welcome.do转"&gt;入另一个模块&lt;/a&gt;<br />
            上面的超级链接地址中，/wawa是模块名，而page对应wawa模块下的welcome的actiono</font></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<br />
<br />
<hr />
<br />
<br />
<img src ="http://www.blogjava.net/angel159/aggbug/246797.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/angel159/" target="_blank">angelspider</a> 2008-12-17 11:01 <a href="http://www.blogjava.net/angel159/archive/2008/12/17/246797.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>