﻿<?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-【永恒的瞬间】  -文章分类-struts</title><link>http://www.blogjava.net/19851985lili/category/18360.html</link><description>☜Give me hapy ☞




</description><language>zh-cn</language><lastBuildDate>Thu, 29 May 2008 23:20:13 GMT</lastBuildDate><pubDate>Thu, 29 May 2008 23:20:13 GMT</pubDate><ttl>60</ttl><item><title>Struts使用Tiles辅助开发</title><link>http://www.blogjava.net/19851985lili/articles/203787.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 29 May 2008 04:31:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/203787.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/203787.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/203787.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/203787.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/203787.html</trackback:ping><description><![CDATA[对于在页面的布局管理以及可重用方面，Tiles做得很优秀，使我们在开发过程中思路非常流畅，特别是在用struts开发项目过程中，如果使用tiels来辅助开发，往往能带到事半功倍的效果。<br />
<br />
如果要看Tiles的详细文档，请访问<a href="http://www.lifl.fr/~dumoulin/tiles/">http://www.lifl.fr/~dumoulin/tiles/</a><br />
<br />
在此我想从使用方式上说一下自己的经验：<br />
<br />
往往我们的一个项目中，大部分的页面的布局都是一样的，这其中如果我们把一样风格的页面归为一类的话，这样的分类就不会很多了。（不同的项目这样的分类多少为有区别，要看页面风格规划的是否高效）<br />
<br />
假设我们提出一类页面（如产品管理）的风格，布局如下：<br />
<img src="http://www.csdn.net/Develop/ArticleImages/19/19985/CSDN_Dev_Image_2003-7-241402590.gif"  alt="" />&nbsp;<br />
那么我们可以在tiles-defs.xml中定义这样一个总的类型，如下：<br />
<br />
tiles-defs.xml&nbsp;&nbsp;放在/yourwebapp/WEB-INF/下<br />
<br />
<div class="codeStyle">
<ol>
    <li>&lt;?xml&nbsp;version=<font color="#ff33ff">"1.0"</font>&nbsp;encoding=<font color="#ff33ff">"ISO-8859-1"</font>&nbsp;?&gt;
    <li>&nbsp;&lt;!DOCTYPE&nbsp;tiles-definitions&nbsp;PUBLIC
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff33ff">"-//Apache&nbsp;Software&nbsp;Foundation//DTD&nbsp;Tiles&nbsp;Configuration&nbsp;1.1//EN"</font>
    <li><font color="#ff33ff">"http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd"</font>&gt;
    <li>&lt;tiles-definitions&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!―布局类型一&nbsp;--&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;definition&nbsp;name=<font color="#ff33ff">"mainLayout"</font>&nbsp;path=<font color="#ff33ff">"/homepage.jsp"</font>&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=<font color="#ff33ff">"top"</font>&nbsp;&nbsp;value=<font color="#ff33ff">"/header.jsp"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=<font color="#ff33ff">"menu"</font>&nbsp;&nbsp;&nbsp;&nbsp;value=<font color="#ff33ff">"/menu.jsp"</font>/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=<font color="#ff33ff">"main"</font>&nbsp;value=<font color="#ff33ff">"/main.jsp"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=<font color="#ff33ff">"footer"</font>&nbsp;value=<font color="#ff33ff">"/footer.jsp"</font>&nbsp;/&gt;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&lt;/definition&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!―布局类型二&nbsp;--&gt;
    <li>&nbsp;&nbsp;&lt;definition&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;
    <li>&nbsp;&nbsp;&lt;/definition&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;
    <li>&lt;/tiles-definitions&gt; </li>
</ol>
</div>
<br />
<br />
以上定义了一种布局类型，假设命名为A布局，下面要列举两个属于该类型风格的页面的布局方法添加产品页面，最终我们要关心的时addProducts.jsp这个页面，但是我们如何使用A布局的布局风格呢？<br />
<br />
如下：<br />
<br />
&#8230;&#8230;接上tiles-defs.xml&#8230;&#8230;<br />
<br />
<div class="codeStyle">
<ol>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!―布局类型A布局一&nbsp;--&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;definition&nbsp;name=<font color="#ff33ff">"mainLayout"</font>&nbsp;path=<font color="#ff33ff">"/homepage.jsp"</font>&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=<font color="#ff33ff">"top"</font>&nbsp;&nbsp;value=<font color="#ff33ff">"/header.jsp"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=<font color="#ff33ff">"menu"</font>&nbsp;&nbsp;&nbsp;&nbsp;value=<font color="#ff33ff">"/menu.jsp"</font>/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=<font color="#ff33ff">"main"</font>&nbsp;value=<font color="#ff33ff">"/main.jsp"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=<font color="#ff33ff">"footer"</font>&nbsp;value=<font color="#ff33ff">"/footer.jsp"</font>&nbsp;/&gt;&nbsp;&nbsp;&nbsp;
    <li>&lt;/definition&gt;
    <li>
    <li>&lt;!―布局类型A布局&#8220;子类1:添加商品&#8221;一&nbsp;--&gt;
    <li>&lt;definition&nbsp;name=&#8221;mainLayout_products_add&#8221;&nbsp;<strong><font color="#0000ff">extends</font></strong>=&#8221;&nbsp;mainLayout&#8221;&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=&#8221;main&#8221;&nbsp;value=&#8221;/addProducts.jsp&#8221;/&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!―相当于把布局A中main的内容换成我们需要的，其他保留&nbsp;--&gt;
    <li>&lt;/definition&gt;
    <li>&lt;!―布局类型A布局&#8220;子类2:查询商品&#8221;一&nbsp;--&gt;
    <li>&lt;definition&nbsp;name=&#8221;mainLayout_products_search&#8221;&nbsp;<strong><font color="#0000ff">extends</font></strong>=&#8221;&nbsp;mainLayout&#8221;&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;put&nbsp;name=&#8221;main&#8221;&nbsp;value=&#8221;/searchProducts.jsp&#8221;/&gt;
    <li>&lt;!―相当于把布局A中main的内容换成我们需要的，其他保留&nbsp;--&gt;
    <li>&lt;/definition&gt;
    <li>&#8230;&#8230;
    <li>&#8230;&#8230; </li>
</ol>
</div>
<br />
<br />
以上只是以一种布局类型来说明，其他的布局类型（如：布局B，布局C。。。。。）都用相通的方法扩展，没有什么难的地方。<br />
<br />
下面简要说一些tiles在struts-config.xml中的配置，在struts1.1种tiles是利用struts的扩展机制来完成装载的，代码很简单如下：<br />
<br />
<div class="codeStyle">
<ol>
    <li><em><font color="#339900">//struts-config.xml</font></em>
    <li>&nbsp;&nbsp;&#8230;&#8230;
    <li>&nbsp;&nbsp;&lt;plug-in&nbsp;className=<font color="#ff33ff">"org.apache.struts.tiles.TilesPlugin"</font>&nbsp;&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property&nbsp;property=<font color="#ff33ff">"definitions-config"</font>&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value=<font color="#ff33ff">"/WEB-INF/tiles-defs.xml"</font>&nbsp;/&gt;
    <li>&nbsp;&nbsp;&lt;/plug-in&gt; </li>
</ol>
</div>
<br />
<br />
如果你些多个tiles配置文件，那么用&#8220;，&#8221;号隔开。<br />
下面在举一个使用tiles以后action&nbsp;mapping&nbsp;的写法<br />
<br />
如我们要进行添加商品的请求，在添加页面里要先进行商品类型的装载：<br />
<br />
addProductAction.do――〉ProductAction――〉addProducts.jsp<br />
ProductAction完成商品类型的集合返回client端<br />
<div class="codeStyle">
<ol>
    <li><em><font color="#339900">//Struts-config.xml</font></em>
    <li>&#8230;&#8230;&#8230;&#8230;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;action&nbsp;path=&#8221;/&nbsp;addProductAction&#8221;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type=&#8221;com.***.&nbsp;ProductAction&#8221;&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!―成功以后返回布局A子类1--&nbsp;&gt;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;forward&nbsp;name=&#8221;&#8221;&nbsp;path=&#8221;&nbsp;mainLayout_products_add&#8221;&gt;
    <li>&lt;/action&gt;
    <li>&#8230;&#8230;&#8230;&#8230; </li>
</ol>
</div>
<br />
<br />
好了，以上对一个操作的流程采用tiles以后的写法进行了简要的说明，具体Tiles的文档请参看上面给出的连接。<br />
<br />
Struts发布包里也有tilse的文档和例子。<br />
<img src ="http://www.blogjava.net/19851985lili/aggbug/203787.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2008-05-29 12:31 <a href="http://www.blogjava.net/19851985lili/articles/203787.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为Struts应用配置web.xml文件 </title><link>http://www.blogjava.net/19851985lili/articles/98469.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Wed, 07 Feb 2007 00:23:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/98469.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/98469.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/98469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/98469.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/98469.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Web.xml												文件对于配置任何														Java Web												应用都是必须的														.												当配置														Struts												应用时														,												还应该在...&nbsp;&nbsp;<a href='http://www.blogjava.net/19851985lili/articles/98469.html'>阅读全文</a><img src ="http://www.blogjava.net/19851985lili/aggbug/98469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-07 08:23 <a href="http://www.blogjava.net/19851985lili/articles/98469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts框架</title><link>http://www.blogjava.net/19851985lili/articles/97670.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 02 Feb 2007 12:51:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/97670.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/97670.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/97670.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/97670.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/97670.html</trackback:ping><description><![CDATA[struts框架具有组件的模块化，灵活性和重用性的优点，同时简化了基于MVC的web应用程序的开发。<br />本章详细讨论struts架构。我们将看到struts是如何清晰地区分控制，事务逻辑和外观，从而简化了开发应用程序过程的。我们还将介绍struts提供的类如何使得开发工作更加简单，这些类包括：<br />l	控制程序流程的类<br />l	实现和执行程序事务逻辑的类<br />l	自定义的标记库使得创建和验证HTML表单更加容易<br />1．	Struts压缩包内容<br />文件夹jakarta-struts-1.0.2包含两个目录，lib和webapps。在lib目录中有使用struts创建应用程序是所需的文件：<br />文件	描述<br />jdbc2_0-stdext.jar	包含JDBC2.0 Optional Package API类。如果我们要使用struts提供的数据资源，就需要将这个文件拷贝到WEB-INF\lib下<br />Struts.jar	包含struts中所有的java类。同样也需要拷贝到WEB-INF\lib下<br />*.tld	标记库描述器文件，描述了多个struts标记库中的自定义标记。同样要拷贝到WEB-INF\lib下<br />在webapps目录下有如下文件：<br />Web应用程序	描述<br />Struts-blank.war	一个简单的web应用程序<br />Struts-documentation.war	包含struts站点上所有struts文档<br />Struts-example.war	Struts很多特性的示范<br />Struts-exercisetaglib.war	主要用于对自定义标签库进行增加而使用的测试页，但也可以示范如何使用struts标记<br />Struts-template.war	包含struts模板标记的介绍和范例<br />Struts-upload.war	一个简单的例子，示范如何使用struts框架上传文件<br />2.Struts体系结构<br />让我们从MVC角度观察struts框架中的组件<br /><br />框架中三个部分：模型，视窗和控制器。<br />模型<br />在struts框架中，模型分为两个部分：<br />l	系统的内部状态<br />l	可以改变状态的操作（事务逻辑）<br />  内部状态通常由一组ActinForm JavaBean表示。根据设计或应用程序复杂度的不同，这些Bean可以是自包含的并具有持续的状态，或只在需要时才获得数据（从某个数据库）。<br />  大型应用程序通常在方法内部封装事务逻辑（操作），这些方法可以被拥有状态信息的bean调用。比如购物车bean，它拥有用户购买商品的信息，可能还有checkOut()方法用来检查用户的信用卡，并向仓库发定货信息。<br />  小型程序中，操作可能会被内嵌在Action类，它是struts框架中控制器角色的一部分。当逻辑简单时这个方法很适合。<br />  建议用户将事务逻辑（要做什么）与Action类所扮演的角色（决定做什么）分开。<br />视窗<br />  由JSP建立，struts包含扩展自定义标签库，可以简化创建完全国际化用户界面的过程。<br />控制器<br />  struts中，基本的控制器组件是ActionServlet类中的实例servelt，实际使用的servlet在配置文件中由一组映射（由ActionMapping类进行描述）进行定义。<br />3.Struts框架中的组件<br />   <br />(由于ROSE工具还未能下载，只能找来这幅图，它说明了一定问题，特别是ActionErrors，但它并没有将ActionMapping，JSP和Tag Library包含进来，有时间作完替换)<br />框架中所使用的组件：<br />ActionServlet	控制器<br />ActionClass	包含事务逻辑<br />ActionForm	显示模块数据<br />ActionMapping	帮助控制器将请求映射到操作<br />ActionForward	用来指示操作转移的对象<br />ActionError	用来存储和回收错误<br />Struts标记库	可以减轻开发显示层次的工作<br />下面我们看看各自在框架中所扮演的角色和责任。<br />3.1 Struts配置文件<br />这是将struts组件结合在一起的东东：struts-config.xml。默认值<br />\WEB-INF\struts-config.xml。配置文件可以定义：<br />l	全局转发<br />l	ActionMapping类<br />l	ActionForm bean<br />l	JDBC数据源<br />配置全局转发<br />全局转发用来在JSP页之间创建逻辑名称映射。转发都可以通过对调用操作映射的实例来获得，例如：<br />actionMappingInstace.findForward(“logicalName”);<br />全局转发的例子：(所有的例子我没有进行解释，一是结合表可以理解，二是例子大部分来自系列四的示例，你应该在作完实验后，再来看一便)<br />&lt;global-forwards&gt;<br />&lt;forward   name=<font color="#00bb00" size="2">"bookCreated"</font><font color="black" size="2">  path=</font><font color="#00bb00" size="2">"/BookView.jsp"</font><font color="black" size="2">/&gt;<br />&lt;/global-forwards&gt;<br /> 属性	描述<br />Name	全局转发的名字<br />Path	与目标URL的相对路径<br /><br />配置ActionMapping<br />ActionMapping对象帮助进行框架内部的流程控制，它们可将请求URI映射到Action类,并且将Action类与ActionForm bean相关联。ActionServlet在内部使用这些映射，并将控制转移到特定Action类的实例。所有Action类使用perform()方法实现特定应用程序代码，返回一个ActionForward对象，其中包括响应转发的目标资源名称。例如：<br />&lt;action-mappings&gt;<br />&lt;action  path=</font><font color="#00bb00" size="2">"/createBook"</font><font color="black" size="2"><br />             type=</font><font color="#00bb00" size="2">"BookAction"</font><font color="black" size="2"><br />             name=</font><font color="#00bb00" size="2">"bookForm"</font><font color="black" size="2"><br />             scope=</font><font color="#00bb00" size="2">"request"</font><font color="black" size="2"><br />             input=</font><font color="#00bb00" size="2">"/CreateBook.jsp"</font><font color="black" size="2">&gt;<br />&lt;/action&gt;<br />&lt;forward name=”failure” path=”/CreateBook.jsp”/&gt;<br />&lt;forward name=”cancel” path=”/index.jsp”/&gt;<br />&lt;/action-mappings&gt;<br />属性	描述<br />Path 	Action类的相对路径<br />Name	与本操作关联的Action bean的名称<br />Type	连接到本映射的Action类的全称（可有包名）<br />Scope	ActionForm bean的作用域（请求或会话）<br />Prefix	用来匹配请求参数与bean属性的前缀<br />Suffix	用来匹配请求参数与bean属性的后缀<br />attribute	作用域名称。<br />className	ActionMapping对象的类的完全限定名默认的类是org.apache.struts.action.ActionMapping<br />input	输入表单的路径，指向bean发生输入错误必须返回的控制<br />unknown	设为<font color="blue" size="2">true</font>，操作将被作为所有没有定义的ActionMapping的URI的默认操作<br />validate	设置为<font color="blue" size="2">true</font>，则在调用Action对象上的perform()方法前，ActionServlet将调用ActionForm bean的validate()方法来进行输入检查<br />通过&lt;forward&gt;元素，可以定义资源的逻辑名称，该资源是Action类的响应要转发的目标。<br />属性	描述<br />Id	ID<br />ClassName	ActionForward类的完全限定名，默认是org.apache.struts.action.ActionForward<br />Name	操作类访问ActionForward时所用的逻辑名<br />Path	响应转发的目标资源的路径<br />redirect	若设置为<font color="blue" size="2">true</font>，则ActionServlet使用sendRedirect()方法来转发资源<br /><br />配置ActionForm Bean<br />ActionServlet使用ActionForm来保存请求的参数，这些bean的属性名称与HTTP请求参数中的名称相对应，控制器将请求参数传递到ActionForm bean的实例，然后将这个实例传送到Action类。例子：<br />&lt;form-beans&gt;<br />&lt;form-bean name=</font><font color="#00bb00" size="2">"bookForm"</font><font color="black" size="2"> type=</font><font color="#00bb00" size="2">"BookForm"</font><font color="black" size="2">/&gt;<br />&lt;/form-beans&gt;<br />属性	描述<br />Id	ID<br />className	ActionForm bean的完全限定名，默认值是org.apache.struts.action.ActionFormBean<br />Name	表单bean在相关作用域的名称，这个属性用来将bean与ActionMapping进行关联<br />Type	类的完全限定名<br /><br />配置JDBC数据源<br />用&lt;data-sources&gt;元素可以定义多个数据源。<br />属性	描述<br />Id	ID<br />Key	Action类使用这个名称来寻找连接<br />Type	实现JDBC接口的类的名称<br />下面属性需要&lt;set-property&gt;元素定义，在框架1.1版本中已不在使用，但你可用&lt;data-source&gt;元素。例子：<br />&lt;data-sources&gt;<br />&lt;data-source id=”DS1”<br />key=”conPool”<br />    type=”org.apache.struts.util.GenericDataSource”<br />&lt;set-property id=”SP1”<br />autoCommit=</font><font color="#00bb00" size="2">"true"</font><font color="black" size="2"><br />description=</font><font color="#00bb00" size="2">"Example Data Source Configuration"</font><font color="black" size="2"><br />driverClass=</font><font color="#00bb00" size="2">"org.test.mm.mysql.Driver"</font><font color="black" size="2"><br />maxCount=</font><font color="#00bb00" size="2">"4"</font><font color="black" size="2"><br />minCount=</font><font color="#00bb00" size="2">"2"</font><font color="black" size="2"><br />url=</font><font color="#00bb00" size="2">"jdbc:mysql://localhost/test"</font><font color="black" size="2"><br />user=</font><font color="#00bb00" size="2">"struts"</font><font color="black" size="2"><br />password=</font><font color="#00bb00" size="2">"wrox"</font><font color="black" size="2"> /&gt;<br />&lt;data-source/&gt;<br />&lt;/data-sources&gt;<br />属性	描述<br />desciption	数据源的描述<br />autoCommit	数据源创建的连接所使用的默认自动更新数据库模式<br />driverClass	数据源所使用的类，用来显示JDBC驱动程序接口<br />loginTimeout	数据库登陆时间的限制，以秒为单位<br />maxCount	最多能建立的连接数目<br />minCount	要创建的最少连接数目<br />password	数据库访问的密码<br />readOnly	创建只读的连接<br />User	访问数据库的用户名<br />url	JDBC的URL<br />通过指定关键字名称，Action类可以访问数据源，比如：<br />javax.sql.DataSource ds = servlet.findDataSource(“conPool”);<br />javax.sql.<font color="red" size="2">Connection</font> con = ds.get<font color="red" size="2">Connection</font>();<br /><br />3.2 ActionServlet类<br />框架中的控制器组件是有org.apache.struts.action.ActionServlet类实现的，这个类是javax.servlet.http.HttpServlet类的扩展。<br />Struts controller基本功能是：<br />1. 截获用户的Http请求<br />2. 把这个请求映射到相应的Action类，如果这是此类收到的第一个请求，将初始化实例并<br />缓寸。<br />3. 创建或发现一个ActionForm bean实例（看配置文件是否定义），然后将请求过程移植到 <br />bean.<br />4. 调用Action实例的perform（）方法并将ActioForm bean,Action Mapping对象,request<br />和response对象传给它。<br />如：<font color="blue" size="2">public</font> ActionForword perform(ActionMapping mapping,<br />                                 ActionForm form,<br />                                 HttpServletRequest request,<br />                                 HttpServletResponse response)<br />5.perform返回一个ActionForword对象，此对象连接到相应的jsp页面.<br />ActionServlet配置<br />我们需要在web.xml中声明ActionServlet，并且将它配置成启动时进行加载。以下为可以配置的初始化参数：<br />参数	默认值	描述<br />application	<font color="blue" size="2">null</font>	应用程序的资源集合的类<br />bufferSize	4096	文件上传的缓冲区大小<br />config	/WEB-INF/struts-config.xml	配置文件的位置和名称<br />content	Text/html	默认的内容类型<br />debug	0	程序调试的级别<br />detail	0	程序调试细节的级别<br />factory	<font color="blue" size="2">null</font>	消息资源工厂，用于国际化中解释消息资源<br />formBean	org.apache.struts.action.ActionFormBean	封装ActionForm bean信息的类的名称<br />forward	org.apache.struts.action.ActionForward	封装ActionForward对象信息的类的名称<br />locale	<font color="blue" size="2">true</font>	为<font color="blue" size="2">true</font>,将在用户会话中存储一个本地对象<br />mapping	org.apache.struts.action.ActionForward	封装ActionMapping信息的类的名称<br />maxFileSize	250M	上传文件的最大尺寸<br />multipartClass	org.apache.struts.action.ActionForward	处理多部分请求的类的名称<br />noCache	False	HTTP标头是否要设置为禁止缓寸<br />Null	True	设置为<font color="blue" size="2">true</font>，对于无效的信息关键字将返回<font color="blue" size="2">null</font><br />tempDir	作为一个servlet参数提供给程序的工作目录	处理下载文件是使用的临时工作目录<br />validate	True	是否使用新格式的配置文件<br />vallidating	True	是否对配置文件进行有效性分析<br />大多数情况下，标准的servlet就能够满足用户需要。<br />第一次收到特定请求的URI时，ActionServlet将适当的Action类进行实例化，然后ActionServlet在Action类实例中以servlet为变量名存储一个引用。当被实例化后，Action类会被暂存以备再用。<br />ActionServlet也提供一些方法，由Action类用来访问数据源和转发目标之类的资源。<br />ActionServlet方法<br />ActinServlet提供了一组能够被Action对象使用的方法。<br />    Struts API的全部信息在struts-documentation.war中可以找到。动态的添加或删除，这些方法只影响应用程序当前的实例：<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> addFormBean(ActionFormBean formBean)<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> removeFormBean(ActionFormBean formBean)<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> addForward(ActionForward actionForward)<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> removeForward(ActionForward actionForward)<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> addMapping(ActionMapping actionMapping)<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> removeMapping(ActionMapping actionMapping)<br />根据名称查找对象：<br /><font color="blue" size="2">public</font> ActionFormBean findFormBean(<font color="red" size="2">String</font> name)<br /><font color="blue" size="2">public</font> ActionForward findForward(<font color="red" size="2">String</font> name)<br /><font color="blue" size="2">public</font> ActionMapping findMapping(<font color="red" size="2">String</font> name)<br />用来处理数据源：<br />  <font color="blue" size="2">public</font><font color="blue" size="2">void</font> addDataSource(<font color="red" size="2">String</font> key , DataSource ds)<br />  <font color="blue" size="2">public</font> DataSource findDataSource(<font color="red" size="2">String</font> key)<br />我们还可以：<br />l	使用destroy()方法结束ActionServlet<br />l	使用reload()方法从struts配置文件将信息重新加载。<br /><br />3.3 ActionMapping类<br />将特定请求映射到特定Action的相关信息存储在ActionMapping中，ActionServelt将ActionMapping传送到Action类的perform()方法，Action将使用ActionMapping的findForward()方法，此方法返回一个指定名称的ActionForward，这样Action就完成了本地转发。若没有找到具体的ActionForward，就返回一个<font color="blue" size="2">null</font>.<br /><font color="blue" size="2">public</font> ActionForward findForward(<font color="red" size="2">String</font> name)<br />可在映射中动态添加ActionForward:<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> addForward(ActionForward forward)<br />可返回与映射关联的表单bean:<br /><font color="blue" size="2">public</font><font color="red" size="2">String</font> getName()<br />可返回映射的属性域（会话或请求）<br />  <font color="blue" size="2">public</font><font color="red" size="2">String</font> getScope()<br /><br />3.4 Action类<br />Action类真正实现应用程序的事务逻辑，它们负责处理请求。在收到请求后，ActionServlet会：<br />l	为这个请求选择适当的Action<br />l	如果需要，创建Action的一个实例<br />l	调用Action的perform()方法<br />如果ActionServlet不能找到有效的映射，它会调用默认的Action类(在配置文件中定义)。如果找到了ActionServlet将适当的ActionMapping类转发给Action，这个Action使用ActionMapping找到本地转发，然后获得并设置ActionMapping属性。根据servlet的环境和被覆盖的perform()方法的签名，ActionServlet也会传送ServletRequest对象或HttpServletRequest对象。<br />所有Action类都扩展org.apache.struts.action.Action类，并且覆盖类中定义的某一个perform()方法。有两个perform()方法：<br />处理非HTTP（一般的）请求：<br /><font color="blue" size="2">public</font> ActionForward perform(ActionMapping action, <br />AcionForm form,<br />ServletRequest request,<br />ServletResponse response)<br />    <font color="red" size="2">throws</font> IOException,ServletException<br />处理HTTP请求：<br /><font color="blue" size="2">public</font> ActionForward perform(ActionMapping action, <br />AcionForm form,<br />HttpServletRequest request,<br />HttpServletResponse response)<br />    <font color="red" size="2">throws</font> IOException,ServletException<br />Action类必须以“线程安全”的方式进行编程，因为控制器会令多个同时发生的请求共享同一个实例，相应的，在设计Action类时就需要注意以下几点：<br />l	不能使用实例或静态变量存储特定请求的状态信息，它们会在同一个操作中共享跨越请求的全局资源<br />l	如果要访问的资源（如JavaBean和会话变量）在并行访问时需要进行保护，那么访问就要进行同步<br />Action类的方法<br />除了perform()方法外，还有以下方法：<br />可以获得或设置与请求相关联的区域：<br /><font color="blue" size="2">public</font> Locale getLocale(HttpServletRequest request)<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> setLocale(HttpServletRequest request,Locale locale)<br />为应用程序获得消息资源：<br /><font color="blue" size="2">public</font> MessageResources getResources()<br />检查用户是否点击表单上的“取消”键，如果是，将返回<font color="blue" size="2">true</font>:<br /><font color="blue" size="2">public</font> Boolean isCancelled(HttpServletRequest request)<br />当应用程序发生错误时，Action类能够使用下面方法存储错误信息：<br /><font color="blue" size="2">public</font><font color="blue" size="2">void</font> saveErrors(HttpServletRequest request,ActionErrors errors)<br />ActionError实例被用来存储错误信息，这个方法在错误关键字下的请求属性列表中存储ActionError对象。通过使用在struts标记库中定义的自定义标记，JSP页能够显示这些错误信息，稍后我们就介绍。<br /><br />3.5 ActionForm类<br />框架假设用户在应用程序中为每个表单都创建了一个ActionForm bean，对于每个在struts-config.xml文件中定义的bean，框架在调用Action类的perform()方法之前会进行以下操作：<br />l	在相关联的关键字下，它检查用于适当类的bean实例的用户会话，如果在会话中没有可用的bean，它就会自动创建一个新的bean并添加到用户的会话中。<br />l	对于请求中每个与bean属性名称对应的参数，Action调用相应的设置方法。<br />l	当Action perform()被调用时，最新的ActionForm bean传送给它，参数值就可以立即使用了。<br />ActionForm类扩展org.apache.struts.action.ActionForm类，程序开发人员创建的bean能够包含额外的属性，而且ActionServlet可能使用反射（允许从已加载的对象中回收信息）访问它。<br />ActionForm类提供了另一种处理错误的手段，提供两个方法：<br />Public ActionErrors validate(ActionMappin mapping,<br />ServletRequest request)<br />Public ActionErrors validate(ActionMappin mapping,<br />HttpServletRequest request)<br />你应该在自己的bean里覆盖validate()方法，并在配置文件里设置&lt;action&gt;元素的validate为<font color="blue" size="2">true</font>。在ActionServlet调用Action类前，它会调用validate()，如果返回的ActionErrors不是<font color="blue" size="2">null</font>，则ActinForm会根据错误关键字将ActionErrors存储在请求属性列表中。<br />如果返回的不是<font color="blue" size="2">null</font>，而且长度大于0，则根据错误关键字将实例存储在请求的属性列表中，然后ActionServlet将响应转发到配置文件&lt;action&gt;元素的input属性所指向的目标。<br />如果需要执行特定的数据有效性检查，最好在Action类中进行这个操作，而不是在ActionForm类中进行。<br />方法reset()可将bean的属性恢复到默认值：<br />  <font color="blue" size="2">public</font><font color="blue" size="2">void</font> reset(ActionMapping mapping,HttpServletRequest request)<br />    <font color="blue" size="2">public</font><font color="blue" size="2">void</font> reset(ActionMapping mapping,ServletRequest request)<br />典型的ActionFrom bean只有属性的设置与读取方法（getXXX）,而没有实现事务逻辑的方法。只有简单的输入检查逻辑，使用的目的是为了存储用户在相关表单中输入的最新数据，以便可以将同一网页进行再生，同时提供一组错误信息，这样就可以让用户修改不正确的输入数据。而真正对数据有效性进行检查的是Action类或适当的事务逻辑bean。<br /><br />3.6 ActionForward类<br />目的是控制器将Action类的处理结果转发至目的地。<br />Action类获得ActionForward实例的句柄，然后可用三种方法返回到ActionServlet，所以我们可以这样使用findForward():<br />l	ActionServlet根据名称获取一个全局转发<br />l	ActionMappin实例被传送到perform()方法，并根据名称找到一个本地转发<br />另一种是调用下面的一个构造器来创建它们自己的一个实例：<br /><font color="blue" size="2">public</font> ActionForward()<br /><font color="blue" size="2">public</font> ActionForward(<font color="red" size="2">String</font> path)<br /><font color="blue" size="2">public</font> ActionForward(<font color="red" size="2">String</font> path,Boolean redirect)<br /><br />3.7 错误处理<br />struts提供了两个类来处理错误：ActionErrors和ActionError，它们都扩展org.apache.struts.action。ActionErrors保存着ActionError对象的集合，其中每一个代表了独立的错误信息。每个ActionError都包含了关键字，能够映射到资源文件中存储的错误信息，而这个资源文件是在ActionServlet初始化参数中指定的。<br />ActionError类<br />ActionError类定义了一组重载的构造器来创建错误信息，第一个构造器方法使用一个字符串作为参数，例如：<br />      ActionError error = <font color="blue" size="2">new</font> ActionError(“error.Invalid”);<br />实例error映射到应用程序资源文件中的一个错误消息：<br />      error.invalid=&lt;b&gt;Invalid Number&lt;/b&gt;<br />如果在JSP页使用&lt;html:error&gt;，用户就会看见加粗的Invalid Number。<br />另一种使用了java.text.MessageFormat类，可在消息中指定替换字符串，例如：<br />error.invalid=&lt;b&gt;Invalid Number{0}&lt;/b&gt;<br />创建一个错误消息：<br />ActionError error = <font color="blue" size="2">new</font> ActionError(‘error.invalid’,<font color="blue" size="2">new</font> Double(-1));<br />JSP页显示：Invalild Number –1<br />    还有获得特定消息的错误关键字：<br /><font color="blue" size="2">public</font><font color="red" size="2">String</font> getKey()<br />    还有获得替换字符串数组：<br /><font color="blue" size="2">public</font><font color="red" size="2">String</font>[] getValues()<br /><br />ActionError类<br />ActionError类从不独立进行错误处理，它们总是被存储在ActionErrors对象中。ActionErrors对象保存ActionError类的集合以及它们特定的属性值，我们可以使用自己定义的属性值，或是使用ActionErrors.GLOBAL_ERROR.<br />下面是典型Action类的perform()中错误处理情况：<br />MyForm form = (MyForm) form;<br /><font color="blue" size="2">if</font> (number == -1) {<br />ActionErrors errors = <font color="blue" size="2">new</font> ActionErrors();<br />ActionError error = <font color="blue" size="2">new</font> ActionError(“error.Invalid”,<font color="blue" size="2">new</font> Double(-1));<br />errors.add(ActionErrors.GLOBAL_ERROR,error);<br />saveErrors(req,errors);<br /><font color="red" size="2">String</font> input = mapping.getInput();<br />Return <font color="blue" size="2">new</font> ActionForward(input);<br />      }<br />ActionErrors有如下有用方法：<br />方法	描述<br />clear()	清除所有错误信息<br />empty()	如果ActionErrors对象是空的，它返回<font color="blue" size="2">true</font><br />get()	返回错误信息。若无参数，所有信息将作为一个Iterator对象返回<br />properties()	返回包含属性名称的Iterator，这些属性至少有一个错误<br />size()	返回错误的数目（整型数）<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />Struts标记库<br />4.Struts标记库<br />JSP视窗组件所使用的 struts标记库由四类标记组成：<br />l	Bean标记：用来在JSP页中管理bean<br />l	逻辑标记：用来在JSP页中控制流程<br />l	HTML标记：用来生成HTML标记，在表单中显示数据，使用会话ID对URL进行编程<br />l	模板标记：使用动态模板构造普通格式的页<br />4.1 Bean标记<br />这个标记库中包含用于定义新bean、访问bean及其属性的标记。Struts框架提供了多种自定义标记用来在JSP页中处理JavaBean。这些标记被封装在一个普通的标记库中，在文件struts-bean.tld中定义了它的标记库描述器。Bean标记库将标记定义在四个子类别中：<br />l	创建和复制bean的标记<br />l	脚本变量定义标记<br />l	bean翻译标记<br />l	消息国际化标记<br />4.1.1 Bean复制标记<br />可定义新bean，可复制现有bean，还可从现有bean复制属性。<br />&lt;bean:define&gt;标记用来：<br />l	定义新字符串常数<br />l	将现有的bean复制到新定义的bean对象<br />l	复制现有bean的属性来创建新的bean<br />  &lt;bean:define&gt;标记属性：<br />  <br />属性	描述<br />Id	新定义的bean脚本变量名称，必须设置<br />Type	定义引入脚本变量的类<br />Value	为id属性定义的脚本变量分配一个新的对象<br />Name	目标bean的名称。若value属性没有设置，这个属性就必须设置<br />property	Name属性定义的bean的属性名称，用来定义新的bean<br />Scope	源bean的作用域。若没有设置，搜索范围是从页作用域到应用程序作用域<br />toScope	目标bean的作用域。若没有设置，默认值是页作用域<br />例如：定义一个bean:<br />&lt;bean:define id=”test” value=”<font color="blue" size="2">this</font> is a test”/&gt;<br />源bean在页作用域中被拷贝大哦请求作用域中的另一个bean:<br />&lt;bean:define id=”targetBean” name=”sourceBean”<br />scope=”page” toScope=”request”/&gt;<br />4.1.2 定义脚本变量的标记<br />从多种资源中定义和生成脚本变量，这些资源包括cookie,请求参数，HTTP标头等等。属性如下：<br />属性	描述<br />Id	脚本变量和要定义的页作用域属性的名称<br />Name	cookie/标头/参数的名称<br />multiple	如果这个属性设置了任意一个数值，所有匹配的cookie都会被积累并存储到一个Cookie[](一个数组)类型的bean里。若无设置，指定cookie的第一个值将作为Cookie类型的值<br />Value	如果没有匹配的cookie或数值，就返回这个属性指定的默认值<br />例如：<br />&lt;bean:cookie id=”myCookie” name=”userName”/&gt;<br />脚本变量名称是myCookie，用来创建这个属性的cookie的名称是userName。<br />&lt;bean:header id=”myHeader” name=”Accept-Language”/&gt;<br />脚本变量名称是myHeader,请求标头的名称是Accept-Language.<br />&lt;bean:parameter id=”myParameter” name=”myParameter”&gt;<br />脚本变量名称是myPatameter,它保存的请求参数的名称也是myParameter.<br />&lt;bean:include&gt;标记将对一个资源的响应进行检索，并引入一个脚本变量和字符串类型的页作用域属性。这个资源可以是一个页，一个ActionForward或一个外部URL。与&lt;jsp:include&gt;的不同是资源的响应被存储到一个页作用域的bean中，而不是写入到输出流。属性如下：<br />属性	描述<br />Id	脚本变量和要定义的页作用域属性的名称<br />Page	一个内部资源<br />forward	一个ActionForward<br />Href	要包含的资源的完整URL<br />例如：<br />&lt;bean:include id=”myInclude” page=”MyJsp?x=1”/&gt;<br />脚本变量的名称是myInclude，要检索的响应来自资源MyJsp?x=1。<br /><br />&lt;bean:resource&gt;标记将检索web应用中的资源，并引入一个脚本变量和InputStream或字符串类型的页作用域属性。如果在检索资源时发生问题，就会产生一个请求时间异常。属性如下：<br />属性	描述<br />Id	脚本变量和要定义的页作用域属性的名称<br />Name	资源的相对路径<br />Input	如果这个属性不存在，资源的类型就是字符串<br />例如：<br />&lt;bean:resource id=”myResource” name=”/WEB-INF/images/myResource.xml”/&gt;<br />脚本变量的名称是myResource，要检索的资源的名称是myResource.xml。<br /><br />4.1.3 显示Bean属性<br />  标记库中定义了&lt;bean:write&gt;标记，用来将bean的属性输送到封装的JSP页写入器。这个标记与&lt;jsp:getProperty&gt;类似，属性如下：<br />属性	描述<br />Name	要进行属性显示的bean的名称<br />property	要显示的属性的名称。如果这个属性类有java.beans.PropertyEditor,getAsText()或toString 方法会被调用<br />Scope	Bean的作用域，若没有设置，搜索范围是从页到应用程序作用域<br />Filter	如果设置<font color="blue" size="2">true</font>,属性中的所有特殊HTML字符都将被转化为相应的实体引用<br />Ignore	如果设置false，当发现属性时会产生一个请求时间异常，否则返回<font color="blue" size="2">null</font><br />例如：<br />&lt;bean:write name=”myBean” property=”myProperty” scope=”request”<br /> filter=”<font color="blue" size="2">true</font>”/&gt;<br />myBean的属性myProperty将会被显示，作用域为请求，如果发现任何HTML特殊字符都将被转化为相应的实体引用。<br /><br />4.1.4 消息标记和国际化<br />strtus框架支持国际化和本地化。用户在他们的计算机中定义自己所在的区域，当web应用程序需要输出一条消息时，它将引用一个资源文件，在这个文件中所有的消息都使用了适当的语言。一个应用程序可能提供了很多资源文件，每个文件提供了用不同语言编写的消息。如果没有找到所选语言的资源文件，就将使用默认的资源文件。<br />struts框架对国际化的支持是使用&lt;bean:message&gt;标记，以及使用java.util数据包中定义的Locale和ResourceBundle类来实现Java2平台对这些任务的支持。Java.text.MessageFormat类定义的技术可以支持消息的格式。利用此功能，开发人员不需了解这些类的细节就可进行国际化和设置消息的格式。<br />用strtus实现国际化和本地化：<br />第一步要定义资源文件的名称，这个文件会包含用默认语言编写的在程序中会出现的所有消息。这些消息以“关键字-值”的形式存储，如下：<br />error.validation.location = The entered location is invalid<br />这个文件需要存储在类的路径下，而且它的路径要作为初始化参数传送给ActionServlet作为参数进行传递时，路径的格式要符合完整Java类的标准命名规范。比如，如果资源文件存储在WEB-INF\classes目录中，文件名是ApplicationResources.properties，那么需要传递的参数值是ApplicationResources。如果文件在WEB-INF\classes\com\test中，那么参数值就应该是com.test. ApplicationResources.<br />为了实现国际化，所有的资源文件必须都存储在基本资源文件所在的目录中。基本资源文件包含的是用默认地区语言-本地语言编写的消息。如果基本资源文件的名称是ApplicationResources.properties，那么用其他特定语言编写的资源文件的名称就应该是ApplicationResources_xx.properties(xx为ISO编码，如英语是en)。因此这些文件应包含相同的关键字，但关键字的值是用特定语言编写的。<br />ActionServlet的区域初始化参数必须与一个<font color="blue" size="2">true</font>值一起传送，这样ActionServlet就会在用户会话中的Action.LOCALE_KEY关键字下存储一个特定用户计算机的区域对象。现在可以运行一个国际化的web站点，它可以根据用户计算机上的设置的区域自动以相应的语言显示。<br />我们还可以使用特定的字符串来替换部分消息，就象用java.text.MessageFormat的方法一样：<br />error.invalid.number = The number {0} is valid<br />我们可以把字符串{0}替换成任何我们需要的数字。&lt;bean:message&gt;标签属性如下：<br />属性	描述<br />Key	资源文件中定义消息关键字<br />Locale	用户会话中存储的区域对象的属性名称。若没有设置，默认值是Action.LOCALE_KEY<br />Bundle	在应用程序上下文中，存储资源对象的属性的名称。如果没有设置这个属性，默认值是Action.MESSAGE_KEY<br />arg0	第一个替换参数值<br />arg1	第二个替换参数值<br />arg2	第三个替换参数值<br />arg3	第四个替换参数值<br />例如：资源文件中定义了一个消息：<br />info.myKey = The numbers entered are {0},{1},{2},{3}<br />我们可使用下面的消息标记：<br />&lt;bean:message key=”info.myKey” arg0=”5” arg1=”6” arg2=”7” arg3=”8”/&gt;<br />  这个信息标记输出到JSP页会显示为：The numbers entered are 5,6,7,8<br /><br />4.2 逻辑标记<br />逻辑库的标记能够用来处理外观逻辑而不需要使用scriptlet。Struts逻辑标签库包含的标记能够有条件地产生输出文本，在对象集合中循环从而重复地产生输出文本，以及应用程序流程控制。它也提供了一组在JSP页中处理流程控制的标记。这些标记封装在文件名为struts-logic.tld的标记包中。逻辑标记库定义的标记能够执行下列三个功能：<br />l	条件逻辑<br />l	重复<br />l	转发/重定向响应<br />4.2.1 条件逻辑<br />struts有三类条件逻辑。第一类可以比较下列实体与一个常数的大小：<br />l	cookie<br />l	请求参数<br />l	bean或bean的参数<br />l	请求标头<br /> 以下列出了这一类标记：<br />标记	功能<br />&lt;equal&gt;	如果常数与被定义的实体相等，返回<font color="blue" size="2">true</font><br />&lt;notEqual&gt;	如果常数与被定义的实体不相等，返回<font color="blue" size="2">true</font><br />&lt;greaterEqual&gt;	如果常数大于等于被定义的实体，返回<font color="blue" size="2">true</font><br />&lt;lessEqual&gt;	如果常数小于等于被定义的实体，返回<font color="blue" size="2">true</font><br />&lt;lessThan&gt;	如果常数小于被定义的实体，返回<font color="blue" size="2">true</font><br />&lt;greaterThan&gt;	如果常数大于被定义的实体，返回<font color="blue" size="2">true</font><br /><br />这一类的所有标记有相同的属性<br />属性	描述<br />Value	要进行比较的常数值<br />Cookie	要进行比较的HTTP cookie的名称<br />Header	要进行比较的HTTP请求标头的名称<br />parameter	要进行比较的HTTP请求参数的名称<br />Name	如果要进行比较的是bean或bean的属性，则这个属性代表bean的名称 <br />property	要进行比较的bean属性的名称<br />Scope	Bean的作用域，如果没有指定作用域，则它的搜索范围是从页到应用程序<br />例如：<br />&lt;logic:equal parameter=”name” value=”SomeName”&gt;<br />        The entered name is SomeName<br />&lt;/logic:equal&gt;<br />判断名为”name”的请求参数的值是否是”SomeName”。<br />&lt;logic:greaterThan name=”bean” property=”prop” scope=”page” value=”7”&gt;<br />The value of bean.Prop is greater than 7<br />&lt;/logic:greaterThan&gt;<br />判断在页的作用域中是否有一个名为”bean”的bean，它有一个prop属性，这个属性的值是否大于7。如果这个属性能够转化为数值，就进行数值比较，否则就进行字符串比较。<br />第二类条件标记定义了两个标记：<br />l	&lt;logic:present&gt;<br />l	&lt;logic:notPresent&gt;<br />它们的功能是在计算标记体之前判断特定的项目是否存在。标记的属性和属性值决定了要进行检查的项目。<br />属性	描述<br />Cookie	由这个属性指定的cookie将被检查是否存在<br />Header	由这个属性指定的请求标头将被检查是否存在<br />parameter	由这个属性指定的请求参数将被检查是否存在<br />Name	如果没有设置property属性，那么有这个属性指定的bean将被检查是否存在。如果设置了，那么bean和bean属性都将被检查是否存在。<br />property	检查有name属性指定的bean中是否存在指定的属性<br />Scope	如果指定了bean的名称，这就是bean的作用域。如果没有指定作用域，搜索的范围从页到应用程序作用域。<br />Role	检查当前已经确认的用户是否属于特殊的角色<br />User	检查当前已经确认的用户是否有特定的名称<br />例如：<br />&lt;logic:notPresent name=”bean” property=”prop” scope=”page”&gt;<br />The bean property bean.prop is present<br />&lt;/logic:notPresent&gt;<br />标记判断在页作用域中是否存在一个名为”bean”的bean，这个bean有一个prop属性。<br />第三类条件标记比较复杂，这些标记根据模板匹配的结果检查标记体的内容。换句话说，这些标记判断一个指定项目的值是否是一个特定常数的子字符串：<br />l	&lt;logic:match&gt;<br />l	&lt;logic:notMatch&gt;<br />这些标记允许JSP引擎在发现了匹配或是没有发现时计算标记主体。属性如下：<br />属性	描述<br />Cookie	要进行比较的HTTP cookie的名称<br />Header	要进行比较的的HTTP标头 的名称<br />parameter	要进行比较的的HTTP请求参数的名称<br />Name	若要对bean或bean的属性进行比较，这个属性是用户指定bean的名称<br />location	如果设置了这个属性的值，将会在这个指定的位置(索引值)进行匹配<br />scope	如果对bean进行比较，这个属性指定了bean的作用域。如果没有设置这个参数，搜索范围是从页到应用程序作用域<br />property	要进行比较的bean的属性名称<br />value	要进行比较的常数值<br />例如：<br />&lt;logic:match parameter=”name” value=”xyz” location=”1”&gt;<br />      The parameter name is a sub-string of the string xyz from index 1<br />&lt;/logic:match&gt;<br />标记检查名为”name”的请求参数是否是”xyz”的子字符串，但是子字符串必须从”xyz”的索引位置1开始（也就是说子字符串必须是”y”或”yz”）。<br />4.2.2 重复标记<br />在逻辑标记库中定义了&lt;logic:iterate&gt;标记，它能够根据特定集合中元素的数目对标记体的内容进行重复的检查。集合的类型可以是java.util.Iterator,java.util.Collection<br />,java.util.Map或是一个数组。有三种方法可以定义这个集合：<br />l	使用运行时间表达式来返回一个属性集合的集合<br />l	将集合定义为bean，并且使用name属性指定存储属性的名称。<br />l	使用name属性定义一个bean，并且使用property属性定义一个返回集合的bean属性。<br />当前元素的集合会被定义为一个页作用域的bean。属性如下，所有这些属性都能使用运行时表达式。<br />属性	描述<br />collection	如果没有设置name属性，它就指定了要进行重复的集合<br />Id	页作用域bean和脚本变量的名称，它保存着集合中当前元素的句柄<br />indexed	页作用域JSP bean的名称，它包含着每次重复完成后集合的当前索引<br />Length	重复的最大次数<br />Name	作为集合的bean的名称，或是一个bean名称，它由property属性定义的属性，是个集合<br />Offset	重复开始位置的索引<br />property	作为集合的Bean属性的名称<br />Scope	如果指定了bean名称，这个属性设置bean的作用域。若没有设置，搜索范围从页到应用程序作用域<br />Type	为当前定义的页作用域bean的类型<br />例如：<br />&lt;logic:iterate id=”currentInt”<br />collection=”&lt;% =myList %&gt;”<br />type=”java.lang.Integer”<br />offset=”1”<br />length=”2”&gt;<br />    &lt;% =currentint %&gt;<br />    &lt;/logic:iterate&gt;<br />代码将从列表中的第一个元素开始重复两个元素并且能够让当前元素作为页作用域和java.lang.Integer类型的脚本变量来使用。也就是说，如果myList包含元素1，2，3，4等，代码将会打印1和2。<br />4.2.3 转发和重定向标记<br />转发标记<br />&lt;logic:forward&gt;标记能够将响应转发给重定向到特定的全局ActionForward上。ActionForward的类型决定了是使用PageContext转发响应，还是使用sendRedirect将响应进行重定向。此标记只有一个”name”属性，用来指定全局ActionForward的名称，例如：<br />&lt;logic:forward name=”myGlobalForward”/&gt;<br />重定向标记<br />&lt;logic:redirect&gt;标记是一个能够执行HTTP重定向的强大工具。根据指定的不同属性，它能够通过不同的方式实现重定向。它还允许开发人员指定重定向URL的查询参数。属性如下：<br />属性	描述<br />Forward	映射了资源相对路径的ActionForward<br />Href	资源的完整URL<br />Page	资源的相对路径<br />Name	Map类型的页名称，请求，会话或程序属性的名称，其中包含要附加大哦重定向URL（如果没有设置 property属性）上的“名称-值”参数。或是具有Map类型属性的bean名称，其中包含相同的信息（没有设置property属性）<br />Property	Map类型的bean属性的名称。Bean的名称由name属性指定。<br />Scope	如果指定了bean的名称，这个属性指定搜索bean的范围。如果没有设置，搜索范围从页到应用程序作用域<br />ParamID	定义特定查询参数的名称<br />ParamName	字符串类型的bean的名称，其中包含查询参数的值(如果没有设置paramProperty属性)；或是一个bean的名称，它的属性(在paramProperty属性中指定)包含了查询参数值<br />paramProperty	字符串bean属性的名称，其中包含着查询参数的值<br />ParamScope	ParamName定义的bean的搜索范围<br />使用这个标记时至少要指定forward,href或page中的一个属性，以便标明将响应重定向到哪个资源。<br />4.3 HTML标记<br />Struts HTML标记可以大致地分为以下几个功能：<br />l	显示表单元素和输入控件<br />l	显示错误信息<br />l	显示其他HTML元素<br />4.3.1 显示表单元素和输入控件<br />struts将HTML表单与为表单操作而定义的ActionForm bean紧密联系在一起。表单输入字段的名称与ActionForm bean里定义的属性名称是对应的。当第一次显示表单时，表单的输入字段是从ActionForm bean中移植过来的，当表单被提交时，请求参数将移植到ActionForm bean实例。<br />所有可以在&lt;form&gt;标记中使用的用来显示HTML输入控件的内嵌标记都使用下列属性来定义JavaScript事件处理器。<br />属性	描述<br />Onblur	字段失去了焦点<br />Onchange	字段失去了焦点并且数值被更改了<br />Onclick	字段被鼠标点击<br />Ondblclick	字段被鼠标双击<br />Onfocus	字段接收到输入焦点<br />Onkeydown	字段拥有焦点并且有键按下<br />onkeypress	字段拥有焦点并且有键按下并释放<br />Onkeyup	字段拥有焦点并且有键被释放<br />onmousedown	鼠标指针指向字段并且点击<br />onmousemove	鼠标指针指向字段并且在字段内移动<br />onmouseout	鼠标指针指向控件，但是指针在元素外围移动<br />onmouseover	鼠标指针没有指向字段，但是指针在元素内部移动<br />Onmouseup	鼠标指针指向字段，并且释放了鼠标按键<br />&lt;form&gt;元素中能够被定义的其他一般属性有：<br />属性	描述<br />Accesskey	定义访问输入字段的快捷键<br />Style	定义输入字段的样式<br />styleClass	定义输入字段的样式表类<br />Tabindex	输入字段的tab顺序<br />表单标记<br />&lt;html:form&gt;标记用来显示HTML标记，可以指定AcitonForm bean的名称和它的类名。如果没有设置这些属性，就需要有配置文件来指定ActionMapping以表明当前输入的是哪个JSP页，以及从映射中检索的bean名和类。如果在ActionMapping指定的作用域中没有找到指定的名称，就会创建并存储一个新的bean，否则将使用找到的bean。<br />&lt;form&gt;标记能够包含与各种HTML输入字段相对应的子标记。<br />&lt;html:form&gt;标记属性如下：<br />属性	描述<br />Action	与表单相关的操作。在配置中，这个操作也用来标识与表单相关的ActionForm bean<br />Enctype	表单HTTP方法的编码类型<br />Focus	表单中需要初始化焦点的字段<br />Method	表单使用的HTTP方法<br />Name	与表单相关的ActionForm bean的名称。如果没有设置这个属性，bean的名称将会从配置信息中获得<br />Onreset	表单复位时的JavaScript事件句柄<br />Onsubmit	表单提交时的JavaScript事件句柄<br />Scope	搜索ActionForm bean的范围。如果没有设置，将从配置文件中获取<br />Style	使用的格式<br />styleClass	这个元素的格式表类<br />Type	ActionForm bean的完整名称。如果没有设置，将从配置文件获得<br />例如：<br />&lt;html:form action=”validateEmploee.<font color="blue" size="2">do</font>” method=”post”&gt;<br />&lt;/html:form&gt;<br />与表单相关的操作路径是validateEmployee,而表单数据是通过POST传递的。对于这个表单来说，ActionForm bean的其他信息，如bean名称类型，作用域，都是从表单指定操作的ActionMapping中检索得到的：<br />&lt;form-beans&gt;<br />&lt;form-bean name=”empForm” type=”com.example.EmployeeForm”/&gt;<br />    &lt;/form-beans&gt;<br />    &lt;action-mappings&gt;<br />    &lt;action path=”/validateEmployee”<br />type=”com.example.ValidateExampleAction”<br />name=”empForm”<br />scope=”request”<br />input=”/employeeInput.jsp”&gt;<br />&lt;forward name=”success” path=”/employeeOutput.jsp”&gt;<br />     &lt;/action&gt;<br />    &lt;/action-mapping&gt;<br />如果配置文件中包含上述信息，并且请求URI的*.<font color="blue" size="2">do</font>被映射到ActionServlet，与表单相关的ActionForm bean的名称，类型和作用域分别是empForm,com.example.EmployeeForm和request.这些属性也可以使用&lt;html:form&gt;标记属性进行显示的定义。<br />以下标记必须嵌套在&lt;html:form&gt;标记里<br />按钮和取消标记<br />&lt;html:button&gt;标记显示一个按钮控件；&lt;html:cancel&gt;标记显示一个取消按钮。属性如下：<br />属性	描述<br />Property	定义在表单被提交时返回到服务器的请求参数的名称<br />Value	按钮上的标记<br />复位和提交标记<br />&lt;html:reset&gt;和&lt;html:submit&gt;标记分别能够显示HTML复位按钮和提交按钮。<br />文本和文本区标记<br />&lt;html:text&gt;和&lt;html:textarea&gt;标记分别HTML文本框和文本区，属性如下：<br />属性	描述<br />Property	定义当表单被提交时送回到服务器的请求参数的名称，或用来确定文本元素当前值的bean的属性名称<br />Name	属性被查询的bean的名称，它决定了文本框和文本区的值。如果没有设置，将使用与这个内嵌表单相关的ActionForm的名称<br />&lt;html:text&gt;标记还有以下属性：<br />属性	描述<br />Maxlength	能够输入的最大字符数<br />Size	文本框的大小（字符数）<br />&lt;html:textarea&gt;标记特有的属性如下：<br />属性	描述<br />Rows	文本区的行数<br />Cols	文本区的列数<br />检查框和复选框标记<br />&lt;html:checkbox&gt;标记能够显示检查框控件。&lt;html:multibox&gt;标记能够显示HTML复选框控件，请求对象在传递检查框名称时使用的getParameterValues()调用将返回一个字符串数组。属性如下：<br />属性	描述<br />Name	Bean的名称，其属性会被用来确定检查是否以选中的状态显示。如果没有设置，将使用与这个内嵌表单相关的ActionFrom bean的名称。<br />Property	检查框的名称，也是决定检查框是否以选中的状态显示的bean属性名称。在复选框的情况下，这个属性必须是一个数组。<br />Value	当检查框被选中时返回到服务器的请求参数的值<br />例如：<br />&lt;html:checkbox property=”married” value=”Y”/&gt;<br />一个名为married的检查框，在表单提交时会返回一个”Y”.<br />文件标记<br />&lt;html:file&gt;标记可以显示HTML文件控件。属性如下：<br />属性	描述<br />Name	Bean的名称，它的属性将确定文件控件中显示的内容。如果没设置，将使用与内嵌表单相关的ActionForm bean的名称<br />property	这个属性定义了当表单被提交时送回到服务器的请求参数的名称，以及用来确定文件控件中显示内容的bean属性名称<br />Accept	服务器能够处理的内容类型集。它也将对客户浏览器对话框中的可选文件类型进行过滤<br />Value	按钮上的标记，这个按钮能够在本地文件系统中浏览文件<br />单选钮标记<br />&lt;html:radio&gt;标记用来显示HTML单选钮控件，属性如下：<br />属性	描述<br />Name	Bean的名称，其属性会被用来确定单选钮是否以选中的状态显示。如果没有设置，将使用与这个内嵌表单相关的ActionFrom bean的名称。<br />property	当表单被提交时送回到服务器的请求参数的名称，以及用来确定单选钮是否以被选中状态进行显示的bean属性的名称<br />Value	当单选钮被选中时返回到服务器的值<br />隐藏标记<br />&lt;html:hidden&gt;标记能够显示HTML隐藏输入元素，属性如下：<br />属性	描述<br />Name	Bean的名称，其属性会被用来确定隐藏元素的当前值。如果没有设置，将使用与这个内嵌表单相关的ActionFrom bean的名称。<br />property	定义了当表单被提交时送回到服务器的请求参数的名称，以及用来确定隐藏元素当前值的bean属性的名称<br />Value	用来初始化隐藏输入元素的值<br />密码标记<br />&lt;html:password&gt;标记能够显示HTML密码控件，属性如下：<br />属性	描述<br />maxlength	能够输入的最大字符数<br />Name	Bean的名称，它的属性将用来确定密码元素的当前值。如果没有设置，将使用与这个内嵌表单相关的ActionFrom bean的名称。<br />property	定义了当表单被提交时送回到服务器的请求参数的名称，以及用来确定密码元素当前值的bean属性的名称<br />redisplay	在显示这个字段时，如果相应的bean属性已经被设置了数据，这个属性决定了是否显示密码的内容<br />Size	字段的大小<br />选择标记<br />&lt;html:select&gt;标记能够显示HTML选择控件，属性如下：<br />属性	描述<br />multiple	表明这个选择控件是否允许进行多选<br />Name	Bean的名称，它的属性确定了哪个。如果没有设置，将使用与这个内嵌表单相关的ActionFrom bean的名称。<br />property	定义了当表单被提交时送回到服务器的请求参数的名称，以及用来确定哪个选项需要被选中的bean属性的名称<br />Size	能够同时显示的选项数目<br />Value	用来表明需要被选中的选项<br />选项标记(这个元素需要嵌套在&lt;html:select&gt;标记里)<br />&lt;html:option&gt;标记用来显示HTML选项元素集合，属性如下：<br />属性	描述<br />collection	Bean集合的名称，这个集合存储在某个作用域的属性中。选项的数目与集合中元素的数目相同。Property属性能够定义选项值所使用的bean属性，而labelProperty属性定义选项标记所使用的bean的属性<br />labelName	用来指定存储于某个作用域的bean，这个bean是一个字符串的集合，能够定义&lt;html:option&gt;元素的标记(如果标志与值不相同)<br />labelProperty	与collection属性共同使用时，用来定义了存储于某个作用域的bean，这个bean将返回一个字符串集合，能够用来写入&lt;html:option&gt;元素的value属性<br />Name	如果这是唯一被指定的属性，它就定义了存储于某个作用域的bean，这个bean将返回一个字符串集合，能够用来写入&lt;html:option&gt;元素的value属性<br />property	这个属性在与collection属性共同使用时，定义了每个要显示选项值的独立bean的name属性。如果不是与collection属性共同使用，这个属性定义了由name属性指定的bean的属性名称(如果有name属性)，或是定义了一个ActionForm bean，这个bean将返回一个集合来写入选项的值<br />我们看一下这个标记的一些例子：<br />&lt;html:option collection=”optionCollection” property=”optionValue”<br />labelProperty=”optionLabel”/&gt;<br />标记假设在某个作用域中有一个名为optionCollection的集合，它包含了一些具有optionValue属性的独立的bean，每个属性将作为一个选项的值。每个选项的标志由bean的optionLabel属性属性进行定义。<br />&lt;html:option name=”optionValues” labelName=”optionLabels”/&gt;<br />标记中optionValues代表一个存储在某个作用域中的bean，它是一个字符串集合，能够用来写入选项的值，而optionLabels代表一个存储在某个作用域中的bean，它也是一个字符串集合，能够用来写入选项的标志。<br />4.3.2 显示错误信息的标记<br />&lt;<a name="baidusnap0"></a><b style="COLOR: black; BACKGROUND-COLOR: #ffff66">html:errors</b>&gt;标记能够与ActionErrors结合在一起来显示错误信息。这个标记首先要从当前区域的资源文件中读取消息关键字errors.header，然后显示消息的文本。接下去它会在ActionErrors对象(通常作为请求参数而存储在Action.ERROR_KEY关键字下)中循环，读取单个ActionError对象的消息关键字，从当前区域的资源文件中读取并格式化相应的消息，并且显示它们。然后它读取与errors.footer关键字相对应的消息并且显示出来。<br />通过定义property属性能够过滤要显示的消息，这个属性的值应该与ActionErrors对象中存储ActionError对象的关键字对应。属性如下：<br />属性	描述<br />Bundle	表示应用程序作用域属性的名称，它包含着消息资源，其默认值Acion.MESSAGE_KEY<br />Locale	表示会话作用域属性的名称，它存储着用户当前登录的区域信息。其默认值是Action.ERROR_KEY<br />Name	表示请求属性的名称，它存储着ActionErrors对象。其默认值是Action.ERROR_KEY<br />property	这个属性指定了ActionErrors对象中存储每个独立ActionError对象的关键字，它可以过滤消息<br />例子：<br />&lt;<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">html:errors</b>/&gt;<br />显示集合中所有的错误。<br />&lt;<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">html:errors</b> property=”missing.name”/&gt;<br />显示存储在missing.name关键字的错误。<br />4.3.3 其他HTML标记<br />struts HTML标记还定义了下列标记来显示其他HTML元素：<br />l	&lt;html:html&gt; : 显示HTML元素<br />l	&lt;html:img&gt; : 显示图象标记<br />l	&lt;html:link&gt; : 显示HTML链接或锚点<br />l	&lt;html:rewrite&gt; : 创建没有锚点标记的URI<br />这些标记的详细内容请参照struts文档。<br />4.4 模板标记<br />动态模板是模块化WEB页布局设计的强大手段。Struts模板标记库定义了自定义标记来实现动态模板。<br />插入标记<br />&lt;template:insert&gt;标记能够在应用程序的JSP页中插入动态模板。这个标记只有一个template属性，用来定义模板JSP页。要插入到模板的页是有多个&lt;template:put&gt;标记来指定的，而这些标记被定义为&lt;template:insert&gt;标记的主体内容。<br />放置标记<br />&lt;template:put&gt;标记是&lt;template:insert&gt;标记内部使用的，用来指定插入到模板的资源。属性如下：<br />属性	描述<br />content	定义要插入的内容，比如一个JSP文件或一个HTML文件<br />direct	如果这个设置为<font color="blue" size="2">true</font>，由content属性指定的内容将直接显示在JSP上而不是作为包含文件<br />Name	要插入的内容的名称<br />Role	如果设置了这个属性，只有在当前合法用户具有特定角色时才能进行内容的插入。<br />获得标记<br />在模板JSP页中使用&lt;template:get&gt;标记能够检索由&lt;template:put&gt;标记插入到JSP页的资源。属性如下：<br />属性	描述<br />Name	由&lt;template:put&gt;标记插入的内容的名称<br />Role	如果设置了这个属性，只有在当前合法用户具有特定角色时才能进行内容的检索<br />使用模板标记<br />首先编写一个模板JSP页，它将被所有的web页使用：<br />&lt;html&gt;<br />  &lt;%@ taglib uri=”/template” prefix=”template” %&gt;<br />  &lt;head&gt;<br />&lt;title&gt;&lt;/title&gt;<br />  &lt;/head&gt;<br />  &lt;body&gt;<br />&lt;table width=”100%” height=”100%” &gt;<br />  &lt;tr height=”10%”&gt;<br />    &lt;td&gt;<br />      &lt;template:get name=”header”/&gt;<br />    &lt;/td&gt;<br />  &lt;/tr&gt;<br />  &lt;tr height=”80%”&gt;<br />    &lt;td&gt;<br />      &lt;template:get name=”content”/&gt;<br />    &lt;/td&gt;<br />  &lt;/tr&gt;<br />  &lt;tr height=”10%”&gt;<br />    &lt;td&gt;<br />      &lt;template:get name=”footer”/&gt;<br />    &lt;/td&gt;<br />  &lt;/tr&gt;<br />&lt;/table&gt;<br />  &lt;/body&gt;<br />&lt;/html&gt;<br />我们将这个文件命名为template.jsp。这个文件使用&lt;template:get&gt;标记来获得由JSP页使用&lt;template:put&gt;标记提供的内容，并且将内容在一个HTML表格中显示出来。这三个内容是标题，内容和页脚。典型的内容JSP会是这样：<br />&lt;%@ taglib uri=”/template” prefix=”/template” %&gt;<br />&lt;template:insert template=”template.jsp”&gt;<br />  &lt;template:put name=”header” content=”header.html”/&gt;<br />  &lt;template:put name=”content” content=”employeeList.jsp”/&gt;<br />  &lt;template:put name=”footer” content=”footer.html”/&gt;<br />&lt;/template:insert&gt;<br />这个应用程序JSP页使用&lt;template:insert标记来定义模板，然后使用&lt;template:put&gt;标记将特定内容名称指定的资源放到模板JSP页中。如果我们有上百个布局相同的页</font><img src ="http://www.blogjava.net/19851985lili/aggbug/97670.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-02 20:51 <a href="http://www.blogjava.net/19851985lili/articles/97670.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts时，如果要在JSP隐式的传值给Action有两种情况：</title><link>http://www.blogjava.net/19851985lili/articles/97664.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 02 Feb 2007 12:48:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/97664.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/97664.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/97664.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/97664.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/97664.html</trackback:ping><description><![CDATA[你的代码本身有问题，一般来说，我们在使用Struts时，如果要在JSP隐式的传值给Action有两种情况：<br />1、要传的值是FromBean中的一个字段，你说的情况应该就是这种情况，例如需要在Edit页面中保存theID，在Action中执行Update操作时根据ID来更新数据库的值，你可以这样做：<br />Jsp中的代码为：&lt;html:hidden property="theID" /&gt;<br />提交后，theID的值就会放到FormBean中的theID中，你就可以通过getTheID()来获得这个值。<br />2、要传的值不是FromBean中的一个字段：<br />Jsp中的代码为：<br />&lt;input type="hidden" name="XXX" value="&lt;%=request.getAttribute(XXX)%&gt;"&gt;<br />当然，你应该在Action中就已经就这个值放到了request中，request.setAttribute("XXX",value);，<br />然后在Action中你才可以通过request.getParameter("XXX");来取得这个值。<br /><br />补充一点，request.setAttribute("XXX",value);中，value应该是个String，还有，&lt;input type="hidden" name="XXX" value="&lt;%=request.getAttribute(XXX)%&gt;"&gt;应该改为<br />&lt;input type="hidden" name="XXX" value="&lt;%=(String)request.getAttribute(XXX)%&gt;"&gt;<br /><img src ="http://www.blogjava.net/19851985lili/aggbug/97664.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-02 20:48 <a href="http://www.blogjava.net/19851985lili/articles/97664.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts实现多附件上传 广东精鹰软件工作室(刘正仁) </title><link>http://www.blogjava.net/19851985lili/articles/97645.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 02 Feb 2007 12:34:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/97645.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/97645.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/97645.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/97645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/97645.html</trackback:ping><description><![CDATA[
		<p>jsp页面:</p>
		<p>&lt;%@ page contentType="text/html; charset=utf-8" %&gt;<br />&lt;<a href="mailto:%@include">%@include</a> file="/common.jsp"%&gt;<br />&lt;html&gt;<br />&lt;head&gt;<br />&lt;title&gt;<br />testArr<br />&lt;/title&gt;<br />&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;&lt;/head&gt;<br />&lt;body bgcolor="#ffffff"&gt;<br />&lt;html:form action="/testArr.do"  enctype="multipart/form-data"&gt;<br />&lt;input type="hidden" name="fileUpLoadNumberRow" id="fileUpLoadNumberRow" value="1"&gt;<br /> &lt;table  &lt;%=tableStyle%&gt; id="testArr"&gt;<br /> &lt;tr  class="ListTableHeader" &gt;<br />     &lt;td width="13%"  align="center"&gt;&lt;b&gt;操作&lt;/b&gt;&lt;/td&gt;<br />     &lt;td width="33%"  align="center"&gt;&lt;b&gt;文件描述&lt;/b&gt;&lt;/td&gt;<br />  &lt;td width="54%"  align="center"&gt;&lt;b&gt;源文件&lt;/b&gt;&lt;/td&gt;<br /> &lt;/tr&gt;<br /> &lt;tr  class="ListTableRow" &gt;<br />     &lt;td width="13%"&gt; &lt;input type="button" name="Submit" value="删除" class="Button4"  onclick="delCode(1)"&gt;&lt;/td&gt;<br />     &lt;td width="33%"  align="center"&gt;&lt;b&gt;&lt;input type="hidden" name="fileUpLoadHiddenIDNewObject1" value="" id="fileUpLoadHiddenIDNewObject1"&gt;&lt;input type="text" name="fileTitle1" &lt;%=input100Change%&gt; id="fileTitle1"&gt;&lt;/b&gt;&lt;/td&gt;<br />  &lt;td width="54%"  align="center"&gt;&lt;b&gt;&lt;input type="file" name="filePath1"  &lt;%=input100%&gt; id="filePath1"  onchange="showFileChange(1,'filePath','fileUpLoadHiddenIDNewObject','fileTitle')"&gt;&lt;/b&gt;&lt;/td&gt;<br /> &lt;/tr&gt;<br /> &lt;tr  class="ListTableRow" &gt;<br />     &lt;td width="100%" colspan="3" &gt;&lt;input type="submit" name="Submit" value="提交" class="Button4"&gt;<br />     &lt;input type="button" name="Submit" value="新增附件" class="Button4"  onclick="addCode()"&gt;<br />    &lt;/td&gt;<br /> &lt;/tr&gt;<br /> &lt;/table&gt;<br />&lt;/html:form&gt;<br />&lt;script language="javascript" type="text/javascript"&gt;<br />String.prototype.trim = function()<br />{<br />    return this.replace(/(^[\s]*)|([\s]*$)/g, "");<br />}<br />function addCode(){<br />  var objTable=document.all("testArr");<br />  var objTableLength=objTable.rows.length<br />  var objChild=document.all("fileUpLoadNumberRow");<br />  objChild.value=parseInt(objChild.value,10)+1;<br />  var myrow=objTable.insertRow(objTableLength-1);<br />  var mycell=myrow.insertCell();<br />  mycell.innerHTML="&lt;input type='button' name='Submit' value='删除' class='Button4' onClick='delCode("+(objTableLength-2+1)+")'&gt;";</p>
		<p>  mycell=myrow.insertCell();<br />  mycell.innerHTML="&lt;input type='hidden' name='fileUpLoadHiddenIDNewObject"+objChild.value+"'  id='fileUpLoadHiddenIDNewObject"+objChild.value+"'&gt;&lt;input type='text' name='fileTitle"+objChild.value+"' &lt;%=input100Change%&gt; id='fileTitle"+objChild.value+"'  value='' trim='true' dataType='Require'  msg='文件描述不能为空！'&gt;";<br />  mycell=myrow.insertCell();<br />  var html=""<br />  html=html+"&lt;input type='file' name='filePath"+objChild.value+"' &lt;%=input100%&gt; id='filePath"+objChild.value+"' onChange=showFileChange("+objChild.value+",'filePath','fileUpLoadHiddenIDNewObject','fileTitle')&gt;";<br />  mycell.innerHTML=html</p>
		<p>}<br />function delCode(rowNum)<br />{<br />  var objTable=document.all("testArr");<br />  if(window.confirm("真的要删除所选项！"))<br />  {<br />         objTable.deleteRow(rowNum);<br />  }<br />  for(var i=1;i&lt;objTable.rows.length-1;i++)<br />  {</p>
		<p>         objTable.rows(i).cells(0).innerHTML="&lt;input type='button' name='Submit' value='删除' class='Button4' onClick='delCode("+i+")'&gt;";</p>
		<p>  }</p>
		<p>}<br />function changeButtomHtml()<br />{</p>
		<p>}</p>
		<p>&lt;/script&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</p>
		<p> </p>
		<p>common.jsp     不要的代码请去除</p>
		<p>&lt;!--引入系统中要用的标签--&gt;</p>
		<p>&lt;<a href="mailto:%@taglib">%@taglib</a> uri="/WEB-INF/struts-html.tld" prefix="html"%&gt;<br />&lt;<a href="mailto:%@taglib">%@taglib</a> uri="/WEB-INF/fireeagle.tld" prefix="fireeagle"%&gt;<br />&lt;!--引入系统中要用的类--&gt;<br />&lt;<a href="mailto:%@page">%@page</a> import="java.util.*"%&gt;<br />&lt;<a href="mailto:%@page">%@page</a> import="com.ytstm.frame.IConstants"%&gt;<br />&lt;<a href="mailto:%@page">%@page</a> import="com.ytstm.util.*"%&gt;</p>
		<p>&lt;%<br />  String baseURL = request.getContextPath();      //得到当前发布的根路经<br />  Object objectRes=request.getAttribute("org.apache.struts.action.MESSAGE");  //得到struts当前配置的资源文件<br />  org.apache.struts.util.MessageResources resources =(org.apache.struts.util.MessageResources)objectRes;<br />  String exitPro="";                       //当页面处在修改状态时的提示语<br />  String pageNum_fireeagle="";             //翻页时当输入的不是数字时的提示语<br />  if(resources!=null)<br /> {<br />  exitPro= resources.getMessage("exitPro");<br />  pageNum_fireeagle=resources.getMessage("pageNum");<br /> }</p>
		<p>%&gt;<br />&lt;script language="javascript" type="text/javascript"&gt;<br />  var baseURL='&lt;%=baseURL%&gt;';        //得到当前发布的根路经<br />  var editModel_fireeagle=false;     //用户操作的当前页面的状态. true以修改数据,false没有修改数据<br />  var exitPro='&lt;%=exitPro%&gt;'         //当页面处在修改状态时的提示语<br />  var pageNum_fireeagle='&lt;%=pageNum_fireeagle%&gt;'   //翻页时当输入的不是数字时的提示语<br /> &lt;/script&gt;<br />&lt;%<br />  //tableStyle  表格的样式,可以减少页面的html代码量<br />  String tableStyle="width=\"100%\"  border=\"1\" cellSpacing=\"0\" cellpadding=\"3\"   bordercolorlight=\"#E2D7CF\" bordercolordark=\"#FAF8F6\"";<br />  String frame = baseURL + "/frame"; //框架模块的前缀<br />  String project = baseURL + "/project";//项目立项模块的前缀<br />  String contract = baseURL + "/contract";//合同模块的前缀<br />  String process = baseURL + "/process";//过程模块的前缀</p>
		<p>  //input 的样式和键盘按下事件,它会转入到下一个可输入控件,可以减少页面的html代码量<br />  String input="class='formStyleall' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input4="class='formStyleall' size='4' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />   String input10="class='formStyleall' size='12' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input12="class='formStyleall' size='12' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input15="class='formStyleall' size='15' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input20="class='formStyleall' size='20' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input25="class='formStyleall' size='25' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input30="class='formStyleall' size='30' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input35="class='formStyleall' size='35' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input40="class='formStyleall' size='40' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input50="class='formStyleall' size='50' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />  String input60="class='formStyleall' size='60' onKeyDown='next_focus(this)' onChange='changeEditModel()'";<br />   String input100="class='formStyleall' style='width=100%' onKeyDown='next_focus(this)'";<br />   String input100Change="class='formStyleall' style='width=100%' onKeyDown='next_focus(this)' onChange='changeEditModel()'";</p>
		<p>  //onchange事件的全局变量,这个方法用于修改用户操作的当前页面的状态.<br />  String onChange="onChange='changeEditModel()'";<br />  String changeName="'changeEditModel()'";<br />  //给色*号标示.和()标示,可以减少页面的html代码量<br />  String red="&amp;nbsp;&amp;nbsp;&lt;font color='red'&gt;&lt;b&gt;*&lt;/b&gt;&lt;/font&gt;";<br />  String redLeft="&lt;font color='#FF0000'&gt;(&lt;/font&gt;";<br />  String redRight="&lt;font color='#FF0000'&gt;)&lt;/font&gt;";<br />  String orderTitle="style='cursor:hand'  align='center'";<br />  //查看,新增,修改.用在联接?后面<br />  String modifyView=IConstants.FRAME_MODIFY_FLAG+"="+IConstants.FRAME_MODIFY_FLAG_VIEW;<br />  String modifyAdd=IConstants.FRAME_MODIFY_FLAG+"="+IConstants.FRAME_MODIFY_FLAG_ADD;<br />  String modifyEdit=IConstants.FRAME_MODIFY_FLAG+"="+IConstants.FRAME_MODIFY_FLAG_EDIT;</p>
		<p>  //页面退出是要执行的方法,当用户修改了页面内容后退出页面时,要给提示信息给用户<br />  String onbeforeunload ="onbeforeunload='javacript:return(isClose())'";<br />  //屏蔽页面的右键功能<br />// String disableCopy="ondragstart=self.event.returnValue=true onselectstart=self.event.returnValue=true oncontextmenu=self.event.returnValue=false";<br />String disableCopy="";<br />%&gt;<br />&lt;!--引入公用的js代码--&gt;<br />&lt;script type="text/javascript" src="&lt;%=baseURL%&gt;/js/public.js"&gt;&lt;/script&gt;<br />&lt;!--引入公验证的js代码--&gt;<br />&lt;script type="text/javascript" src="&lt;%=baseURL%&gt;/js/validator.js"&gt;&lt;/script&gt;<br />&lt;script type="text/javascript" src="&lt;%=baseURL%&gt;/js/sorttable/sortabletable.js"&gt;&lt;/script&gt;<br />&lt;script type="text/javascript" src="&lt;%=baseURL%&gt;/js/selectdate1.js"&gt;&lt;/script&gt;<br />&lt;link href="&lt;%=baseURL%&gt;/css/main.css" rel="stylesheet" type="text/css"&gt;<br />&lt;!--有错误信息和提示信息时层要显示的位置--&gt;<br />&lt;style type="text/css"&gt;<br />&lt;!--<br /> #errorDiv {<br /> position: absolute;<br /> left: 20%;<br /> top: 20%;<br /> width: 352px;<br /> height: 21px;<br /> background-color: #FFFFFF;<br /> }<br />--&gt;<br />&lt;/style&gt;</p>
		<p> </p>
		<p>publlic.js   不要的代码请去除</p>
		<p> </p>
		<p>
				<br />function next_focus(text)<br />{<br /> if(window.event.keyCode ==13)<br /> {<br />  window.event.keyCode=9;<br /> }<br />}</p>
		<p>
				<br />function mouseovertd (o)<br />{<br /> o.style.color='#ffffff';<br /> o.style.backgroundColor='#B3B3B3';</p>
		<p>}<br />function mouseouttd (o)<br />{<br /> o.style.color='#000000';<br /> o.style.backgroundColor='';</p>
		<p>}</p>
		<p> </p>
		<p>function goPage(flag,currPage,formId,formAction,formTarget,formMethod,pageNumId)<br />{<br />  var formObj=document.all(formId)<br />   formObj.target=formTarget;<br /> formObj.method=formMethod;<br /> if(flag=='go')<br /> {<br />  var obj=document.all(pageNumId)<br />   if(isNaN(obj.value))<br />     {<br />       alert(pageNum_fireeagle);<br />         obj.select();<br />         return;<br />     }<br />  else<br />  {<br />   currPage=obj.value<br />  }<br /> }</p>
		<p> pageMethod="pageMethod="+flag+"&amp;currentPage="+currPage;<br /> formAction=formAction+"&amp;"+pageMethod;<br /> formObj.action=formAction;<br />        top.bottom.document.all("process").innerHTML="&lt;img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'&gt;";<br /> formObj.submit();<br />}<br />function submitForm(formId,submitbutton)<br />{<br />  editModel_fireeagle=false;<br /> submitbutton.disabled=true<br />  var objForm =document.all(formId);<br />   if(Validator.Validate(objForm,2))<br />   {<br />    top.bottom.document.all("process").innerHTML="&lt;img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'&gt;";<br />    objForm.submit();<br />   }<br />   else<br />   {<br />        submitbutton.disabled=false<br />   }<br />}<br />function delOnClick(url,target)<br />{</p>
		<p>   if(window.confirm("确定删除！"))<br />   {<br />      top.bottom.document.all("process").innerHTML="&lt;img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'&gt;"<br />     if(target=='parent')<br />     {<br />     parent.location.href=url<br />     }else if(target=='self')<br />     {<br />     location.href=url<br />     }<br />   }<br />}<br />function submitFormQuery(formId,queryFlag)<br />{</p>
		<p>  var objForm =document.all(formId);<br />  objForm.is_QUERY.value=queryFlag;<br />  top.bottom.document.all("process").innerHTML="&lt;img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'&gt;";<br />   objForm.submit();</p>
		<p>}</p>
		<p>
				<br />function buttomOnClick(url,target)<br />{<br />   top.bottom.document.all("process").innerHTML="&lt;img name='pro' src='"+baseURL+"/images/public/process.gif' border='0'&gt;"<br />if(target=='parent')<br />   {<br />    parent.location.href=url<br />   }else if(target=='self')<br />   {<br />      location.href=url<br />   }<br />}</p>
		<p>function changeEditModel()<br />{<br />  editModel_fireeagle=true<br />}</p>
		<p>function isClose()<br />{<br />if(editModel_fireeagle)<br />  {<br />    top.bottom.document.all("process").innerHTML="&lt;img name='pro' src='"+baseURL+"/images/public/prosessEnd.gif' border='0'&gt;"<br />  return exitPro<br />  }<br />}</p>
		<p>//只能输入数字<br />//页面使用:&lt;input type=text name=test value="" onKeypress="JHshNumberText()"&gt;<br />function JHshNumberText()<br />{<br />  if ( !(((window.event.keyCode &gt;= 48) &amp;&amp; (window.event.keyCode &lt;= 57))<br />  || (window.event.keyCode == 13) || (window.event.keyCode == 46)<br />  || (window.event.keyCode == 45)))<br />  {<br />    window.event.keyCode = 0 ;<br />  }<br />}</p>
		<p>document.onkeydown = openHelp<br />function openHelp()<br />{<br /> if(window.event.keyCode==113)<br />        {<br />          if(top.main.document.title.indexOf("HELP")&gt;=0)<br />          {<br />            showModalDialog(baseURL+"/frame/help/"+top.main.document.title);<br />          }<br />        }</p>
		<p>    if(window.event.keyCode==116)<br />    {<br />      event.keyCode=0;<br />      event.returnValue=false;</p>
		<p>    }<br />}<br />function jtrim(sstr)   //去掉左右空格<br />{<br />  var astr="";<br />  var dstr="";<br />  var flag=0;<br />  for (i=0;i&lt;sstr.length;i++)<br />  {if ((sstr.charAt(i)!=' ')||(flag!=0))<br />  {dstr+=sstr.charAt(i);<br />  flag=1;<br />  }<br />  }<br />  flag=0;<br />  for (i=dstr.length-1;i&gt;=0;i--)<br />  {if ((dstr.charAt(i)!=' ')||(flag!=0))<br />  {astr+=dstr.charAt(i);<br />  flag=1;<br />  }<br />  }<br />  dstr="";<br />  for (i=astr.length-1;i&gt;=0;i--) dstr+=astr.charAt(i);<br />  return dstr;<br />}</p>
		<p>function popup(page,w,h){ //在窗口中央弹出窗口<br />  var width=screen.width;<br />  var height=screen.height;<br />  var arg;<br />  l=(width-w)/2;<br />  t=(height-h)/2;<br />  if (width&gt;w &amp;&amp; height&gt;h) arg="top="+t+",left="+l+",";<br />  win=window.open (page,"select", arg+"height="+h+", width="+w+",toolbar=no, menubar=no, scrollbars=auto, resizable=no, location=no, status=no");<br />  return win;<br />}</p>
		<p>function popupProject(page,w,h){ //在窗口中央弹出窗口<br />  var width=screen.width;<br />  var height=screen.height;<br />  var arg;<br />  l=(width-w)/2;<br />  t=(height-h)/2;<br />  if (width&gt;w &amp;&amp; height&gt;h) arg="top="+t+",left="+l+",";<br />  win=window.open (page,"select", arg+"height="+h+", width="+w+",toolbar=no, menubar=no, scrollbars=yes, resizable=tes, location=no, status=no");<br />  return win;<br />}</p>
		<p>var LookProjectWin=null;<br />function lookProject(url)<br />{<br /> LookProjectWin= popupProject(url,750,450)<br />}<br />function exitWindow()<br />{<br />  if(LookProjectWin!=null)<br />  {<br />    LookProjectWin.close();<br />  }<br />}</p>
		<p>//flag  文件标示<br />//filePath  文件路经标示<br />//fileUpLoadHiddenIDNewObject 文件隐藏控件名标示<br />//fileTitle 文件标题控件名标示<br />function showFileChange(flag,filePath,fileUpLoadHiddenIDNewObject,fileTitle)<br />{<br />  var sorFileName=document.all(filePath+flag).value<br />  var pos=sorFileName.lastIndexOf("\\");<br />  var fuleName=sorFileName.substring(pos+1);<br />  document.all(fileUpLoadHiddenIDNewObject+flag).value=fuleName<br />  var dotPos=fuleName.lastIndexOf(".");<br />  var fuleNameDot=fuleName.substring(0,dotPos);<br />  if(document.all(fileTitle+flag).value=="")<br />    document.all(fileTitle+flag).value=fuleNameDot<br />}<br /></p>
		<p>struts配置</p>
		<p> &lt;form-beans&gt;<br />    &lt;form-bean name="testForm" type="com.ytstm.TestForm"/&gt;<br />  &lt;/form-beans&gt;</p>
		<p> &lt;action path="/testArr" type="com.ytstm.TestArr" name="testForm"&gt;<br />      &lt;forward name="test" path="/testArr.jsp" /&gt;<br />    &lt;/action&gt;</p>
		<p> </p>
		<p> </p>
		<p>com.ytstm.TestForm</p>
		<p>package com.ytstm;</p>
		<p>import org.apache.struts.action.*;</p>
		<p>public class TestForm extends ActionForm{<br />    public TestForm() {<br />    }</p>
		<p>
				<br />}</p>com.ytstm.TestArr 
<p>package com.ytstm;</p><p>import org.apache.struts.action.ActionForward;<br />import javax.servlet.http.HttpServletRequest;<br />import org.apache.struts.action.ActionMapping;<br />import javax.servlet.http.HttpServletResponse;<br />import org.apache.struts.action.ActionForm;<br />import java.util.*;<br />import org.apache.struts.upload.*;<br />import java.io.*;<br />import com.ytstm.util.UpLoadUtil;</p><p>public class TestArr extends org.apache.struts.action.Action{<br />    public TestArr() {<br />    }</p><p>    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception<br /> {<br />            List returnArr=UpLoadUtil.upload(form,request,"testTable","F:/ytstm/YTSTMWeb/fileset/","fileUpLoadNumberRow","fileUpLoadHiddenIDNewObject","fileTitle");<br />            if(returnArr!=null)<br />            {<br />                for(int i=0;i&lt;returnArr.size();i++)<br />                {<br />                    Map map=(Map)returnArr.get(i);<br />                    System.out.println("TABLENAME==="+map.get("TABLENAME"));<br />                    System.out.println("FILENAME==="+map.get("FILENAME"));<br />                    System.out.println("FILEPATH==="+map.get("FILEPATH"));<br />                    System.out.println("FILETYPE==="+map.get("FILETYPE"));<br />                    System.out.println("FORMERLYFILENAME==="+map.get("FORMERLYFILENAME"));<br />                }<br />            }<br />            return mapping.findForward("test");<br />        }<br />}<br /></p><p>com.ytstm.util.UpLoadUtil</p><p>package com.ytstm.util;</p><p>import org.apache.struts.action.*;<br />import javax.servlet.http.*;<br />import java.util.*;<br />import java.io.*;<br />import org.apache.struts.upload.*;</p><p>public class UpLoadUtil {<br />    public UpLoadUtil() {<br />    }<br />    /**<br />     *<br />     * @param form ActionForm<br />     * @param request HttpServletRequest<br />     * @param tableName String     表名<br />     * @param storePath String     路经<br />     * @param fileNumControl String  表示附件个数的页面控件名<br />     * @param fileNumControl String  表示附件隐藏的页面控件名<br />     * @return List<br />     * @throws IOException<br />     */<br />    public static List upload(ActionForm form, HttpServletRequest request,String tableName,String storePath,String fileNumControl,String hiddenIDNewObject,String fileTitle) throws<br />            IOException<br />    {<br />         List retList = new ArrayList(); //存放附件的信息<br />         Hashtable files = form.getMultipartRequestHandler().getFileElements();<br />        String strnumberRowNew = request.getParameter(fileNumControl);<br />        int intnumberRowNew = 0;<br />        FormFile ff[] = null;<br />        ff = new FormFile[files.size()];<br />        Enumeration fileKey = files.keys();<br />        int i = 0;</p><p>        while (fileKey.hasMoreElements()) {<br />            String ffname = (String) fileKey.nextElement();</p><p>            ff[i] = (FormFile) files.get(ffname);<br />            i++;<br />        }</p><p>        for (int a = 0; a &lt; ff.length; a++) {<br />            if (ff[a] == null || ff[a].getFileSize() == 0 ||<br />                ff[a].getFileName() == null<br />                || ff[a].getFileName().equals("")) {<br />            } else {</p><p>               Map fileMap=new HashMap();<br />               fileMap.put("TABLENAME",tableName); //表名，设为信息表</p><p>                InputStream stream = ff[a].getInputStream();<br />                java.util.Date date = new java.util.Date(System.<br />                        currentTimeMillis()); //获取当前时间<br />                String virFileName = date.getTime()+""+a;<br />                fileMap.put("FORMERLYFILENAME",ff[a].getFileName()); //标题文件的名字</p><p><br />                if (strnumberRowNew != null) {<br />                    intnumberRowNew = Integer.parseInt(strnumberRowNew);<br />                    for (int n = 1; n&lt;= intnumberRowNew; n++) {<br />                    String filesor = request.getParameter(hiddenIDNewObject + n);<br />                        if (filesor!=null&amp;&amp;filesor.equals(ff[a].getFileName())) {<br />                            String fileTitleValue = request.getParameter(fileTitle + n);<br />                            fileMap.put("FILENAME",fileTitleValue);<br />                            break;<br />                        }<br />                    }<br />                }</p><p><br />                int dotIndex = ff[a].getFileName().lastIndexOf(".");<br />                String fileType = ff[a].getFileName().substring(dotIndex + 1);<br />                fileMap.put("FILEPATH",virFileName + "." + fileType); //路径<br />                fileMap.put("FILETYPE",fileType);</p><p><br />                retList.add(fileMap);</p><p>                OutputStream bos =<br />                        new FileOutputStream(storePath + virFileName +<br />                                             "." + fileType);</p><p>                int bytesRead = 0;<br />                byte[] buffer = new byte[8192];<br />                while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {<br />                    bos.write(buffer, 0, bytesRead);<br />                }<br />                bos.close();<br />            }<br />        }</p><p>         return retList;</p><p>    }<br />    /**<br />     *<br />     * @param request HttpServletRequest<br />     * @param list List                  数据中以存在附件<br />     * @param fileNumControl String      同上<br />     * @param hiddenIDNewObject String   同上<br />     * @param fileTitle String           同上<br />     * @return List<br />     */<br />    public List combinateEditList(HttpServletRequest request, List list,String fileNumControl,String hiddenIDNewObject,String fileTitle) {<br />          List result=new ArrayList();<br />          if(list==null||list.size()==0) return new ArrayList();<br />           String strnumberRowNew = request.getParameter(fileNumControl);<br />          int  intnumberRowNew=0;<br />           if (strnumberRowNew != null) {<br />               intnumberRowNew = Integer.parseInt(strnumberRowNew);<br />               for (int n = 1; n &lt;= intnumberRowNew; n++) {<br />                   String filesor = request.getParameter("hiddenIDNewObject" +  n);<br />                   String fileTitleValue = request.getParameter(fileTitle + n);<br />                   for(int i=0;i&lt;list.size();i++)<br />                   {<br />                       Map fileMap = (Map)list.get(i);<br />                       if((fileMap.get("ACCESSORYID").toString()).equals(filesor))<br />                       {<br />                           fileMap.put("FILENAME",fileTitleValue);<br />                           result.add(fileMap);<br />                            break;<br />                       }<br />                   }<br />               }<br />           }<br />           return result;<br />    }</p><p>}<br /></p><p>如果出现中文乱码，请修改struts源程序的相关类把编码修改成utf-8,网上可以查到。<br /></p><img src ="http://www.blogjava.net/19851985lili/aggbug/97645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-02 20:34 <a href="http://www.blogjava.net/19851985lili/articles/97645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts Validator验证器使用指南 </title><link>http://www.blogjava.net/19851985lili/articles/97634.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 02 Feb 2007 12:21:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/97634.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/97634.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/97634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/97634.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/97634.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 验证器：																																																								从0.5版，验证器在一些form中就已经实现了，他最初包含在开发人员包中，后来核心代码挪到Jakarta Commons包中和Struts特别扩展中作为 Struts 1.1的一部分。许多开发者为方便一直使用struts验证器，这篇文档...&nbsp;&nbsp;<a href='http://www.blogjava.net/19851985lili/articles/97634.html'>阅读全文</a><img src ="http://www.blogjava.net/19851985lili/aggbug/97634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-02-02 20:21 <a href="http://www.blogjava.net/19851985lili/articles/97634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>StrutsTest使用手册 </title><link>http://www.blogjava.net/19851985lili/articles/93525.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 12 Jan 2007 12:10:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/93525.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/93525.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/93525.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/93525.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/93525.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: StrutsTest:																																																																http://strutstestcase.sourceforge.net/																																																									...&nbsp;&nbsp;<a href='http://www.blogjava.net/19851985lili/articles/93525.html'>阅读全文</a><img src ="http://www.blogjava.net/19851985lili/aggbug/93525.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-12 20:10 <a href="http://www.blogjava.net/19851985lili/articles/93525.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jakarta-Common-BeanUtils使用笔记</title><link>http://www.blogjava.net/19851985lili/articles/93513.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Fri, 12 Jan 2007 11:13:00 GMT</pubDate><guid>http://www.blogjava.net/19851985lili/articles/93513.html</guid><wfw:comment>http://www.blogjava.net/19851985lili/comments/93513.html</wfw:comment><comments>http://www.blogjava.net/19851985lili/articles/93513.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/19851985lili/comments/commentRss/93513.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/19851985lili/services/trackbacks/93513.html</trackback:ping><description><![CDATA[   <span style="FONT-FAMILY: 宋体">第一次接触</span><span lang="EN-US">BeanUtils</span><span style="FONT-FAMILY: 宋体">是在学习</span><span lang="EN-US">Struts</span><span style="FONT-FAMILY: 宋体">的过程中，在</span><span lang="EN-US">Struts</span><span style="FONT-FAMILY: 宋体">中它被大量用于处理</span><span lang="EN-US">FormBean</span><span style="FONT-FAMILY: 宋体">。</span><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang="EN-US">BeanUtils</span><span style="FONT-FAMILY: 宋体">主要提供了对于</span><span lang="EN-US">JavaBean</span><span style="FONT-FAMILY: 宋体">进行各种操作，</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span>BeanUtils</span><span style="FONT-FAMILY: 宋体">一共分</span><span lang="EN-US">4</span><span style="FONT-FAMILY: 宋体">个包：</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt"><span lang="EN-US" style="FONT-FAMILY: Wingdings"><span>Ø<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">         </span></span></span><span lang="EN-US" style="FONT-FAMILY: Helvetica">org.apache.commons.beanutils</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt"><span lang="EN-US" style="FONT-FAMILY: Wingdings"><span>Ø<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">         </span></span></span><span lang="EN-US" style="FONT-FAMILY: Helvetica">org.apache.commons.beanutils.converters</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt"><span lang="EN-US" style="FONT-FAMILY: Wingdings"><span>Ø<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">         </span></span></span><span lang="EN-US" style="FONT-FAMILY: Helvetica">org.apache.commons.beanutils.locale</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt"><span lang="EN-US" style="FONT-FAMILY: Wingdings"><span>Ø<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">         </span></span></span><span lang="EN-US" style="FONT-FAMILY: Helvetica">org.apache.commons.beanutils.locale.converters</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 17.95pt"><span style="FONT-FAMILY: 宋体">其中上面两个是</span><span lang="EN-US" style="FONT-FAMILY: Helvetica">BeanUtils</span><span style="FONT-FAMILY: 宋体">的默认实现，它没有针对本地化的任何处理，这个可以提高执行效率。但是若你的程序对于本地化有要求的话，那还是使用下面</span><span lang="EN-US" style="FONT-FAMILY: Helvetica">2</span><span style="FONT-FAMILY: 宋体">个包比较安全。</span><span lang="EN-US" style="FONT-FAMILY: Helvetica"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"></span> </p><p class="1" style="MARGIN: 17pt 0cm 16.5pt 21.25pt"><a name="_Toc93765168"><span lang="EN-US"><span><strong><font size="6">2.</font></strong><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">   </span></span></span><span lang="EN-US"><strong><font size="6">org.apache.commons.beanutils</font></strong></span></a></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">这个包主要提供用于操作</span><span lang="EN-US">JavaBean</span><span style="FONT-FAMILY: 宋体">的工具类，</span><span lang="EN-US" style="FONT-FAMILY: 宋体">Jakarta-Common-BeanUtils</span><span style="FONT-FAMILY: 宋体">的主要功能都在这个包里实现。<span lang="EN-US"></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-FAMILY: 宋体"><span>    </span></span><span style="FONT-FAMILY: 宋体">下面分别介绍几个主要的工具类：</span></p><p class="2" style="MARGIN: 13pt 0cm 13pt 1cm"><a name="_Toc93765169"><span lang="EN-US"><span><strong><font face="Arial" size="5">2.1.</font></strong><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"></span></span></span><span lang="EN-US"><strong><font face="Arial" size="5">BeanUtil</font></strong></span></a></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体">、首先，我先定义一个</span><span lang="EN-US">JavaBean</span><span style="FONT-FAMILY: 宋体">作为之后例子的操作对象。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)">    public class Company</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)">    {</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>private String name;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>private HashMap address = new HashMap();</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>private String[] otherInfo;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>private ArrayList product;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>private ArrayList employee;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>private HashMap telephone;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public Company(){}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public String getName()</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>return name;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public void setName(String name)</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>this.name = name;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public String getAddress(String type)</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>return address.get(type).toString();</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public void setAddress(String type, String address)</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>this.address.put(type,address);</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public String[] getOtherInfo()</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>return otherInfo;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public void setOtherInfo(String[] otherInfo)</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>this.otherInfo = otherInfo;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public ArrayList getProduct()</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>return product;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public void setProduct(ArrayList product)</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>this.product = product;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public ArrayList getEmployee()</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>return employee;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public void setEmployee(ArrayList employee)</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>this.employee = employee;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public HashMap getTelephone()</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>return telephone;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>public void setTelephone(HashMap telephone)</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>{</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>this.telephone = telephone;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>}</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)">    }</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US">2</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">BeanUtils</span><span style="FONT-FAMILY: 宋体">可以直接</span><span lang="EN-US">get</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">set</span><span style="FONT-FAMILY: 宋体">一个属性的值。它将</span><span lang="EN-US">property</span><span style="FONT-FAMILY: 宋体">分成</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体">种类型：</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span>Simple</span><span style="FONT-FAMILY: 宋体">——简单类型，如</span><span lang="EN-US">Stirng</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">Int</span><span style="FONT-FAMILY: 宋体">……</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span>Indexed</span><span style="FONT-FAMILY: 宋体">——索引类型，如</span><span style="FONT-FAMILY: 宋体">数组、</span><span lang="EN-US">arrayList</span><span style="FONT-FAMILY: 宋体">……</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span>Maped</span><span style="FONT-FAMILY: 宋体">——这个不用说也该知道，就是指</span><span lang="EN-US">Map</span><span style="FONT-FAMILY: 宋体">啦，比如</span><span lang="EN-US">HashMap</span><span style="FONT-FAMILY: 宋体">……</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">访问不同类型的数据可以直接调用函数</span><span lang="EN-US">getProperty</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">setProperty</span><span style="FONT-FAMILY: 宋体">。它们都只有</span><span lang="EN-US">2</span><span style="FONT-FAMILY: 宋体">个参数，第一个是</span><span lang="EN-US">JavaBean</span><span style="FONT-FAMILY: 宋体">对象，第二个是要操作的属性名。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)">Company c = new Company();</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)">c.setName("Simple");</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt"><span lang="EN-US"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt"><span style="FONT-FAMILY: 宋体">对于</span><span lang="EN-US">Simple</span><span style="FONT-FAMILY: 宋体">类型，参数二直接是属性名即可</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt"><span lang="EN-US" style="COLOR: green">//Simple</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>    </span><span style="COLOR: rgb(51,102,255)">System.out.println(BeanUtils.getProperty(c, "name"));</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: green"><span>    </span></span><span style="FONT-FAMILY: 宋体">对于</span><span lang="EN-US">Map</span><span style="FONT-FAMILY: 宋体">类型，则需要以“属性名（</span><span lang="EN-US">key</span><span style="FONT-FAMILY: 宋体">值）”的形式</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang="EN-US" style="COLOR: green">//Map</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>    </span><span style="COLOR: rgb(51,102,255)">System.out.println(BeanUtils.getProperty(c, "address (A2)"));</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>    </span>HashMap am = new HashMap();</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>    </span>am.put("1","234-222-1222211");</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>    </span>am.put("2","021-086-1232323");</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>    </span>BeanUtils.setProperty(c,"telephone",am);</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>    </span>System.out.println(BeanUtils.getProperty(c, "telephone (2)"));</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>    </span></span><span style="FONT-FAMILY: 宋体">对于</span><span lang="EN-US">Indexed</span><span style="FONT-FAMILY: 宋体">，则为“属性名</span><span lang="EN-US">[</span><span style="FONT-FAMILY: 宋体">索引值</span><span lang="EN-US">]</span><span style="FONT-FAMILY: 宋体">”，注意这里对于</span><span lang="EN-US">ArrayList</span><span style="FONT-FAMILY: 宋体">和数组都可以用一样的方式进行操作。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang="EN-US" style="COLOR: green">//index</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>    </span><span style="COLOR: rgb(51,102,255)">System.out.println(BeanUtils.getProperty(c, "otherInfo[2]"));</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>    </span>BeanUtils.setProperty(c, "product[1]", "NOTES SERVER");</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>    </span>System.out.println(BeanUtils.getProperty(c, "product[1]"));</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">当然这</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体">种类也可以组合使用啦！</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>    </span><span style="COLOR: green">//nest</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>    </span><span style="COLOR: rgb(51,102,255)">System.out.println(BeanUtils.getProperty(c, "employee[1].name"));</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体">、此外，还有一个很重要的方法</span><span lang="EN-US">copyProperty</span><span style="FONT-FAMILY: 宋体">，可以直接进行</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">之间的</span><span lang="EN-US">clone</span><span style="FONT-FAMILY: 宋体">。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span><span style="COLOR: rgb(51,102,255)">Company c2 = new Company();</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>        </span>BeanUtils.copyProperties(c2, c);</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">但是这种</span><span lang="EN-US">copy</span><span style="FONT-FAMILY: 宋体">都是浅拷贝，复制后的</span><span lang="EN-US">2</span><span style="FONT-FAMILY: 宋体">个</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">的同一个属性可能拥有同一个对象的</span><span lang="EN-US">ref</span><span style="FONT-FAMILY: 宋体">，这个在使用时要小心，特别是对于属性为自定义类的情况。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US">4</span><span style="FONT-FAMILY: 宋体">、最后还有</span><span lang="EN-US">populate</span><span style="FONT-FAMILY: 宋体">，它用于将一个</span><span lang="EN-US">map</span><span style="FONT-FAMILY: 宋体">的值填充到一个</span><span lang="EN-US">bean</span><span style="FONT-FAMILY: 宋体">中，其函数原型如下：</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.75pt; TEXT-ALIGN: left" align="left"><span lang="EN-US" style="COLOR: rgb(51,102,255); FONT-FAMILY: 宋体">public void <font color="#3366ff"><b>populate</b>(java.lang.Object bean,</font></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.75pt; TEXT-ALIGN: left" align="left"><span lang="EN-US" style="COLOR: rgb(51,102,255); FONT-FAMILY: 宋体"><span>                </span>java.util.Map properties)</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left" align="left"><span lang="EN-US" style="COLOR: rgb(51,102,255); FONT-FAMILY: 宋体"><span>              </span>throws java.lang.IllegalAccessException,</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255); FONT-FAMILY: 宋体"><span>                     </span>java.lang.reflect.InvocationTargetException</span><span lang="EN-US"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">在</span><span lang="EN-US">struts</span><span style="FONT-FAMILY: 宋体">中这个函数被用于从</span><span lang="EN-US">http request</span><span style="FONT-FAMILY: 宋体">中取得参数添加到</span><span lang="EN-US">FormBean</span><span style="FONT-FAMILY: 宋体">，目前好像我也没有看到这个函数还有什么其他的用途？！以后想到再说吧：</span><span lang="EN-US">P</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"></span> </p><p class="2" style="MARGIN: 13pt 0cm 13pt 1cm"><a name="_Toc93765170"><span lang="EN-US"><span><strong><font face="Arial" size="5">2.2.</font></strong><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"></span></span></span><span lang="EN-US"><strong><font face="Arial" size="5">LazyDynaBean</font></strong></span></a></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">它实现一个动态的</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">，可以直接往里面加入属性，作为一个</span><span lang="EN-US">JavaBean</span><span style="FONT-FAMILY: 宋体">一样使用，也可以用上面的</span><span lang="EN-US">BeanUtils</span><span style="FONT-FAMILY: 宋体">或</span><span lang="EN-US">get/set</span><span style="FONT-FAMILY: 宋体">方法进行操作，而不用事先定义一个标准的</span><span lang="EN-US">JavaBean</span><span style="FONT-FAMILY: 宋体">类啦：）</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">记得在</span><span lang="EN-US">J2ee</span><span style="FONT-FAMILY: 宋体">设计模式中有一种</span><span lang="EN-US">Value Object</span><span style="FONT-FAMILY: 宋体">的模式，用于在</span><span lang="EN-US">MVC</span><span style="FONT-FAMILY: 宋体">各层之间传递数据，避免直接传递大业务对象引起的性能问题，为了避免在项目中出现很多</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">类，在书中提供了一个动态</span><span lang="EN-US">Value Object</span><span style="FONT-FAMILY: 宋体">的实现（通过扩展</span><span lang="EN-US">Map</span><span style="FONT-FAMILY: 宋体">）。这里</span><span lang="EN-US">LazyDynaBean</span><span style="FONT-FAMILY: 宋体">则可以作为一种更加成熟、稳定的实现来使用。呵呵，原来曾打算自己写一个类似的</span><span lang="EN-US">value object</span><span style="FONT-FAMILY: 宋体">类的，现在看来可以直接用这个啦：</span><span lang="EN-US">P</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">言归正传，</span><span lang="EN-US">LazyBean</span><span style="FONT-FAMILY: 宋体">的确提供了一个很不错的</span><span lang="EN-US">DynaBean</span><span style="FONT-FAMILY: 宋体">的实现。而且就像它的名字中表述的那样，它的确是为我这样的懒人考虑的很周到，用起来几乎不需要写什么多余的代码</span><span lang="EN-US">^_^</span><span style="FONT-FAMILY: 宋体">，下面就看看使用的例子吧！</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span><span>  </span><span style="COLOR: rgb(51,153,102)">//</span></span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">这里使用</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">LazyDynaMap</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">，它是</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">LazyBean</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">的一个轻量级实现</span><span lang="EN-US" style="COLOR: rgb(51,153,102)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>      </span><span style="COLOR: rgb(51,102,255)">LazyDynaMap dynaBean1 = new LazyDynaMap();</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>      </span><span style="COLOR: rgb(51,102,255)">dynaBean1.set("foo", "bar");<span>                  </span></span><span style="COLOR: rgb(51,153,102)">// simple</span><span style="COLOR: rgb(51,102,255)"></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>dynaBean1.set("customer", "title", "Mr");<span>     </span><span>   </span></span><span lang="EN-US" style="COLOR: rgb(51,153,102)">// mapped</span><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>dynaBean1.set("address", 0, "address1");<span>      </span><span>   </span></span><span lang="EN-US" style="COLOR: rgb(51,153,102)">// indexed</span><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>System.out.println(dynaBean1.get("address",0));</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>Map myMap = dynaBean1.getMap();<span>           </span></span><span lang="EN-US" style="COLOR: rgb(51,153,102)">// retrieve the Map</span><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>System.out.println(myMap.toString());</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">上面的例子可以看到，它可以在</span><span lang="EN-US">set</span><span style="FONT-FAMILY: 宋体">时自动增加</span><span lang="EN-US">bean</span><span style="FONT-FAMILY: 宋体">的</span><span lang="EN-US">property</span><span style="FONT-FAMILY: 宋体">（既赋值的同时增加</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">中的</span><span lang="EN-US">property</span><span style="FONT-FAMILY: 宋体">），同时也支持</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体">中类型的</span><span lang="EN-US">property</span><span style="FONT-FAMILY: 宋体">，并且</span><span lang="EN-US">LazyDynaMap</span><span style="FONT-FAMILY: 宋体">还可以导出为</span><span lang="EN-US">map</span><span style="FONT-FAMILY: 宋体">。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">对于这个类还有两个重要的</span><span lang="EN-US">Field</span><span style="FONT-FAMILY: 宋体">要注意：</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span>returnnull</span><span style="FONT-FAMILY: 宋体">——指定在</span><span lang="EN-US">get</span><span style="FONT-FAMILY: 宋体">方法使用了一个没有定义过的</span><span lang="EN-US">property</span><span style="FONT-FAMILY: 宋体">时，</span><span lang="EN-US">DynaBean</span><span style="FONT-FAMILY: 宋体">的行为。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span><span>  </span><span style="COLOR: rgb(51,153,102)">//</span></span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">取的字段的信息</span><span lang="EN-US" style="COLOR: rgb(51,153,102)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>      </span><span style="COLOR: rgb(51,102,255)">dynaBean1.setReturnNull(true);</span><span style="COLOR: rgb(51,153,102)">//</span></span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">设为</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">ture</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">。若</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">Bean</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">中没有此字段，返回</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">null</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,153,102)"><span>    </span><span>                            </span>//</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">默认为</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">false</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">。若</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">Bean</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">中没有此字段，自动增加一个：）</span><span lang="EN-US" style="COLOR: rgb(51,153,102)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>System.out.println(dynaBean1.get("aaa"));</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">//</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">此时返回</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">null</span><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span>Restricted</span><span style="FONT-FAMILY: 宋体">——指定是否允许改变这个</span><span lang="EN-US">bean</span><span style="FONT-FAMILY: 宋体">的</span><span lang="EN-US">property</span><span style="FONT-FAMILY: 宋体">。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 31.5pt"><span lang="EN-US" style="COLOR: rgb(51,153,102)">//MutableDynaClass.setRestricted</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">设为</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">true</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">后，字段不可再增删和修改</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">.</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,153,102)"><span>      </span>//</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">默认为</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">false</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">，允许增删和修改</span><span lang="EN-US" style="COLOR: rgb(51,153,102)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>      </span><span style="COLOR: rgb(51,102,255)">dynaBean1.setRestricted(true);</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>dynaBean1.set("test","error");</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">//</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">这里会出错！</span><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">通过设置这两个属性，可以防止意外修改</span><span lang="EN-US">DynaBean</span><span style="FONT-FAMILY: 宋体">的</span><span lang="EN-US">property</span><span style="FONT-FAMILY: 宋体">。在设计架构时，你可以在后台从数据表或</span><span lang="EN-US">xml</span><span style="FONT-FAMILY: 宋体">文件自动产生</span><span lang="EN-US">DynaBean</span><span style="FONT-FAMILY: 宋体">，在传到控制层和表示层之前设置上述属性使其</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">结构不允许修改，如此就不可能无意中修改</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">包含的属性……这样既可以享用它的便利，有可以防止由此引入的错误可能，设计者实在深得偷懒的精髓啊！！！！！</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"></span> </p><p class="1" style="MARGIN: 17pt 0cm 16.5pt 21.25pt"><a name="_Toc93765171"><span lang="EN-US"><span><strong><font size="6">3.</font></strong><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">   </span></span></span><span style="FONT-FAMILY: 宋体"><font size="6"><strong>其他</strong></font></span></a></p><p class="2" style="MARGIN: 13pt 0cm 13pt 1cm"><a name="_Toc93765172"><span lang="EN-US"><span><strong><font face="Arial" size="5">3.1.</font></strong><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"></span></span></span><span lang="EN-US"><font face="Arial" size="5"><strong>BeanUtils</strong></font></span></a><span><strong><font size="5"><span style="FONT-FAMILY: 黑体">和</span><span lang="EN-US"><font face="Arial">PropertyUtils</font></span></font></strong></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">这两个类几乎有一摸一样的功能，唯一的区别是：</span><span lang="EN-US">BeanUtils</span><span style="FONT-FAMILY: 宋体">在对</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">赋值是会进行类型转化。举例来说也就是在</span><span lang="EN-US">copyProperty</span><span style="FONT-FAMILY: 宋体">时只要属性名相同，就算类型不同，</span><span lang="EN-US">BeanUtils</span><span style="FONT-FAMILY: 宋体">也可以进行</span><span lang="EN-US">copy</span><span style="FONT-FAMILY: 宋体">；而</span><span lang="EN-US">PropertyBean</span><span style="FONT-FAMILY: 宋体">则可能会报错！！</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">针对上面的例子，新建一个</span><span lang="EN-US">Company2</span><span style="FONT-FAMILY: 宋体">的类，其中代码与</span><span lang="EN-US">Company</span><span style="FONT-FAMILY: 宋体">一样，只是将</span><span lang="EN-US">otherinfo</span><span style="FONT-FAMILY: 宋体">从</span><span lang="EN-US">String[]</span><span style="FONT-FAMILY: 宋体">改为</span><span lang="EN-US">String</span><span style="FONT-FAMILY: 宋体">。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>      </span><span style="COLOR: rgb(51,102,255)">Company c = init();</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>Company2 c2 = new Company2();</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>BeanUtils.copyProperties(c2,c);</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,153,102)">//<span>      </span>PropertyUtils.copyProperties(c2,c); </span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">这句会报错！！</span><span lang="EN-US" style="COLOR: rgb(51,153,102)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>System.out.println(c2.getOtherInfo());</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>    </span></span><span style="FONT-FAMILY: 宋体">当然</span><span lang="EN-US">2</span><span style="FONT-FAMILY: 宋体">个</span><span lang="EN-US">Bean</span><span style="FONT-FAMILY: 宋体">之间的同名属性的类型必须是可以转化的，否则用</span><span lang="EN-US">BeanUtils</span><span style="FONT-FAMILY: 宋体">一样会报错。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">若实现了</span><span lang="EN-US">org.apache.commons.beanutils.Converter</span><span style="FONT-FAMILY: 宋体">接口则可以自定义类型之间的转化。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">由于不做类型转化，用</span><span lang="EN-US">PropertyUtils</span><span style="FONT-FAMILY: 宋体">在速度上会有很大提高！</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">此外，不作类型转化还有一个好处，如下面的代码：</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span></span><span lang="EN-US" style="COLOR: rgb(51,153,102)">//test data type convert</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,153,102)">//<span>      </span>ArrayList a1 = BeanUtils.getProperty(c,"product"); //BeanUtils</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">返回的是</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">String</span><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>System.out.println("--" + BeanUtils.getProperty(c,"product"));     </span><span lang="EN-US" style="COLOR: rgb(51,153,102)">//</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">取出后直接被转为</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">String</span><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>ArrayList a = (ArrayList)PropertyUtils.getProperty(c,"product");</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">//PropertyUtils</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">返回的是</span><span lang="EN-US" style="COLOR: rgb(51,153,102)">Object</span><span lang="EN-US" style="COLOR: rgb(51,102,255)"></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="COLOR: rgb(51,102,255)"><span>      </span>System.out.println("--" + a.get(1))</span><span lang="EN-US">;</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">用</span><span lang="EN-US">BeanUtils</span><span style="FONT-FAMILY: 宋体">无法返回一个对象（除非自己写一个</span><span lang="EN-US">Converter</span><span style="FONT-FAMILY: 宋体">），它会自动进行类型转化，然后返回</span><span lang="EN-US">String</span><span style="FONT-FAMILY: 宋体">。对于想返回</span><span lang="EN-US">java</span><span style="FONT-FAMILY: 宋体">类或自定义类的话，还是不要老它大驾转化了。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"></span> </p><p class="2" style="MARGIN: 13pt 0cm 13pt 1cm"><a name="_Toc93765173"><span lang="EN-US"><span><strong><font face="Arial" size="5">3.2.</font></strong><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal"></span></span></span><span lang="EN-US"><font face="Arial" size="5"><strong>Utils</strong></font></span></a><span><span style="FONT-FAMILY: 黑体"><strong><font size="5">类</font></strong></span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span style="FONT-FAMILY: 宋体">所有的</span><span lang="EN-US">XXXUtils</span><span style="FONT-FAMILY: 宋体">类都提供的是静态方法，可以直接调用，其主要实现都在相应的</span><span lang="EN-US">XXXUtilsBean</span><span style="FONT-FAMILY: 宋体">中：</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体">BeanUtils<span>  </span><span>   </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体">——<span lang="EN-US">&gt; BeanUtilsBean</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span>       </span></span><span lang="EN-US" style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体">ConvertUtils<span>  </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体">——<span lang="EN-US">&gt; ConvertUtilsBean</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体"><span>    </span>PropertyUtils </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体">——<span lang="EN-US">&gt; PropertyUtilsBean</span></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"></span> </p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">其意思看类名也应该知道的差不多了，我就不再废话啦！当然你也可以直接调用那些</span><span lang="EN-US">XXXUtilsBean</span><span style="FONT-FAMILY: 宋体">，功能都一样！</span></p><img src ="http://www.blogjava.net/19851985lili/aggbug/93513.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-01-12 19:13 <a href="http://www.blogjava.net/19851985lili/articles/93513.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>