<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>san_yun</title>
    <description>如果你有5个苹果,你会怎么样,你会把它们全吃掉?
如果你把它们全都吃掉，你会失去很多！因为你只知道了苹果的味道.
如果你把这5个苹果分出来，给你的朋友，朋友有了水果也会给你的，
那么你所尝到的就不只是苹果的味道，而多了西瓜，梨，葡萄的味道!</description>
    <link>http://san-yun.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>针对Oracle数据库的优化器详细介绍</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/164421" style="color:red;">http://san-yun.javaeye.com/blog/164421</a>&nbsp;
          发表时间: 2008年02月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://unixboy.javaeye.com/blog/164400" target="_blank">http://unixboy.javaeye.com/blog/164400</a><br />本文的目的： <br /><br />1、说一说Oracle的Optimizer及其相关的一些知识。 <br /><br />2、回答一下为什么有时一个表的某个字段明明有索引,当观察一些SQL的执行计划时,发现确不走索引的问题。 <br /><br />3、如果你对 FIRST_ROWS、 ALL_ROWS这两种模式有疑惑时也可以看一下这篇文章。 <br /><br />开始吧: <br /><br />Oracle在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执行计划去执行。分析语句的执行计划的工作是由优化器(Optimizer)来完成的。不同的情况,一条SQL可能有多种执行计划,但在某一时点,一定只有一种执行计划是最优的,花费时间是最少的。相信你一定会用Pl/sql Developer、Toad等工具去看一个语句的执行计划,不过你可能对Rule、Choose、First rows、All rows这几项有疑问,因为我当初也是这样的,那时我也疑惑为什么选了以上的不同的项,执行计划就变了? <br /><br />1、优化器的优化方式 <br /><br />Oracle的优化器共有两种的优化方式,即基于规则的优化方式(Rule-Based Optimization,简称为RBO)和基于代价的优化方式(Cost-Based Optimization,简称为CBO)。 <br /><br />A、RBO方式：优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则。比如我们常见的,当一个where子句中的一列有索引时去走索引。 <br /><br />B、CBO方式：依词义可知,它是看语句的代价(Cost)了,这里的代价主要指 Cpu和内存。优化器在判断是否用这种方式时,主要参照的是表及索引的统计信息。统计信息给出表的大小、有少行、每行的长度等信息。这些统计信息起初在库内是没有的,是你在做analyze后才出现的,很多的时侯过期统计信息会令优化器做出一个错误的执行计划,因些我们应及时更新这些信息。在Oracle8及以后的版本,Oracle列推荐用CBO的方式。 <br /><br />我们要明了,不一定走索引就是优的,比如一个表只有两行数据,一次IO就可以完成全表的检索,而此时走索引时则需要两次IO,这时对这个表做全表扫描(full table scan)是最好的。 <br /><br />2、优化器的优化模式(Optermizer Mode) <br /><br />优化模式包括Rule,Choose,First rows,All rows这四种方式,也就是我们以上所提及的。如下我解释一下： <br /><br />Rule:不用多说,即走基于规则的方式。 <br /><br />Choolse:这是我们应观注的,默认的情况下Oracle用的便是这种方式。指的是当一个表或或索引有统计信息,则走CBO的方式,如果表或索引没统计信息,表又不是特别的小,而且相应的列有索引时,那么就走索引,走RBO的方式。 <br /><br />First Rows:它与Choose方式是类似的,所不同的是当一个表有统计信息时,它将是以最快的方式返回查询的最先的几行,从总体上减少了响应时间。 <br /><br />All Rows:也就是我们所说的Cost的方式,当一个表有统计信息时,它将以最快的方式返回表的所有的行,从总体上提高查询的吞吐量。没有统计信息则走基于规则的方式。 <br /><br />3、如何设定选用哪种优化模式 <br /><br />a、Instance级别 <br /><br />我们可以通过在init.ora文件中设定OPTIMIZER_MODE =RULE、OPTIMIZER_MODE=CHOOSE、OPTIMIZER_MODE=FIRST_ROWS、OPTIMIZER_MODE= ALL_ROWS去选用3所提的四种方式,如果你没设定OPTIMIZER_MODE参数则默认用的是Choose这种方式。 <br /><br />B、Sessions级别 <br /><br />通过SQL> ALTER SESSION SET OPTIMIZER_MODE=;来设定。 <br /><br />C、语句级别 <br /><br />这些需要用到Hint,比如: <br /><br />　　<br />　　SQL> SELECT /*+ RULE */ a.userid,<br />　　2　　 b.name,<br />　　3　　 b.depart_name<br />　　4　　　FROM tf_f_yhda a,<br />　　5　　　　　　　　tf_f_depart b<br />　　6　　 WHERE a.userid=b.userid; <br />　　<br />4、为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢？如何解决呢？ <br /><br />A、不走索引大体有以下几个原因: <br /><br />♀你在Instance级别所用的是all_rows的方式； <br /><br />♀你的表的统计信息(最可能的原因)； <br /><br />♀你的表很小,上文提到过的,Oracle的优化器认为不值得走索引。 <br /><br />B、解决方法： <br /><br />♀可以修改init.ora中的OPTIMIZER_MODE这个参数,把它改为Rule或Choose,重起数据库。也可以使用4中所提的Hint； <br /><br />♀删除统计信息SQL>analyze table table_name delete statistics； <br /><br />♀表小不走索引是对的,不用调的。 <br /><br />5、其它相关 <br /><br />A、如何看一个表或索引是否是统计信息 <br /><br />　　<br />　　SQL>SELECT * FROM user_tables<br />　　2　 WHERE table_name=&lt;table_name><br />　　3 AND num_rows is not null;<br />　　<br />　　SQL>SELECT * FROM user_indexes<br />　　2　 WHERE table_name=&lt;table_name><br />　　3　　 AND num_rows is not null; <br />　　 <br />b、如果我们先用CBO的方式,我们应及时去更新表和索引的统计信息,以免生形不切合实的执行计划。 <br /><br />　　<br />　　SQL> ANALYZE TABLE table_name COMPUTE STATISTICS;<br />　　SQL> ANALYZE INDEX index_name ESTIMATE STATISTICS; <br />　　
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/164421#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 23 Feb 2008 12:52:02 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/164421</link>
        <guid>http://san-yun.javaeye.com/blog/164421</guid>
      </item>
      <item>
        <title>优化数据库大幅度提高Oracle的性能</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/164419" style="color:red;">http://san-yun.javaeye.com/blog/164419</a>&nbsp;
          发表时间: 2008年02月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://unixboy.javaeye.com/blog/164399" target="_blank">http://unixboy.javaeye.com/blog/164399</a><br />几个简单的步骤大幅提高Oracle性能--我优化数据库的三板斧。 <br /><br />数据库优化的讨论可以说是一个永恒的主题。资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack，贴出数据库配置等等。还有的人认为要抓出执行最慢的语句来进行优化。但实际情况是，提出疑问的人很可能根本不懂执行计划，更不要说statspack了。而我认为，数据库优化，应该首先从大的方面考虑：网络、服务器硬件配置、操作系统配置、Oracle服务器配置、数据结构组织、然后才是具体的调整。实际上网络、硬件等往往无法决定更换，应用程序一般也无法修改，因此应该着重从数据库配置、数据结构上来下手，首先让数据库有一个良好的配置，然后再考虑具体优化某些过慢的语句。我在给我的用户系统进行优化的过程中，总结了一些基本的，简单易行的办法来优化数据库，算是我的三板斧，呵呵。不过请注意，这些不一定普遍使用，甚至有的会有副作用，但是对OLTP系统、基于成本的数据库往往行之有效，不妨试试。（注：附件是Burleson写的用来报告数据库性能等信息的脚本，本文用到） <br /><br />一．设置合适的SGA <br /><br />常常有人抱怨服务器硬件很好，但是Oracle就是很慢。很可能是内存分配不合理造成的。(1)假设内存有512M，这通常是小型应用。建议Oracle的SGA大约240M，其中：共享池（SHARED_POOL_SIZE）可以设置 60M到80M，根据实际的用户数、查询等来定。数据块缓冲区可以大致分配120M-150M，8i下需要设置DB_BLOCK_BUFFERS， DB_BLOCK_BUFFER*DB_BLOCK_SIZE等于数据块缓冲区大小。9i 下的数据缓冲区可以用db_cache_size来直接分配。 <br /><br />(2)假设内存有1G，Oracle 的SGA可以考虑分配500M：共享池分配100M到150M，数据缓冲区分配300M到400M。 <br /><br />(3)内存2G，SGA可以考虑分配1.2G，共享池300M到500M，剩下的给数据块缓冲区。 <br /><br />(4)内存2G以上：共享池300M到500M就足够啦，再多也没有太大帮助； (Biti_rainy有专述)数据缓冲区是尽可能的大，但是一定要注意两个问题：一是要给操作系统和其他应用留够内存，二是对于32位的操作系统， Oracle的SGA有1.75G的限制。有的32位操作系统上可以突破这个限制，方法还请看Biti的大作吧。 <br /><br />二．分析表和索引，更改优化模式 <br /><br />Oracle默认优化模式是CHOOSE，在这种情况下，如果表没有经过分析，经常导致查询使用全表扫描，而不使用索引。这通常导致磁盘I/O太多，而导致查询很慢。如果没有使用执行计划稳定性，则应该把表和索引都分析一下，这样可能直接会使查询速度大幅提升。分析表命令可以用ANALYZE TABLE 分析索引可以用ANALYZE INDEX命令。对于少于100万的表，可以考虑分析整个表，对于很大的表，可以按百分比来分析，但是百分比不能过低，否则生成的统计信息可能不准确。可以通过DBA_TABLES的LAST_ANALYZED列来查看表是否经过分析或分析时间，索引可以通过DBA_INDEXES的 LAST_ANALYZED列。 <br /><br />下面通过例子来说明分析前后的速度对比。（表CASE_GA_AJZLZ大约有35万数据，有主键）首先在SQLPLUS中打开自动查询执行计划功能。(第一次要执行\RDBMS\ADMIN\utlxplan.sql来创建PLAN_TABLE这个表) <br /><br />　　<br />　　SQL> SET AUTOTRACE ON<br />　　SQL>SET TIMING ON <br />　　 <br />通过SET AUTOTRACE ON 来查看语句的执行计划，通过SET TIMING ON 来查看语句运行时间。 <br /><br />　　<br />　　SQL> select count(*) from CASE_GA_AJZLZ;<br />　　COUNT(*)<br />　　----------<br />　　346639<br />　　<br />　　已用时间: 00: 00: 21.38<br />　　<br />　　Execution Plan<br />　　　　0 SELECT STATEMENT Optimizer=CHOOSE<br />　　1 0 SORT (AGGREGATE)<br />　　2 1 TABLE ACCESS (FULL) OF 'CASE_GA_AJZLZ'<br />　　…………………… <br />　　 <br />请注意上面分析中的TABLE ACCESS(FULL)，这说明该语句执行了全表扫描。而且查询使用了21.38秒。这时表还没有经过分析。下面我们来对该表进行分析： <br /><br />　　<br />　　SQL> analyze table CASE_GA_AJZLZ compute statistics; <br />　　 <br />表已分析。已用时间: 00: 05: 357.63。然后再来查询： <br /><br />　　<br />　　SQL> select count(*) from CASE_GA_AJZLZ;<br />　　COUNT(*)<br />　　----------<br />　　346639<br />　　<br />　　已用时间: 00: 00: 00.71<br />　　<br />　　Execution Plan<br />　<br />　　0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=351 Card=1)<br />　　1 0 SORT (AGGREGATE)<br />　　2 1 INDEX (FAST FULL SCAN) OF 'PK_AJZLZ' (UNIQUE) (Cost=351<br />　　Card=346351)<br />　　………………………… <br />　　 <br />请注意，这次时间仅仅用了0.71秒！这要归功于INDEX(FAST FULL SCAN)。通过分析表，查询使用了PK_AJZLZ索引，磁盘I/O大幅减少，速度也大幅提升！下面的实用语句可以用来生成分析某个用户的所有表和索引，假设用户是GAXZUSR： <br /><br />　　<br />　　SQL> set pagesize 0<br />　　SQL> spool d:\analyze_tables.sql;<br />　　SQL> select 'analyze table '||owner||'.'||table_name||' <br />compute statistics;' from dba_tables where owner='GAXZUSR';<br />　　SQL> spool off<br />　　SQL> spool spool d:\analyze_indexes.sql;<br />　　SQL> select 'analyze index '||owner||'.'||index_name||' <br />compute statistics;' from dba_indexes where owner='GAXZUSR';<br />　　SQL> spool off<br />　　SQL> @d:\analyze_tables.sql<br />　　SQL> @d:\analyze_indexes.sql <br />　　 <br />解释：上面的语句生成了两个sql文件，分别分析全部的GAXZUSR的表和索引。如果需要按照百分比来分析表，可以修改一下脚本。通过上面的步骤，我们就完成了对表和索引的分析，可以测试一下速度的改进啦。建议定期运行上面的语句，尤其是数据经过大量更新。 <br /><br />当然，也可以通过dbms_stats来分析表和索引，更方便一些。但是我仍然习惯上面的方法，因为成功与否会直接提示出来。<br /><br /> <br /><br />另外，我们可以将优化模式进行修改。optimizer_mode值可以是RULE、CHOOSE、FIRST_ROWS和ALL_ROWS。对于OLTP系统，可以改成 FIRST_ROWS，来要求查询尽快返回结果。这样即使不用分析，在一般情况下也可以提高查询性能。但是表和索引经过分析后有助于找到最合适的执行计划。 <br /><br />三．设置cursor_sharing=FORCE 或SIMILAR <br /><br />这种方法是8i才开始有的，oracle805不支持。通过设置该参数，可以强制共享只有文字不同的语句解释计划。例如下面两条语句可以共享： <br /><br />　　<br />　　SQL> SELECT * FROM MYTABLE WHERE NAME='tom'<br />　　SQL> SELECT * FROM MYTABLE WHERE NAME='turner' <br />　　 <br />这个方法可以大幅降低缓冲区利用率低的问题，避免语句重新解释。通过这个功能，可以很大程度上解决硬解析带来的性能下降的问题。个人感觉可根据系统的实际情况，决定是否将该参数改成FORCE。该参数默认是exact。不过一定要注意，修改之前，必须先给ORACLE打补丁，否则改之后oracle会占用100%的CPU,无法使用。对于ORACLE9i，可以设置成SIMILAR，这个设置综合了FORCE和EXACT的优点。不过请慎用这个功能，这个参数也可能带来很大的负面影响！ <br /><br />四．将常用的小表、索引钉在数据缓存KEEP池中 <br /><br />内存上数据读取速度远远比硬盘中读取要快，据称，内存中数据读的速度是硬盘的 14000倍！如果资源比较丰富，把常用的小的、而且经常进行全表扫描的表给钉内存中，当然是在好不过了。可以简单的通过ALTER TABLE tablename CACHE来实现，在ORACLE8i之后可以使用ALTER TABLE table STORAGE(BUFFER_POOL KEEP)。一般来说，可以考虑把200数据块之内的表放在keep池中，当然要根据内存大小等因素来定。关于如何查出那些表或索引符合条件，可以使用本文提供的access.sql和access_report.sql。这两个脚本是著名的Oracle专家 Burleson写的，你也可以在读懂了情况下根据实际情况调整一下脚本。对于索引，可以通过ALTER INDEX indexname STORAGE(BUFFER_POOL KEEP)来钉在KEEP池中。 <br /><br />将表定在KEEP池中需要做一些准备工作。对于ORACLE9i 需要设置DB_KEEP_CACHE_SIZE，对于8i，需要设置buffer_pool_keep。在8i中，还要修改 db_block_lru_latches，该参数默认是1，无法使用buffer_pool_keep。该参数应该比2*3*CPU数量少，但是要大于 1，才能设置DB_KEEP_CACHE_BUFFER。buffer_pool_keep从db_block_buffers中分配，因此也要小于 db_block_buffers。设置好这些参数后，就可以把常用对象永久钉在内存里。 <br /><br />五．设置optimizer_max_permutations <br /><br />对于多表连接查询，如果采用基于成本优化(CBO)，ORACLE会计算出很多种运行方案，从中选择出最优方案。这个参数就是设置oracle究竟从多少种方案来选择最优。如果设置太大，那么计算最优方案过程也是时间比较长的。 Oracle805和8i默认是80000，8建议改成2000。对于9i，已经默认是2000了。 <br /><br />六．调整排序参数 <br /><br />(1) SORT_AREA_SIZE:默认的用来排序的SORT_AREA_SIZE大小是32K，通常显得有点小，一般可以考虑设置成1M（1048576）。这个参数不能设置过大，因为每个连接都要分配同样的排序内存。 <br /><br />(2) SORT_MULTIBLOCK_READ_COUNT:增大这个参数可以提高临时表空间排序性能，该参数默认是2，可以改成32来对比一下排序查询时间变化。注意，这个参数的最大值与平台有关系。
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/164419#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 23 Feb 2008 12:49:30 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/164419</link>
        <guid>http://san-yun.javaeye.com/blog/164419</guid>
      </item>
      <item>
        <title>struts2学习</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/164415" style="color:red;">http://san-yun.javaeye.com/blog/164415</a>&nbsp;
          发表时间: 2008年02月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          应用程序越大，它里面action mapping的数量也越多，通过使用通配符，我们可以将一些相似的mapping绑在一起，用一个比较通用的mapping来表示，在前面关于action配置的那章里面也提到了这个通配符的使用，这里再系统的说一下。<br /><br />如下所示，有一个配置好了的action mapping：<br /><br />&lt;action<br /><br />    name="/edit*"<br /><br />    class="org.apache.struts.webapp.example.Edit{1}Action"><br /><br />    &lt;result name="failure"path="/mainMenu.jsp"/><br /><br />    &lt;result path="/{1}.jsp"/><br /><br />&lt;/action><br /><br />这个action mapping可以用匹配所有以/edit开头的对action名称，例如/editSubscription，editRegistration等等，但是/editSubscription/add不会被匹配上。被通配符所匹配的内容将会被替换到action mapping以及result的各个属性中去，去取代{1}。比方说/editSubscription匹配上了，那么其中一个result的path属性就会被框架认为是Subscription.jsp。<br /><br />要注意的是，如果一个请求的url和多个action mapping匹配上了，那么选择最后面的那个执行，也就是说按照从后往前的顺序进行匹配查找，有一个例外就是精确匹配优先，如果有一个action mapping没用通配符和url给匹配上了，那么优先选择精确匹配，折合servlet中的匹配原则是一样的。<br /><br />通配符中几个特殊的标记，如下所述：<br /><br />*：可以匹配0个或多个任意字符，但是不包括正斜杠”/”；<br /><br />**：可以匹配0个或多个任意字符，包括正斜杠’’/”在内<br /><br />\：反斜杠，转义字符。<br /><br />因为*不能匹配正斜杠，所以前面/editSubscription/add不会被匹配上。<br /><br />在action mapping中，被通配符所匹配上的值可以用符号{N}来访问，其中N是一个1到9之间的数，用来表示代替第N个被匹配上的值，说通俗点就是第N个*号所表示的内容，比方说通配符表达式是/edit*/add*/confirm*，它匹配上了/editOrder/addItem/confirmResult，那么{1}就代表Order，{2}就代表Item，{3}就代表Result，依此类推。
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/164415#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 23 Feb 2008 12:27:24 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/164415</link>
        <guid>http://san-yun.javaeye.com/blog/164415</guid>
      </item>
      <item>
        <title>在线HTML编辑器原理</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/154629" style="color:red;">http://san-yun.javaeye.com/blog/154629</a>&nbsp;
          发表时间: 2008年01月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          为什么能实现在线编辑呢?  首先需要ie 的支持，在 ie 5.5以后就有一个编辑状态，就是利用这个编辑状态,然后用javascript 来控制在线编辑的。<br />下面给出一个简短的例子： <br />首先要有一个编辑框，这个编辑框其实就是一个 可编辑状态的 网页，我们这里用iframe 来建立编辑框<br /><br />&lt;IFRAME id=HtmlEdit style="WIDTH: 100%; HEIGHT: 296px" marginWidth=0 marginHeight=0><br />&lt;/IFRAME><br /><br />并且在 加上javascript 代码来指定 HtmlEdit 有编辑功能:<br /><br />function document.onreadystatechange()<br />{<br /> HtmlEdit.document.designMode="On";<br />}<br /><br /> <br /><br />HtmlEdit.document.body.innerHTML  这句可以获得 HtmEdit 里面的html代码. 一般的我们会用这样的javascript 将 iframe 里的内容传递给一个textarea 然后提交给服务器处理.<br /><br />function getIframeData(){<br /> document.form1.test.value=HtmlEdit.document.body.innerHTML;<br />}<br />function sentIframeData(){<br /> HtmlEdit.document.body.innerHTML=document.form1.test.value;<br />}<br /><br />var sel = HtmlEdit.document.selection.createRange(); 而这一句可以获得选取的焦点:<br /><br />下面我就演示一个完成的例子. 一个拥有加粗功能的在线编辑器,有兴趣的朋友可以在此基础上完成其他功能!!<br /><br />&lt;html><br />&lt;head><br />&lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312"><br />&lt;script language="javascript"><br />function getIframeData(){<br /> document.form1.test.value=HtmlEdit.document.body.innerHTML;<br />}<br />function sentIframeData(){<br /> HtmlEdit.document.body.innerHTML=document.form1.test.value;<br />}<br />function doB(){<br /> HtmlEdit.focus();<br /> var sel = HtmlEdit.document.selection.createRange();<br /> insertHTML("&lt;b>"+sel.text+"&lt;/b>");<br />}<br />function insertHTML(html) {<br /> if (HtmlEdit.document.selection.type.toLowerCase() != "none"){<br />  HtmlEdit.document.selection.clear() ;<br /> }<br /> HtmlEdit.document.selection.createRange().pasteHTML(html) ; <br />}<br />function document.onreadystatechange()<br />{<br /> HtmlEdit.document.designMode="On";<br />}<br />&lt;/script><br />&lt;/head><br /><br />&lt;body><br />&lt;form action="test.asp?act=add" method="post" name="form1"><br />  <br />&lt;IFRAME id=HtmlEdit style="WIDTH: 100%; HEIGHT: 296px" marginWidth=0 marginHeight=0><br />&lt;/IFRAME><br />&lt;textarea name="test" rows="10" id="test" style="width:100%;">&lt;/textarea><br />&lt;br><br />&lt;input type="submit" name="Submit" value="提交"><br />&lt;input type="button" value="iframe->textarea" onClick="getIframeData()"><br />&lt;input type="button" value="textarea->iframe" onClick="sentIframeData()"><br />&lt;input type="button" value="B" onClick="doB()"><br />&lt;/form><br />&lt;/body><br />&lt;/html>
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/154629#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 10 Jan 2008 09:57:25 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/154629</link>
        <guid>http://san-yun.javaeye.com/blog/154629</guid>
      </item>
      <item>
        <title>java关键字</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/154221" style="color:red;">http://san-yun.javaeye.com/blog/154221</a>&nbsp;
          发表时间: 2008年01月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          关键字: java keywords,native,strictfp,transient,volatile <br />Java关键字（keywords） <br /><br />abstract default if private this <br />boolean do implements protected throw <br />break double import public throws <br />byte else instanceof return transient <br />case extends int short try <br />catch final interface static void <br />char finally long strictfp volatile <br />class float native super while <br />const for new switch <br />continue goto package synchronized<br /><br /><br />以上是java specifications中定义的keywords，一共48个，其中常见的三个看似是关键字的true, false, null,都不是关键字，而是作为一个单独标识类型。 <br />其中，不常用到的关键字有：const，goto，native，strictfp，transient，volatile。 <br />const和goto为java中的保留字。 <br />1. native <br />native是方法修饰符。Native方法是由另外一种语言（如c/c++，FORTRAN，汇编）实现的本地方法。因为在外部实现了方法，所以在java代码中，就不需要声明了，有点类似于借口方法。Native可以和其他一些修饰符连用，但是abstract方法和Interface方法不能用native来修饰。 <br />Example： <br /><br />public interface TestInterface {<br />     void doMethod();<br />}<br />public class Test implements TestInterface {<br />    public native void doMethod();<br />    private native int doMethodB();<br />　　public native synchronized String doMethodC();<br />　　static native void doMethodD();<br />}<br />为什么需要使用native method？请参考： <br />http://www.javaeye.com/topic/72543 java Native Method初涉 <br />2. strictfp <br />修饰类和方法，意思是FP-strict，精确浮点，符合IEEE-754规范的。当一个class或interface用strictfp声明，内部所有的float和double表达式都会成为strictfp的。Interface method不能被声明为strictfp的，class的可以。 <br />Example： <br /><br />strictfp interface FPTest {<br />     void methodA();<br />}<br />class FPClass implements FPTest {<br />    public void methodA() {<br />    }<br />    public void methodB() {<br />　　}<br />　　public strictfp void methodC() {<br />　　}<br />}<br />class FPClassB {<br />    strictfp void methodA() {<br />    }<br />}<br />3.transient <br />变量修饰符。标记为transient的变量，在对象存储时，这些变量状态不会被持久化。当对象序列化的保存在存储器上时，不希望有些字段数据被保存，为了保证安全性，可以把这些字段声明为transient。 <br />4. volatile <br />volatile修饰变量。在每次被线程访问时，都强迫从共享内存中重读该成员变量的值。而且，当成员变量发生变化时，强迫线程将变化值回写到共享内存。这样在任何时刻，两个不同的线程总是看到某个成员变量的同一个值。 <br />看看Java Language Specification中的例子。 <br />条件：一个线程不停的调用方法one()，一个线程不停的调用方法two()。我测试过多次，这种情况好像一直没有出现。 <br /><br />class Test {<br />	static int i = 0, j = 0;<br />	static void one() { i++; j++; }<br />	static void two() {<br />		System.out.println("i=" + i + " j=" + j);<br />	}<br />}<br />结果偶尔会出现j大于i的情况，因为方法没有同步，所以会出现i和j可能不是一次更新。一种防止这种情况发生的办法就是声明两个方法为synchronized 的。 <br /><br />class Test {<br />	static int i = 0, j = 0;<br />	static synchronized void one() { i++; j++; }<br />	static synchronized void two() {<br />		System.out.println("i=" + i + " j=" + j);<br />	}<br />}<br />这样可以防止两个方法同时被执行，还可以保证j和i被同时更新，这样一来i和j的值一直是一样的。 <br />另外一种途径就是把i和j声明为volatile。 <br /><br />class Test {<br />	static volatile int i = 0, j = 0;<br />	static void one() { i++; j++; }<br />	static void two() {<br />		System.out.println("i=" + i + " j=" + j);<br />	}<br />}
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/154221#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Jan 2008 09:39:03 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/154221</link>
        <guid>http://san-yun.javaeye.com/blog/154221</guid>
      </item>
      <item>
        <title>使用JSON实现代码分离</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/139477" style="color:red;">http://san-yun.javaeye.com/blog/139477</a>&nbsp;
          发表时间: 2007年11月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在学习JSON之前，当我在写大量JSP页面的时候，产生动态数据一般采用两种途径:<br />1.直接在页面中写java代码<br />2 采用各种标签代替<br />   这两种用法的支持者都很多,但是我发现就算是采用标签也好,对于页面的重用还是无能为力,比如有几个页面都需要用到一个item数据，一个是管理用户页面，一个是订单页面。我们既要在管理用户的servlet写上setAttribute('item',item),也要在管理订单的servlet写上setAttribute('item',item);然后在页面上通过getAttribute()获得数据:<br /><pre name="code" class="java">
  &lt;%for(int i=0;i&lt;item.length;++i){%>
      html tag ...
  &lt;%}%>
</pre><br />或者采用标签的形式:<br /><pre name="code" class="java">
  &lt;ww:iterator value="item">
      html tag...
  &lt;ww:iterator>
</pre><br />   很多时候我们会采用 &lt;jsp:inclue page="common.jsp"/>来重用这样的页面,但这里有个问题，如果多个的页面样式不一样呢?如果数据不是很多呢，这样会产生很多页面碎片,实践已经证明,重用页面并不是一个好办法.<br /><br />   有时候我想，如果我能单独用一个action来提供输出数据，每个需要这些数据的页面页面都去获取这些数据,关于这些数据在页面如何渲染是页面的问题，这个action只提供数据,这样我们重用数据不是比重用页面好很多么?<br /><br />   但是之前的技术并不能支撑这样的实现，一个页面如何自己主动去访问它需要的数据呢?<br /><br />   答案是当然是通过AJAX技术.但今天我介绍的是另外一种技术JSON.<br /><br />   先简单的介绍一下JSON(虽然很多人已经知道),JSON JavaScirp Object Notion 可以看成一段javascript对象树，比如 user.id 表示的是user对象的id，如果对webwork或则是srtus2.0熟悉的朋友应该对此并不陌生，对象树可以嵌套对象,比如user.cat.age 表示user对象的成员cat的年龄。除了对象还可以嵌套数组方法user.cat[0].sayHello(); <br />  我们这样声明一个JSON:<br /><pre name="code" class="java">
var user = { id:’1’, name:’sanyun’};	
alert(user.id)	//输出1
user = { id:’1’, cat:{age:2,color:’white’ }};
alert(user.cat.age)	//输出2
</pre><br /><br />  但是JSON本身是不能和后端通信的,不过我们可以通过<br /><pre name="code" class="java">
&lt;script type="text/javascript" src="后端资源"> &lt;/script>
</pre><br />来和服务器后端通信.<br />我们可以把它封装成一个方法:<br /><pre name="code" class="java">
function CallBack(model) {
    this.model = model;
}
CallBack.init = function (url) {
    var headElement = document.getElementsByTagName("head").item(0);
    var scriptTag = document.createElement("script");
    scriptTag.setAttribute("type", "text/javascript");
    scriptTag.setAttribute("src", url);
    headElement.appendChild(scriptTag);
};
</pre><br />   不过需要注意的是采用这种方式后台MIME必须要设置为 html/Javascritp，当然你也可以轻松把这种方式替换成Ajax.<br />解析<br />  通信之后我们需要做的是解析数据,一般来说,我们可以通过for in 简单的遍列JSON<br /><pre name="code" class="java">
   //model表示后端产生的JSON
CallBack.update(model){
  for(i in model){
     var node =document.getElementByID(i);
     if(node){
       node.value = model[i];
     }
  }
}
</pre><br />后台<br /><pre name="code" class="java">
public class ShowType extends HttpServlet {
    
   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
   response.addHeader("Cache-Control", "no-cache");  //(1)
   response.setContentType("HTML/JavaScript;charset=GBK");//(2)
   PrintWriter out = response.getWriter();
   String json = ” {name:'jiangyunpeng', status:'1',sex:'female'}  ”//(3)
   out.print("CallBack.update("+json+")"); //(4)
  }  	
}
</pre><br /> (1)首先需要设置缓存为空<br /> (2)然后MIME必须要设置为 html/Javascritp<br /> (3)产生一段JSON，这里我们是手动产生的，可以采用JSON开源框架<br /> (4)调用我们前面页面定义的JS函数<br />通过这样处理了之后我们的页面再也没有任何JAVA代码或者自定义标签了,他完全是一个HTML页面(当然这里为了演示，把解析JSON过程过于简单化了),他具有这些好处:<br />1.它是一个HTML，响应速度比JSP快<br />2.对于一些表单元素,比如checkbox,select，如果采用java代码会很繁琐,<br /><pre name="code" class="java">
   function initCheckbox(){
     if('&lt;%=status%>'==1){  //这里有JAVA代码
        document.getElementById('checkbox').checked = true;
     }else{
        document.getElementById('checkbox').checked = fasle;
      }
  }
</pre><br />但是如果采用JSON的话<br /><pre name="code" class="java">
  function initCheckbox(){
     if(status==1){      //这里只有JSON
        document.getElementById('checkbox').checked = true;
     }else{
        document.getElementById('checkbox').checked = fasle;
      }
  }
</pre><br />  我们可以把这段代码放在解析方法里面，判断查询的对象如果是checkbox,就像上面这样处理，这样我们就可以更本不用关心它是否是checkbox<br />3.重用了数据.多个页面可以通过JSON访问相同的数据，这里没有setAttribute(),也不用考虑生命周期。<br />4.降低了服务器端的负载。因为我们把解析的数据任务放在客户端里面进行，服务器只需要产生一些JSON字符串。<br />5.分离了JAVA代码和JS,诸如验证，判断，很多时候在javascript里面嵌套java，可读性很差。<br /><br />小结：我觉得采用JSON是个不错的选择，大家可以试试。<img src="/images/smiles/icon_surprised.gif"/>原来大伙早知道啦！<br />参考：http://www.javaworld.com/javaworld/jw-11-2006/jw-1115-json.html
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/139477#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 09 Nov 2007 14:05:41 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/139477</link>
        <guid>http://san-yun.javaeye.com/blog/139477</guid>
      </item>
      <item>
        <title>备忘录</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/109678" style="color:red;">http://san-yun.javaeye.com/blog/109678</a>&nbsp;
          发表时间: 2007年08月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.当通过classloader获得资源路径的时候,注意完整的路径名称是packageName.className<br /><br />2.文件上传时,表单的编码一定要设置成为 enctype="multipart/form-data",默认是enctype="application/x-www-form-urlencoded".<br /><br />3.通过javascript提交表单,一定要设置method = post<br /><br />4.select decode(id,null,1,2) from  t_form_template where version = 1
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/109678#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 07 Aug 2007 10:48:51 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/109678</link>
        <guid>http://san-yun.javaeye.com/blog/109678</guid>
      </item>
      <item>
        <title>Oracle高级查询</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/94713" style="color:red;">http://san-yun.javaeye.com/blog/94713</a>&nbsp;
          发表时间: 2007年06月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          使用Oracle特有的查询语法, 可以达到事半功倍的效果<br /><br />转http://www.blogjava.net/waterye/archive/2005/0<br /><br />1. 树查询 <br /><pre name="code" class="java">
create table tree (
    id number(10) not null primary key,
    name varchar2(100) not null,
    super number(10) not null                // 0 is root
);
-- 从子到父
select * from tree start with id = ? connect by id = prior super 
-- 从父到子
select * from tree start with id = ? connect by prior id = suepr
-- 整棵树
select * from tree start with super = 0 connect by prior id = suepr
</pre><br /><br />2. 分页查询 <br /><pre name="code" class="java">
select * from ( 
    select my_table.*, rownum  my_rownum from ( 
        select name, birthday from employee order by birthday
    ) my_table where rownum &lt; 120 
) where my_rownum >= 100;
</pre><br />3. 累加查询, 以scott.emp为例<br /><pre name="code" class="java">
select empno, ename, sal, sum(sal) over(order by empno) result from emp;
 
     EMPNO ENAME             SAL     RESULT
---------- ---------- ---------- ----------
      7369 SMITH             800        800
      7499 ALLEN            1600       2400
      7521 WARD             1250       3650
      7566 JONES            2975       6625
      7654 MARTIN           1250       7875
      7698 BLAKE            2850      10725
      7782 CLARK            2450      13175
      7788 SCOTT            3000      16175
      7839 KING             5000      21175
      7844 TURNER           1500      22675
      7876 ADAMS            1100      23775
      7900 JAMES             950      24725
      7902 FORD             3000      27725
      7934 MILLER           1300      29025
</pre><br />4. 高级group by<br /><br /><pre name="code" class="java">
select decode(grouping(deptno),1,'all deptno',deptno) deptno,
       decode(grouping(job),1,'all job',job) job,
       sum(sal) sal
from emp 
group by ROLLUP(deptno,job);
DEPTNO                                   JOB              SAL
---------------------------------------- --------- ----------
10                                       CLERK           1300
10                                       MANAGER         2450
10                                       PRESIDENT       5000
10                                       all job         8750
20                                       CLERK           1900
20                                       ANALYST         6000
20                                       MANAGER         2975
20                                       all job        10875
30                                       CLERK            950
30                                       MANAGER         2850
30                                       SALESMAN        5600
30                                       all job         9400
all deptno                               all job        29025

</pre><br />5. use hint<br />当多表连接很慢时,用ORDERED提示试试,也许会快很多<br /><pre name="code" class="java">
SELECT /**//*+ ORDERED */* 
  FROM a, b, c, d 
 WHERE  
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/94713#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Jun 2007 15:31:06 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/94713</link>
        <guid>http://san-yun.javaeye.com/blog/94713</guid>
      </item>
      <item>
        <title>一个cascade笔记</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/78555" style="color:red;">http://san-yun.javaeye.com/blog/78555</a>&nbsp;
          发表时间: 2007年05月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="code_title">
<div class="code_title"></div>
</div>
<p>在one-to-many设置中通常都是把many放设置位save-update，但这样会出现问题.</p>
<p>比如班级(Classlist)和班级公告(Notify)是一对多的关系</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>Session&nbsp;session&nbsp;=&nbsp;factory.openSession(); &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Transaction&nbsp;tx=&nbsp;session.beginTransaction(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Classlist&nbsp;c&nbsp;=&nbsp;(Classlist)&nbsp;session.load(Classlist.</span><span class="keyword">class</span><span>,&nbsp;25389l); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Notify&nbsp;nofity&nbsp;=&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;Notify(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;nofity.setClasslist(c); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;c.getNotify().add(nofity); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;nofity.setClasslist(c); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;session.save(nofity); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;tx.commit(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;session.close();&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>执行的SQL语句:</p>
<div class="code_title">sql 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-sql">
    <li class="alt"><span><span>Hibernate:&nbsp;</span><span class="keyword">select</span><span>&nbsp;classlist0_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id0_,&nbsp;classlist0_.className&nbsp;</span><span class="keyword">as</span><span>&nbsp;className0_&nbsp;</span><span class="keyword">from</span><span>&nbsp;classlist&nbsp;classlist0_&nbsp;</span><span class="keyword">where</span><span>&nbsp;classlist0_.id=? &nbsp;&nbsp;</span></span></li>
    <li class=""><span>Hibernate:&nbsp;</span><span class="keyword">select</span><span>&nbsp;notify0_.classlist_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;classlis7___,&nbsp;notify0_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id__,&nbsp;notify0_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id3_,&nbsp;notify0_.notify_type&nbsp;</span><span class="keyword">as</span><span>&nbsp;notify_t2_3_,&nbsp;notify0_.title&nbsp;</span><span class="keyword">as</span><span>&nbsp;title3_,&nbsp;notify0_.content&nbsp;</span><span class="keyword">as</span><span>&nbsp;content3_,&nbsp;notify0_.accessory&nbsp;</span><span class="keyword">as</span><span>&nbsp;accessory3_,&nbsp;notify0_.postDate&nbsp;</span><span class="keyword">as</span><span>&nbsp;postDate3_,&nbsp;notify0_.classlist_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;classlis7_3_,&nbsp;notify0_.role_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;role_id3_,&nbsp;role1_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id0_,&nbsp;role1_.</span><span class="keyword">name</span><span>&nbsp;</span><span class="keyword">as</span><span>&nbsp;name0_,&nbsp;role1_.uri&nbsp;</span><span class="keyword">as</span><span>&nbsp;uri0_,&nbsp;role1_.classlist_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;classlis4_0_,&nbsp;role1_.user_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;user_id0_,&nbsp;classlist2_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id1_,&nbsp;classlist2_.className&nbsp;</span><span class="keyword">as</span><span>&nbsp;className1_,&nbsp;user3_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id2_,&nbsp;user3_.USER_TYPE&nbsp;</span><span class="keyword">as</span><span>&nbsp;USER_TYPE2_,&nbsp;user3_.loginID&nbsp;</span><span class="keyword">as</span><span>&nbsp;loginID2_,&nbsp;user3_.</span><span class="keyword">password</span><span>&nbsp;</span><span class="keyword">as</span><span>&nbsp;password2_,&nbsp;user3_.sex&nbsp;</span><span class="keyword">as</span><span>&nbsp;sex2_,&nbsp;user3_.birthday&nbsp;</span><span class="keyword">as</span><span>&nbsp;birthday2_,&nbsp;user3_.realName&nbsp;</span><span class="keyword">as</span><span>&nbsp;realName2_,&nbsp;user3_.nickName&nbsp;</span><span class="keyword">as</span><span>&nbsp;nickName2_,&nbsp;user3_.tel&nbsp;</span><span class="keyword">as</span><span>&nbsp;tel2_,&nbsp;user3_.address&nbsp;</span><span class="keyword">as</span><span>&nbsp;address2_,&nbsp;user3_.describ&nbsp;</span><span class="keyword">as</span><span>&nbsp;describ2_,&nbsp;user3_.studentNumber&nbsp;</span><span class="keyword">as</span><span>&nbsp;student12_2_&nbsp;</span><span class="keyword">from</span><span>&nbsp;notify&nbsp;notify0_&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">outer</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;role&nbsp;role1_&nbsp;</span><span class="keyword">on</span><span>&nbsp;notify0_.role_id=role1_.id&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">outer</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;classlist&nbsp;classlist2_&nbsp;</span><span class="keyword">on</span><span>&nbsp;role1_.classlist_id=classlist2_.id&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">outer</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;users&nbsp;user3_&nbsp;</span><span class="keyword">on</span><span>&nbsp;role1_.user_id=user3_.id&nbsp;</span><span class="keyword">where</span><span>&nbsp;notify0_.classlist_id=? &nbsp;&nbsp;</span></li>
    <li class="alt"><span>Hibernate:&nbsp;</span><span class="keyword">insert</span><span>&nbsp;</span><span class="keyword">into</span><span>&nbsp;notify&nbsp;(title,&nbsp;content,&nbsp;accessory,&nbsp;postDate,&nbsp;classlist_id,&nbsp;role_id,&nbsp;notify_type)&nbsp;</span><span class="keyword">values</span><span>&nbsp;(?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;'com.talent.domain.Notify') &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;</p>
<p>但如果是跨Session，情况就大不一样了.</p>
<p>&nbsp;</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>Session&nbsp;session&nbsp;=&nbsp;factory.openSession(); &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Transaction&nbsp;tx=&nbsp;session.beginTransaction(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Classlist&nbsp;c&nbsp;=&nbsp;(Classlist)&nbsp;session.load(Classlist.</span><span class="keyword">class</span><span>,&nbsp;25389l); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.getNotify().iterator(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tx.commit(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session&nbsp;=&nbsp;factory.openSession(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tx=&nbsp;session.beginTransaction(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Notify&nbsp;nofity&nbsp;=&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;Notify(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nofity.setClasslist(c); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.getNotify().add(nofity); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nofity.setClasslist(c); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.save(nofity); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tx.commit(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close();&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;</p>
<div class="code_title">sql 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-sql">
    <li class="alt"><span><span>Hibernate:&nbsp;</span><span class="keyword">select</span><span>&nbsp;classlist0_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id0_,&nbsp;classlist0_.className&nbsp;</span><span class="keyword">as</span><span>&nbsp;className0_&nbsp;</span><span class="keyword">from</span><span>&nbsp;classlist&nbsp;classlist0_&nbsp;</span><span class="keyword">where</span><span>&nbsp;classlist0_.id=? &nbsp;&nbsp;</span></span></li>
    <li class=""><span>Hibernate:&nbsp;</span><span class="keyword">select</span><span>&nbsp;notify0_.classlist_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;classlis7___,&nbsp;notify0_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id__,&nbsp;notify0_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id3_,&nbsp;notify0_.notify_type&nbsp;</span><span class="keyword">as</span><span>&nbsp;notify_t2_3_,&nbsp;notify0_.title&nbsp;</span><span class="keyword">as</span><span>&nbsp;title3_,&nbsp;notify0_.content&nbsp;</span><span class="keyword">as</span><span>&nbsp;content3_,&nbsp;notify0_.accessory&nbsp;</span><span class="keyword">as</span><span>&nbsp;accessory3_,&nbsp;notify0_.postDate&nbsp;</span><span class="keyword">as</span><span>&nbsp;postDate3_,&nbsp;notify0_.classlist_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;classlis7_3_,&nbsp;notify0_.role_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;role_id3_,&nbsp;role1_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id0_,&nbsp;role1_.</span><span class="keyword">name</span><span>&nbsp;</span><span class="keyword">as</span><span>&nbsp;name0_,&nbsp;role1_.uri&nbsp;</span><span class="keyword">as</span><span>&nbsp;uri0_,&nbsp;role1_.classlist_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;classlis4_0_,&nbsp;role1_.user_id&nbsp;</span><span class="keyword">as</span><span>&nbsp;user_id0_,&nbsp;classlist2_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id1_,&nbsp;classlist2_.className&nbsp;</span><span class="keyword">as</span><span>&nbsp;className1_,&nbsp;user3_.id&nbsp;</span><span class="keyword">as</span><span>&nbsp;id2_,&nbsp;user3_.USER_TYPE&nbsp;</span><span class="keyword">as</span><span>&nbsp;USER_TYPE2_,&nbsp;user3_.loginID&nbsp;</span><span class="keyword">as</span><span>&nbsp;loginID2_,&nbsp;user3_.</span><span class="keyword">password</span><span>&nbsp;</span><span class="keyword">as</span><span>&nbsp;password2_,&nbsp;user3_.sex&nbsp;</span><span class="keyword">as</span><span>&nbsp;sex2_,&nbsp;user3_.birthday&nbsp;</span><span class="keyword">as</span><span>&nbsp;birthday2_,&nbsp;user3_.realName&nbsp;</span><span class="keyword">as</span><span>&nbsp;realName2_,&nbsp;user3_.nickName&nbsp;</span><span class="keyword">as</span><span>&nbsp;nickName2_,&nbsp;user3_.tel&nbsp;</span><span class="keyword">as</span><span>&nbsp;tel2_,&nbsp;user3_.address&nbsp;</span><span class="keyword">as</span><span>&nbsp;address2_,&nbsp;user3_.describ&nbsp;</span><span class="keyword">as</span><span>&nbsp;describ2_,&nbsp;user3_.studentNumber&nbsp;</span><span class="keyword">as</span><span>&nbsp;student12_2_&nbsp;</span><span class="keyword">from</span><span>&nbsp;notify&nbsp;notify0_&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">outer</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;role&nbsp;role1_&nbsp;</span><span class="keyword">on</span><span>&nbsp;notify0_.role_id=role1_.id&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">outer</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;classlist&nbsp;classlist2_&nbsp;</span><span class="keyword">on</span><span>&nbsp;role1_.classlist_id=classlist2_.id&nbsp;</span><span class="func">left</span><span>&nbsp;</span><span class="op">outer</span><span>&nbsp;</span><span class="op">join</span><span>&nbsp;users&nbsp;user3_&nbsp;</span><span class="keyword">on</span><span>&nbsp;role1_.user_id=user3_.id&nbsp;</span><span class="keyword">where</span><span>&nbsp;notify0_.classlist_id=? &nbsp;&nbsp;</span></li>
    <li class="alt"><span>Hibernate:&nbsp;</span><span class="keyword">insert</span><span>&nbsp;</span><span class="keyword">into</span><span>&nbsp;notify&nbsp;(title,&nbsp;content,&nbsp;accessory,&nbsp;postDate,&nbsp;classlist_id,&nbsp;role_id,&nbsp;notify_type)&nbsp;</span><span class="keyword">values</span><span>&nbsp;(?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;'com.talent.domain.Notify') &nbsp;&nbsp;</span></li>
    <li class=""><span>Hibernate:&nbsp;</span><span class="keyword">update</span><span>&nbsp;classlist&nbsp;</span><span class="keyword">set</span><span>&nbsp;className=?&nbsp;</span><span class="keyword">where</span><span>&nbsp;id=? &nbsp;&nbsp;</span></li>
    <li class="alt"><span>Hibernate:&nbsp;</span><span class="keyword">update</span><span>&nbsp;notify&nbsp;</span><span class="keyword">set</span><span>&nbsp;title=?,&nbsp;content=?,&nbsp;accessory=?,&nbsp;postDate=?,&nbsp;classlist_id=?,&nbsp;role_id=?&nbsp;</span><span class="keyword">where</span><span>&nbsp;id=? &nbsp;&nbsp;</span></li>
    <li class=""><span>Hibernate:&nbsp;</span><span class="keyword">update</span><span>&nbsp;notify&nbsp;</span><span class="keyword">set</span><span>&nbsp;title=?,&nbsp;content=?,&nbsp;accessory=?,&nbsp;postDate=?,&nbsp;classlist_id=?,&nbsp;role_id=?&nbsp;</span><span class="keyword">where</span><span>&nbsp;id=? &nbsp;&nbsp;</span></li>
    <li class="alt"><span>Hibernate:&nbsp;</span><span class="keyword">update</span><span>&nbsp;notify&nbsp;</span><span class="keyword">set</span><span>&nbsp;title=?,&nbsp;content=?,&nbsp;accessory=?,&nbsp;postDate=?,&nbsp;classlist_id=?,&nbsp;role_id=?&nbsp;</span><span class="keyword">where</span><span>&nbsp;id=? &nbsp;&nbsp;</span></li>
    <li class=""><span>Hibernate:&nbsp;</span><span class="keyword">update</span><span>&nbsp;notify&nbsp;</span><span class="keyword">set</span><span>&nbsp;title=?,&nbsp;content=?,&nbsp;accessory=?,&nbsp;postDate=?,&nbsp;classlist_id=?,&nbsp;role_id=?&nbsp;</span><span class="keyword">where</span><span>&nbsp;id=? &nbsp;&nbsp;</span></li>
    <li class="alt"><span>Hibernate:&nbsp;</span><span class="keyword">update</span><span>&nbsp;notify&nbsp;</span><span class="keyword">set</span><span>&nbsp;title=?,&nbsp;content=?,&nbsp;accessory=?,&nbsp;postDate=?,&nbsp;classlist_id=?,&nbsp;role_id=?&nbsp;</span><span class="keyword">where</span><span>&nbsp;id=?&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>为什么第二种情况会多了这么多UPDATE呢？</p>
<p><font face="Arial">1.因为在classlist被第一个session关闭，classlist变成了游离对象，没有被session关联。<br />
2.在nofity.setClasslist(c)时候，classlist被关联到Session中成为po.<br />
3.因为配置文件中many方设置的cascade选项是save-update,classlist会被结连更新<br />
4.当classlist被更新的时候，由于one方设置的也是save-update,所以和classlist相互关联的notify也会被更新</font></p>
<p>如果我们把many方设置为none就可以了。</p>
<p>但这样又会产生问题，如果我们保存notify，Hibernate会报一个异常，提示引用了一个未保存的临时对象。</p>
<p>解决的方法可以是每次都保存one的那边.</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>Session&nbsp;session&nbsp;=&nbsp;factory.openSession(); &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Transaction&nbsp;tx=&nbsp;session.beginTransaction(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Classlist&nbsp;c&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Classlist(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Notify&nbsp;notify&nbsp;=&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;Notify(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;c.getNotify().add(notify); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;notify.setClasslist(c); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;session.save(c); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;tx.commit(); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;session.close();&nbsp;&nbsp;</span></li>
</ol>
</div>
<div class="code_title">sql 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-sql">
    <li class="alt"><span><span class="keyword">insert</span><span>&nbsp;</span><span class="keyword">into</span><span>&nbsp;classlist&nbsp;(className)&nbsp;</span><span class="keyword">values</span><span>&nbsp;(?) &nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class="keyword">insert</span><span>&nbsp;</span><span class="keyword">into</span><span>&nbsp;notify&nbsp;(title,&nbsp;content,&nbsp;accessory,&nbsp;postDate,&nbsp;classlist_id,&nbsp;role_id,&nbsp;notify_type)&nbsp;</span><span class="keyword">values</span><span>&nbsp;(?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;?,&nbsp;'com.talent.domain.Notify')&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/78555#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 10 May 2007 15:38:23 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/78555</link>
        <guid>http://san-yun.javaeye.com/blog/78555</guid>
      </item>
      <item>
        <title>clone克隆</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/71510" style="color:red;">http://san-yun.javaeye.com/blog/71510</a>&nbsp;
          发表时间: 2007年04月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Main&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Cloneable{ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;msg; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;Main(String&nbsp;msg){ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.msg&nbsp;=&nbsp;msg;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">&quot;init&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;Object&nbsp;clone()</span><span class="keyword">throws</span><span>&nbsp;CloneNotSupportedException{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">super</span><span>.clone(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">boolean</span><span>&nbsp;equals(Object&nbsp;obj){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(obj==</span><span class="keyword">this</span><span>)</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(!(obj&nbsp;</span><span class="keyword">instanceof</span><span>&nbsp;Main))</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">final</span><span>&nbsp;Main&nbsp;temp&nbsp;&nbsp;=&nbsp;(Main)obj; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(</span><span class="keyword">this</span><span>.msg.equals(temp.msg)) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">true</span><span>; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">else</span><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)</span><span class="keyword">throws</span><span>&nbsp;Exception{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main&nbsp;main&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Main(</span><span class="string">&quot;sanyun&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main&nbsp;clone&nbsp;=&nbsp;(Main)main.clone(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(main==clone); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(main.equals(clone)); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(clone.msg); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>需要注意的几点:</p>
<p>1.必须实现Cloneable借口,否则会抛出CloneNotSupportException</p>
<p>2.Object的clone方法原形是protected,覆写时需要扩大访问权限public</p>
<p>3.clone方法并不会调用构造函数。</p>
<p>4Object colen方法的实现中会创建一个复制的对象，这个对象于原来的对象具有相同的值，但具有不同的内存地址</p>
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/71510#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 16 Apr 2007 14:30:46 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/71510</link>
        <guid>http://san-yun.javaeye.com/blog/71510</guid>
      </item>
      <item>
        <title>对象的生命周期</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/71500" style="color:red;">http://san-yun.javaeye.com/blog/71500</a>&nbsp;
          发表时间: 2007年04月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>先来看一段代码:</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.talent.business; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ScheduleManager&nbsp;&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ScheduleManager()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">&quot;DefaultScheduleManager&nbsp;init&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.talent.business; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ScheduleManagerFactory&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;&nbsp;ScheduleManager&nbsp;dsm&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ScheduleManager(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;ScheduleManagerFactory&nbsp;factory&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ScheduleManagerFactory(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;ScheduleManagerFactory()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">&quot;ScheduleManagerFactory&nbsp;init&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;ScheduleManager&nbsp;newInstance()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;factory.dsm; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScheduleManagerFactory.newInstance(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScheduleManagerFactory.newInstance(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>如果你能准确的说出运行结果,那么你就没有必要看这篇文章了,如果不能,我们来一起好好研究对象的生命周期.</p>
<p>运行的结果:</p>
<p><font face="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DefaultScheduleManager init</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="Arial">ScheduleManagerFactory init</font></p>
<p>我们来看这两句结果是如何产生的,当我们在main方法里面调用<font face="Arial">ScheduleManagerFactory .newInstatnce()的时候,JVM 会先装载<font face="Arial">ScheduleManagerFactory .clas,这个时候实际上叫做<strong>类加载</strong>过程。</font></font></p>
<p><font face="Arial"><font face="Arial">实际在当我们每次用new语句产生一个类的实例的时候，JVM都会先对这个对象所属的类型进行加载，JLS（JAVA语言规范）用Class这个类型表示一个对象所属的类型，比如</font></font></p>
<font face="Arial"><font face="Arial">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>System.out.println(String.</span><span class="keyword">class</span><span>.getName());&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<p>&nbsp;这条语句的输出结果将是：java.lang.String;</p>
<p>JVM会进行类加载的时候首先会解析这个类（Class）的字节码时候是安全的，然后会对Class的static成员变量进行初始化。</p>
<p>导致JVM进行类加载有一下这几种情况</p>
<p>1.访问类的静态成员变量或静态成员方法.</p>
<p>2.调用new语句产生类的实例.</p>
<p>3.访问类的子类的静态成员或者实例化子类也会对父类进行加载</p>
<p>&nbsp;</p>
</font></font>
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/71500#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 16 Apr 2007 13:15:43 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/71500</link>
        <guid>http://san-yun.javaeye.com/blog/71500</guid>
      </item>
      <item>
        <title>webwork2入门(二.2)</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/64623" style="color:red;">http://san-yun.javaeye.com/blog/64623</a>&nbsp;
          发表时间: 2007年03月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>在web应用经常需要要对用户提交的表单进行验证</p>
<p>webwork有3种验证方式：</p>
<p>客户端验证</p>
<p>服务器端验证</p>
<p>Ajax验证:</p>
<p>下面来探讨最简单的服务器端验证</p>
<p>webwork通过实现<font face="Arial"><strong>com.opensymphony.xwork.Validateable 和 </strong><font face="Arial"><strong>com.opensymphony.xwork.ValidationAware</strong>接口提供验证功能，通常我们不会自己去实现这两个接口，而是通过继承<strong>com.opensymphony.xwork.ActionSupport</strong>这个类。</font></font></p>
<p>来看我们Action的变化</p>
<div class="code_title">java 代码</div>
<font face="Arial"><font face="Arial">
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;mypackage; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;java.util.Map; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork.ActionContext; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork.ActionSupport; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork.Validateable; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;SimpleAction&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ActionSupport&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Validateable&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;User&nbsp;user&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;User(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;execute()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionContext&nbsp;context&nbsp;=&nbsp;ActionContext.getContext(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map&nbsp;session&nbsp;=&nbsp;context.getSession(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.put(</span><span class="string">&quot;user&quot;</span><span>,&nbsp;user); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.getMessage().add(</span><span class="string">&quot;msg1&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.getMessage().add(</span><span class="string">&quot;msg2&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.getMessage().add(</span><span class="string">&quot;msg3&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;SUCCESS; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;User&nbsp;getUser()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;user; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setUser(User&nbsp;user)&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.user&nbsp;=&nbsp;user; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;validate()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(</span><span class="string">&quot;java&quot;</span><span>.equals(user.getUsername())){ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.addFieldError(</span><span class="string">&quot;username&quot;</span><span>,&nbsp;</span><span class="string">&quot;username&nbsp;can't&nbsp;become&nbsp;java&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>如果我们的用户名为 java 的话就向客户端发送一段失败警告：</p>
<p>其中的<font face="Arial">addFieldError方法是从<font face="Arial">ActionSupport继承来的，第一个参数表示的是域(field)名，第二个参数表示的是出错信息.</font></font></p>
<p>一件奇怪的事是execute方法并没有显示调用validate方法，validate方法怎么运行，它总不可能自动运行吧</p>
<p>答案是通过拦截器</p>
<p>我们的xwork.xml将作如下变化：</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span>&lt;!DOCTYPE&nbsp;xwork&nbsp;PUBLIC&nbsp;&quot;-//OpenSymphony&nbsp;Group//XWork&nbsp;1.1.1//EN&quot;&nbsp;&quot;http://www.opensymphony.com/xwork/xwork-1.1.1.dtd&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">xwork</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">include</span><span>&nbsp;</span><span class="attribute">file</span><span>=</span><span class="attribute-value">&quot;webwork-default.xml&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">package</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;default&quot;</span><span>&nbsp;</span><span class="attribute">extends</span><span>=</span><span class="attribute-value">&quot;webwork-default&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">action</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;simple&quot;</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">&quot;mypackage.SimpleAction&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;success&quot;</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">&quot;redirect&quot;</span><span class="tag">&gt;</span><span>success.jsp</span><span class="tag">&lt;/</span><span class="tag-name">result</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;input&quot;</span><span class="tag">&gt;</span><span>index.jsp</span><span class="tag">&lt;/</span><span class="tag-name">result</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;params&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;validation&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;workflow&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">action</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">package</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="tag">&lt;/</span><span class="tag-name">xwork</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>新增两个拦截器 validation 和 workflow，第一个拦截器增加了验证的功能，第二个拦截器会改变action拦截器的运行顺序，具体是：先执行 <font face="Arial">validate（）方法，让后调用<font face="Arial">hasFieldErrors（）方法检查是否有错误，如果有直接返回input，而不再执行余下的action.</font></font></p>
<p><span><span class="tag"><span class="tag"><span class="tag"><span class="tag"><span class="tag">index.jsp将会做如下变化</span></span></span></span></span></span></p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span>%@taglib&nbsp;</span><span class="attribute">prefix</span><span>=</span><span class="attribute-value">&quot;ww&quot;</span><span>&nbsp;</span><span class="attribute">uri</span><span>=</span><span class="attribute-value">&quot;/webwork&quot;</span><span>&nbsp;%</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">div</span><span>&nbsp;</span><span class="attribute">style</span><span>=</span><span class="attribute-value">&quot;color:&nbsp;red&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">ww:fielderror</span><span>&nbsp;</span><span class="tag">/&gt;</span><span class="tag"><span class="tag-name">div</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">form</span><span>&nbsp;</span><span class="attribute">action</span><span>=</span><span class="attribute-value">&quot;simple.action&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">&quot;text&quot;</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;user.username&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">br</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">&quot;password&quot;</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;user.password&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">br</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">&quot;submit&quot;</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;submit&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag"><span class="tag-name">form</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class=""><span></span><span class="tag"><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span></span><span class="tag"><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p>增加一个捕获错误的标签：</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">ww:fielderror</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<p>&nbsp;</p>
<p>其余部分都不会变化</p>
<p>效果图：</p>
<p><img src="http://san-yun.javaeye.com/upload/picture/pic/2587/cc2e6948-a916-4a28-bed6-262a13d3db27.bmp " alt="" /></p>
</font></font>
          <br/>
          <span style="color:red;">
            <a href="http://san-yun.javaeye.com/blog/64623#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 22 Mar 2007 11:41:45 +0800</pubDate>
        <link>http://san-yun.javaeye.com/blog/64623</link>
        <guid>http://san-yun.javaeye.com/blog/64623</guid>
      </item>
      <item>
        <title>webwork2入门(二.1)</title>
        <author>san_yun</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://san-yun.javaeye.com">san_yun</a>&nbsp;
          链接：<a href="http://san-yun.javaeye.com/blog/64388" style="color:red;">http://san-yun.javaeye.com/blog/64388</a>&nbsp;
          发表时间: 2007年03月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>这一节,我们要掌握的东西</p>
<p>webwork操作session</p>
<p>webwork的验证</p>
<p>webwork两种驱动方式:</p>
<ul>
    <li><font face="Arial">Property-Driven </font></li>
    <li><font face="Arial">Model-Driven</font> </li>
</ul>
<p>前面我们已经学会了webwork的第一个例子,我们发现webwork中的Action是完全和Sevlet解耦合的,在web开发中,我们很多时候都要对Session,Application,Parameter进行操作,那么在webwork中我们该怎么做呢?</p>
<p>我们可以通过两种方式对它们进行操作,一种是通过<strong><font size="-1">com.opensymphony.xwork.</font>ActionContext</strong>进行操作,另外一种是通过实现<font size="-1"><strong>com.opensymphony.webwork.interceptor.SessionAware</strong>接口,这一节我们只关注第一种方式</font> </p>
<p>参考webwork的API,ActionContext是一个执行中的Action的上下文(Context),里面存放了Action,Session,Application,Parameter等信息,通过ActionContext我们就可以很方便的实现上述我们想要的功能啦!那么你可能会问ActionContext又是如何得到这些信息的呢?还记得上个教程中配置文件web.xml里的过滤器(filter)吗? 当一个浏览器产生一个请求到达webwork的时候,首先是被过滤器获得,过滤器通过询问<font size="-1"><strong>com.opensymphony.webwork.dispatcher.mapper.ActionMapper</strong>接口,是否要响应这次请求(实际上就是看我们的配置文件里面是不是有这个action 名字),如果是,过滤器就负责把Session,Parameter,ServletContext等信息转化成一个map对象</font></p>
<p><font size="-1">然后在通过<strong>com.opensymphony.xwork.ActionProxyFactory</strong> 的<font face="Arial">createActionProxy(<font face="Arial">String namespace,<font face="Arial">String actionName,<font face="Arial">&nbsp;Map extraContext,<font face="Arial">boolean executeResult,<font face="Arial">boolean cleanupContext</font></font></font></font></font>)</font>创建ActinoProxy,注意它的参数,第一个是Action的名字空间,第一个是Action的名字,第三个map这里面就是包含的就是上面的信息了.通过ActionProxy,就已经解耦合了面向Servlet的webwork和xwork拉!</font></p>
<p><font size="2">在ActionProxy通过一系列的方法之后会创建<font size="-1"><strong>com.opensymphony.xwork.ActionInvocation</strong>接口,这个接口表示的是一次Action执行的状态,ActionContext实际上就是在这个接口的实现类<strong>DefaultActionInvocation</strong>被初始化的,</font>&nbsp;查看API,可以看到ActionInvocation有一个<strong>getInvocationContext()</strong>的方法,所以ActionContext就是这样来的</font></p>
<p><font size="2">理论说了这么多,还是来点实际的吧:</font></p>
<p>类:</p>
<p>Domain Object: User</p>
<p>Action :<font face="Arial">SimpleAction</font></p>
<p>页面:</p>
<p>index.jsp</p>
<p>success.jsp</p>
<p>先看index.jsp</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span>%@taglib&nbsp;</span><span class="attribute">prefix</span><span>=</span><span class="attribute-value">&quot;ww&quot;</span><span>&nbsp;</span><span class="attribute">uri</span><span>=</span><span class="attribute-value">&quot;/webwork&quot;</span><span>&nbsp;%</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">form</span><span>&nbsp;</span><span class="attribute">action</span><span>=</span><span class="attribute-value">&quot;simple.action&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">&quot;text&quot;</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;user.username&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">br</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">&quot;password&quot;</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;user.password&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">br</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">&quot;submit&quot;</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;submit&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="tag">&lt;/</span><span class="tag-name">form</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="tag">&lt;/</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="tag">&lt;/</span><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>和第一个教程是一样的，我就不再重复</p>
<p>User:</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;mypackage; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;java.util.ArrayList; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;java.util.List; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;User&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;username; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;password; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;message&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ArrayList(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;List&nbsp;getMessage()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;message; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setMessage(List&nbsp;message)&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.message&nbsp;=&nbsp;message; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getPassword()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;password; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPassword(String&nbsp;password)&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.password&nbsp;=&nbsp;password; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getUsername()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;username; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setUsername(String&nbsp;username)&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.username&nbsp;=&nbsp;username; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
<p><font face="Arial">SimpleAction:</font></p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;mypackage; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;java.util.Map; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork.Action; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork.ActionContext; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;SimpleAction&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Action&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;User&nbsp;user&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;User(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;execute()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(Thread.currentThread().getName()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionContext&nbsp;context&nbsp;=&nbsp;ActionContext.getContext(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map&nbsp;session&nbsp;=&nbsp;context.getSession(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.put(</span><span class="string">&quot;user&quot;</span><span>,&nbsp;user); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.getMessage().add(</span><span class="string">&quot;msg1&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.getMessage().add(</span><span class="string">&quot;msg2&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.getMessage().add(</span><span class="string">&quot;msg3&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;SUCCESS; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;User&nbsp;getUser()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;user; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setUser(User&nbsp;user)&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">this</span><span>.user&nbsp;=&nbsp;user; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>其实代码比较简单</p>
<p>ActionContext通过静态方法返回自身的实例,然后可以看到context有很多方法,包括<font face="Arial">getApplication(),getSession(),getParameter(),它们返回的都是map.然后分别对这个map进行操作就可以拉</font></p>
<p>你可能会觉的奇怪,ActionContext通过一个简单的map如何区分两个不同的会话(Session)呢?</p>
<p>答案在于ActionContext是一个线程本地变量（<strong>thread local）</strong>，webwork对于每一个不同的线程，都会把ActionContext放在他们的ThreadLocal中，而我们底层(Tomcat服务器,也是Servlet规范)对于每一个浏览器请求都会产生一个唯一的线程，这样一个线程对应一个浏览器会话，同时也对应了一个ActionContext.</p>
<p>我们可以给一个简单的Servlet&nbsp;例子来帮助理解:</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;mypackage; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;java.io.IOException; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;java.io.PrintWriter; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;javax.servlet.http.HttpServlet; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">import</span><span>&nbsp;javax.servlet.http.HttpServletRequest; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">import</span><span>&nbsp;javax.servlet.http.HttpServletResponse; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ThreadLocalServlet&nbsp;</span><span class="keyword">extends</span><span>&nbsp;HttpServlet&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;service(HttpServletRequest&nbsp;request,HttpServletResponse&nbsp;response)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;IOException{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(</span><span class="string">&quot;text/html&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PrintWriter&nbsp;out&nbsp;=&nbsp;response.getWriter(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.println(Thread.currentThread().getName());&nbsp;</span><span class="comment">//得到当前线程的名字 </span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>以下三个不同的浏览器窗口访问这个Servlet的一种结果：</p>
<p>http-8080-Processor24 </p>
<p>http-8080-Processor25</p>
<p>http-8080-Processor26</p>
<p>webwork会通过三个不同的线程(同时对应了三个不同的浏览器窗口)产生三个不同的ActionContext实例 ，这样就起到了回话的作用了</p>
<p>好了，这个问题搞清楚之后，继续前面的的Action,</p>
<p>来看Action的配置文件xwork.xml</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span><!--CTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd"</sp--><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span> </span></li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">xwork</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">include</span><span>&nbsp;</span><span class="attribute">file</span><span>=</span><span class="attribute-value">&quot;webwork-default.xml&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">package</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;default&quot;</span><span>&nbsp;</span><span class="attribute">extends</span><span>=</span><span class="attribute-value">&quot;webwork-default&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">action</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;simple&quot;</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">&quot;mypackage.SimpleAction&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;success&quot;</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">&quot;redirect&quot;</span><span class="tag">&gt;</span><span>success.jsp</span><span class="tag"><span class="tag-name">result</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;params&quot;</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">action</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">package</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class=""><span></span><span class="tag"><span class="tag-name">xwork</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
<p>&nbsp;</p>
<p>这个配置文件和上篇文件的配置文件是一样的</p>
<p>1.把默认webwork-default.xml包含在我们的配置文件里，webwork-default.xml放在webwork.jar文件中,里面定义了拦截器(inteceptor)，和返回(result)，这里是一个代码片段</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span><!--CTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd"</sp--><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span> </span></li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">xwork</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">package</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;webwork-default&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">result-types</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;...... &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result-type</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;dispatcher&quot;</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">&quot;com.opensymphony.webwork.dispatcher.ServletDispatcherResult&quot;</span><span>&nbsp;</span><span class="attribute">default</span><span>=</span><span class="attribute-value">&quot;true&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result-type</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;redirect&quot;</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">&quot;com.opensymphony.webwork.dispatcher.ServletRedirectResult&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;</span><span class="tag"><span class="tag-name">result-types</span><span class="tag">&gt;</span><span>&nbsp; &nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">interceptors</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>...... &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">interceptor</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;params&quot;</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">&quot;com.opensymphony.xwork.interceptor.ParametersInterceptor&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>......&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag"><span class="tag-name">interceptors</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">package</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">&quot;webwork-default&quot;</span><span class="tag">&gt;</span><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag"><span class="tag-name">xwork</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>2.定义一个package，相当于java里面的的package关键字，起到一个命名空间的作用</p>
<p>3.在pakcage里面定义action，一个package里面可以定义多个action，这里主义的是name 要和 index.jsp 表单中action的名字相同。</p>
<p>4.在action中定义result，默认的返回方式(type)是dispater,我们把它改为重定向redirect</p>
<p>5.定义我们引用的&nbsp;拦截器params</p>
<p>最后来看我们的success.jsp</p>
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span>%@taglib&nbsp;</span><span class="attribute">prefix</span><span>=</span><span class="attribute-value">&quot;ww&quot;</span><span>&nbsp;</span><span class="attribute">uri</span><span>=</span><span class="attribute-value">&quot;/webwork&quot;</span><span>%</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">ww:property</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;#session.user.username&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">ww:property</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;#session['user'].password&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">ww:iterator</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;#session.user.message&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">div</span><span>&nbsp;</span><span class="attribute">style</span><span>=</span><span class="attribute-value">&quot;color:&nbsp;red&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">ww:property</span><span class="tag">/&gt;</span><span class="tag"><span class="tag-name">div</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span></span><span class="tag"><span class="tag-name">ww:iterator</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="tag"><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class=""><span></span><span class="tag"><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>1.声明了我们要使用的webwork标签库</p>
<p>2.通过</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">ww:property</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;&quot;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<p>的形式，得到我们想要获取的值，</p>
<p>访问session可以通过两种方式</p>
<div class="dp-highlighter">
<ol class="dp-xml">
    <li class="alt"><span><span>#session.user.username &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>#session['user'].password&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>我个人觉得第一种更简单一些。注意这样访问</p>
<div class="code_title">
<div class="dp-highlighter">
<ol class="dp-xml">
    <li class="alt"><span><span>#session['user.password']&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
</div>
<p>是得不到正确值的.</p>
<p>3.以下代码</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">ww:iterator</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">&quot;#session.user.message&quot;</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">div</span><span>&nbsp;</span><span class="attribute">style</span><span>=</span><span class="attribute-value">&quot;color:&nbsp;red&quot;</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">ww:property</span><span class="tag">/&gt;</span><span class="tag">&lt;/</span><span class="tag-name">div</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="tag">&lt;/</span><span class="tag-name">ww:iterator</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>声明了一个迭代器标签它，它可以方便的取出一个容器里面的值,</p>
<p>&nbsp;</p>
<p>ok,通过webw