??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲日韩乱码中文无码蜜桃臀,亚洲国产高清在线一区二区三区 ,亚洲国产成人无码AV在线影院http://www.tkk7.com/DenisLing/The only documentation is the code itselfzh-cnSat, 10 May 2025 19:30:13 GMTSat, 10 May 2025 19:30:13 GMT60Spring中的DAO和Servicehttp://www.tkk7.com/DenisLing/archive/2006/02/05/daoAndServiceInSpring.htmlDenisLingDenisLingSun, 05 Feb 2006 09:17:00 GMThttp://www.tkk7.com/DenisLing/archive/2006/02/05/daoAndServiceInSpring.htmlhttp://www.tkk7.com/DenisLing/comments/29620.htmlhttp://www.tkk7.com/DenisLing/archive/2006/02/05/daoAndServiceInSpring.html#Feedback0http://www.tkk7.com/DenisLing/comments/commentRss/29620.htmlhttp://www.tkk7.com/DenisLing/services/trackbacks/29620.html阅读全文

DenisLing 2006-02-05 17:17 发表评论
]]>
数据库设计的范式大纲及一个小的实例说?/title><link>http://www.tkk7.com/DenisLing/archive/2005/12/20/24725.html</link><dc:creator>DenisLing</dc:creator><author>DenisLing</author><pubDate>Tue, 20 Dec 2005 02:54:00 GMT</pubDate><guid>http://www.tkk7.com/DenisLing/archive/2005/12/20/24725.html</guid><wfw:comment>http://www.tkk7.com/DenisLing/comments/24725.html</wfw:comment><comments>http://www.tkk7.com/DenisLing/archive/2005/12/20/24725.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.tkk7.com/DenisLing/comments/commentRss/24725.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/DenisLing/services/trackbacks/24725.html</trackback:ping><description><![CDATA[ <p class="MsoNormal" style="margin-bottom: 12pt;"><b><span style="font-size: 14pt; font-family: 宋体;" lang="EN-US"><o:p> </o:p></span></b></p> <p class="MsoNormal" style="text-align: center;" align="center"><b><span style="font-size: 26pt; font-family: 黑体; color: red;">数据库设计的范式大纲 </span></b><span style="font-size: 26pt; font-family: 黑体;" lang="EN-US"><o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 14pt; font-family: 宋体;">W一范式<span lang="EN-US">:<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-indent: 0.5in;"><span style="font-size: 14pt; font-family: 宋体;">对于表中的每一行,必须且仅仅有唯一的行?span lang="EN-US">.</span>在一行中的每一列仅有唯一的值ƈ且具有原子?span lang="EN-US">.<o:p></o:p></span></span></p> <p class="MsoNormal" style=""><span style="font-size: 14pt; font-family: 宋体;">W二范式<span lang="EN-US">:<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-indent: 0.5in;"><span style="font-size: 14pt; font-family: 宋体;">W二范式要求非主键列是主键的子集Q非主键列活动必d全依赖整个主键。主键必L唯一性的元素<span lang="EN-US">,</span>一个主键可以由一个或更多的组成唯一值的列组成。一旦创建,主键无法改变Q外键关联一个表的主键。主外键兌意味着一对多的关p?span lang="EN-US">.<o:p></o:p></span></span></p> <p class="MsoNormal" style=""><span style="font-size: 14pt; font-family: 宋体;">W三范式<span lang="EN-US">:<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-indent: 0.5in;"><span style="font-size: 14pt; font-family: 宋体;">W三范式要求非主键列互不依赖<span lang="EN-US">.<o:p></o:p></span></span></p> <p class="MsoNormal" style=""><span style="font-size: 14pt; font-family: 宋体;">W四范式<span lang="EN-US">:<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-indent: 0.5in;"><span style="font-size: 14pt; font-family: 宋体;">W四范式止主键列和非主键列一对多关系不受U束<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style=""><span style="font-size: 14pt; font-family: 宋体;">W五范式<span lang="EN-US">:<o:p></o:p></span></span></p> <p class="MsoNormal" style="text-indent: 0.5in;"><span style="font-size: 14pt; font-family: 宋体;">W五范式表分割成尽可能的块,Z排除在表中所有的冗余<span lang="EN-US">.<o:p></o:p></span></span></p> <p class="MsoNormal" style="margin-bottom: 12pt;"><b><span style="font-family: 宋体;" lang="EN-US"><o:p> </o:p></span></b></p> <p class="MsoNormal" style="margin-bottom: 12pt;"><b><span style="font-family: 宋体;" lang="EN-US"><font color="#ff0000">下面先讨论前<span lang="EN-US">3</span>个范式:</font><o:p></o:p></span></b><span lang="EN-US"><o:p><br></o:p></span></p> <p class="MsoNormal" style="margin-bottom: 12pt;"><b><span style="font-family: 宋体;" lang="EN-US"><o:p> </o:p></span></b></p> <p class="MsoNormal" style="margin-bottom: 12pt;"><b><span style="font-family: 宋体;">引言</span></b><span style="font-family: 宋体;" lang="EN-US"><br> <br> </span><span style="font-family: 宋体;">  数据库的设计范式是数据库设计所需要满的规范Q满些规范的数据库是z的、结构明晰的Q同Ӟ不会发生插入 Q?span lang="EN-US">insert</span>Q、删除(<span lang="EN-US">delete</span>Q和更新Q?span lang="EN-US">update</span>Q操作异常。反之则是ؕ七八p,不仅l数据库的编Eh员制造麻烦,而且面目可憎Q可能存储了 大量不需要的冗余信息?span lang="EN-US"><br> <br> </span>  设计范式是不是很难懂呢?非也Q大学教材上l我们一堆数学公式我们当然看不懂Q也C住。所以我们很多h根本不按照范式来设计数据库?span lang="EN-US"><br> <br> </span>  实质上,设计范式用很形象、很z的话语p说清楚,道明白。本文将对范式进行通俗地说明,q以W者曾l设计的一个简单论坛的数据库ؓ例来讲解怎样这些范式应用于实际工程?span lang="EN-US"><br> <br> </span>  <b>范式说明</b><span lang="EN-US"><br> <br> </span>  W一范式Q?span lang="EN-US">1NF</span>Q:数据库表中的字段都是单一属性的Q不可再分。这个单一属性由基本cd构成Q包括整型、实数、字W型、逻辑型、日期型{?span lang="EN-US"><br> <br> </span>  例如Q如下的数据库表是符合第一范式的:<span lang="EN-US"><o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 90%;" border="1" cellpadding="0" cellspacing="0" width="90%"> <tbody><tr style=""> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">1 <o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">2 <o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">3 <o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">4<o:p></o:p></span></span></p> </td> </tr> <tr style=""> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> </td> </tr> </tbody></table> </div> <p class="MsoNormal" style="margin-bottom: 12pt;"><span style="font-family: 宋体;" lang="EN-US"><br> </span><span style="font-family: 宋体;">  而这L数据库表是不W合W一范式的:<span lang="EN-US"><o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 90%;" border="1" cellpadding="0" cellspacing="0" width="90%"> <tbody><tr style=""> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">1 <o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">2 <o:p></o:p></span></span></p> </td> <td colspan="2" style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">3 <o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">4<o:p></o:p></span></span></p> </td> </tr> <tr style=""> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">3.1<o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">字段<span lang="EN-US">3.2 <o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"> <o:p></o:p></span></p> </td> </tr> <!--[if !supportMisalignedColumns]--> <tr height="0"> <td style="border: medium none ;" width="119"><br></td> <td style="border: medium none ;" width="119"><br></td> <td style="border: medium none ;" width="157"><br></td> <td style="border: medium none ;" width="157"><br></td> <td style="border: medium none ;" width="119"><br></td> </tr> <!--[endif]--> </tbody></table> </div> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"><br> </span><span style="font-family: 宋体;">  很显Ӟ在当前的M关系数据库管理系l(<span lang="EN-US">DBMS</span>Q中Q傻瓜也不可能做ZW合W一范式的数据库Q因?span lang="EN-US">DBMS</span>不允怽把数据库表的一列再分成二列或多列。因此,你想在现有的<span lang="EN-US">DBMS</span>中设计出不符合第一范式的数据库都是不可能的?span lang="EN-US"><br> <br> </span>  W二范式Q?span lang="EN-US">2NF</span>Q:数据库表中不存在非关键字D对M候选关键字D늚部分函数依赖Q部分函C赖指的是存在l合关键字中的某些字D决定非关键字段的情况)Q也x有非关键字段都完全依赖于L一l候选关键字?span lang="EN-US"><br> <br> </span>  假定选课关系表ؓ<span lang="EN-US">SelectCourse(</span>学号<span lang="EN-US">, </span>姓名<span lang="EN-US">, </span>q龄<span lang="EN-US">, </span>评名称<span lang="EN-US">, </span>成W<span lang="EN-US">, </span>学分<span lang="EN-US">)</span>Q关键字为组合关键字<span lang="EN-US">(</span>学号<span lang="EN-US">, </span>评名称<span lang="EN-US">)</span>Q因为存在如下决定关p:<span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(</span>学号<span lang="EN-US">, </span>评名称<span lang="EN-US">) ?(</span>姓名<span lang="EN-US">, </span>q龄<span lang="EN-US">, </span>成W<span lang="EN-US">, </span>学分<span lang="EN-US">)<br> <br> </span>  q个数据库表不满第二范式,因ؓ存在如下军_关系Q?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(</span>评名称<span lang="EN-US">) ?(</span>学分<span lang="EN-US">)<br> <br> </span>  <span lang="EN-US">(</span>学号<span lang="EN-US">) ?(</span>姓名<span lang="EN-US">, </span>q龄<span lang="EN-US">)<br> <br> </span>  卛_在组合关键字中的字段军_非关键字的情c?span lang="EN-US"><br> <br> </span>  ׃不符?span lang="EN-US">2NF</span>Q这个选课关系表会存在如下问题Q?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(1) </span>数据冗余Q?span lang="EN-US"><br> <br> </span>  同一门课E由<span lang="EN-US">n</span>个学生选修Q?span lang="EN-US">"</span>学分<span lang="EN-US">"</span>重?span lang="EN-US">n-1</span>ơ;同一个学生选修?span lang="EN-US">m</span>门课E,姓名和年龄就重复?span lang="EN-US">m-1</span>ơ?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(2) </span>更新异常Q?span lang="EN-US"><br> <br> </span>  若调整了某门评的学分,数据表中所有行?span lang="EN-US">"</span>学分<span lang="EN-US">"</span>值都要更斎ͼ否则会出现同一门课E学分不同的情况?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(3) </span>插入异常Q?span lang="EN-US"><br> <br> </span>  假设要开设一门新的课E,暂时q没有h选修。这P׃q没?span lang="EN-US">"</span>学号<span lang="EN-US">"</span>关键字,评名称和学分也无法记录入数据库?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(4) </span>删除异常Q?span lang="EN-US"><br> <br> </span>  假设一批学生已l完成课E的选修Q这些选修记录应该从数据库表中删除。但是,与此同时Q课E名U和学分信息也被删除了。很昄Q这也会D插入异常?span lang="EN-US"> <br> <br> </span>  把选课关系?span lang="EN-US">SelectCourse</span>改ؓ如下三个表:<span lang="EN-US"><br> <br> </span>  学生Q?span lang="EN-US">Student(</span>学号<span lang="EN-US">, </span>姓名<span lang="EN-US">, </span>q龄<span lang="EN-US">)</span>Q?span lang="EN-US"><br> <br> </span>  评Q?span lang="EN-US">Course(</span>评名称<span lang="EN-US">, </span>学分<span lang="EN-US">)</span>Q?span lang="EN-US"><br> <br> </span>  选课关系Q?span lang="EN-US">SelectCourse(</span>学号<span lang="EN-US">, </span>评名称<span lang="EN-US">, </span>成W<span lang="EN-US">)</span>?span lang="EN-US"><br> <br> </span>  q样的数据库表是W合W二范式的,消除了数据冗余、更新异常、插入异常和删除异常?span lang="EN-US"><br> <br> </span>  另外Q所有单关键字的数据库表都符合第二范式,因ؓ不可能存在组合关键字?span lang="EN-US"><br> <br> </span>   W三范式Q?span lang="EN-US">3NF</span>Q:在第二范式的基础上,数据表中如果不存在非关键字段对Q一候选关键字D늚传递函C赖则W合W三范式。所谓传递函C赖,指的是如 果存?span lang="EN-US">"A ?B ?C"</span>的决定关p,?span lang="EN-US">C</span>传递函C赖于<span lang="EN-US">A</span>。因此,满W三范式的数据库表应该不存在如下依赖关系Q?span lang="EN-US"><br> <br> </span>  关键字段<span lang="EN-US"> ?</span>非关键字D?span lang="EN-US">x ?</span>非关键字D?span lang="EN-US">y<br> <br> </span>  假定学生关系表ؓ<span lang="EN-US">Student(</span>学号<span lang="EN-US">, </span>姓名<span lang="EN-US">, </span>q龄<span lang="EN-US">, </span>所在学?span lang="EN-US">, </span>学院地点<span lang="EN-US">, </span>学院电话<span lang="EN-US">)</span>Q关键字为单一关键?span lang="EN-US">"</span>学号<span lang="EN-US">"</span>Q因为存在如下决定关p:<span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(</span>学号<span lang="EN-US">) ?(</span>姓名<span lang="EN-US">, </span>q龄<span lang="EN-US">, </span>所在学?span lang="EN-US">, </span>学院地点<span lang="EN-US">, </span>学院电话<span lang="EN-US">)<br> <br> </span>  q个数据库是W合<span lang="EN-US">2NF</span>的,但是不符?span lang="EN-US">3NF</span>Q因为存在如下决定关p:<span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(</span>学号<span lang="EN-US">) ?(</span>所在学?span lang="EN-US">) ?(</span>学院地点<span lang="EN-US">, </span>学院电话<span lang="EN-US">)<br> <br> </span>  卛_在非关键字段<span lang="EN-US">"</span>学院地点<span lang="EN-US">"</span>?span lang="EN-US">"</span>学院电话<span lang="EN-US">"</span>对关键字D?span lang="EN-US">"</span>学号<span lang="EN-US">"</span>的传递函C赖?span lang="EN-US"><br> <br> </span>  它也会存在数据冗余、更新异常、插入异常和删除异常的情况,读者可自行分析得知?span lang="EN-US"><br> <br> </span>  把学生关p表分ؓ如下两个表:<span lang="EN-US"><br> <br> </span>  学生Q?span lang="EN-US">(</span>学号<span lang="EN-US">, </span>姓名<span lang="EN-US">, </span>q龄<span lang="EN-US">, </span>所在学?span lang="EN-US">)</span>Q?span lang="EN-US"><br> <br> </span>  学院Q?span lang="EN-US">(</span>学院<span lang="EN-US">, </span>地点<span lang="EN-US">, </span>电话<span lang="EN-US">)</span>?span lang="EN-US"><br> <br> </span>  q样的数据库表是W合W三范式的,消除了数据冗余、更新异常、插入异常和删除异常?span lang="EN-US"><br> <br> </span>  鲍依?span lang="EN-US">-</span>U得范式Q?span lang="EN-US">BCNF</span>Q:在第三范式的基础上,数据库表中如果不存在M字段对Q一候选关键字D늚传递函C赖则W合W三范式?span lang="EN-US"><br> <br> </span>  假设仓库理关系表ؓ<span lang="EN-US">StorehouseManage(</span>仓库<span lang="EN-US">ID, </span>存储物品<span lang="EN-US">ID, </span>理?span lang="EN-US">ID, </span>数量<span lang="EN-US">)</span>Q且有一个管理员只在一个仓库工作;一个仓库可以存储多U物品。这个数据库表中存在如下军_关系Q?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(</span>仓库<span lang="EN-US">ID, </span>存储物品<span lang="EN-US">ID) ?</span>理?span lang="EN-US">ID, </span>数量<span lang="EN-US">)<br> <br> </span>  <span lang="EN-US">(</span>理?span lang="EN-US">ID, </span>存储物品<span lang="EN-US">ID) ?(</span>仓库<span lang="EN-US">ID, </span>数量<span lang="EN-US">)<br> <br> </span>  所以,<span lang="EN-US">(</span>仓库<span lang="EN-US">ID, </span>存储物品<span lang="EN-US">ID)</span>?span lang="EN-US">(</span>理?span lang="EN-US">ID, </span>存储物品<span lang="EN-US">ID)</span>都是<span lang="EN-US">StorehouseManage</span>的候选关键字Q表中的唯一非关键字Dؓ数量Q它是符合第三范式的。但是,׃存在如下军_关系Q?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(</span>仓库<span lang="EN-US">ID) ?(</span>理?span lang="EN-US">ID)<br> <br> </span>  <span lang="EN-US">(</span>理?span lang="EN-US">ID) ?(</span>仓库<span lang="EN-US">ID)<br> <br> </span>  卛_在关键字D决定关键字D늚情况Q所以其不符?span lang="EN-US">BCNF</span>范式。它会出现如下异常情况:<span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(1) </span>删除异常Q?span lang="EN-US"><br> <br> </span>  当仓库被清空后,所?span lang="EN-US">"</span>存储物品<span lang="EN-US">ID"</span>?span lang="EN-US">"</span>数量<span lang="EN-US">"</span>信息被删除的同时Q?span lang="EN-US">"</span>仓库<span lang="EN-US">ID"</span>?span lang="EN-US">"</span>理?span lang="EN-US">ID"</span>信息也被删除了?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(2) </span>插入异常Q?span lang="EN-US"><br> <br> </span>  当仓库没有存储Q何物品时Q无法给仓库分配理员?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(3) </span>更新异常Q?span lang="EN-US"><br> <br> </span>  如果仓库换了理员,则表中所有行的管理员<span lang="EN-US">ID</span>都要修改?span lang="EN-US"><br> <br> </span>  把仓库管理关p表分解Z个关p表Q?span lang="EN-US"><br> <br> </span>  仓库理Q?span lang="EN-US">StorehouseManage(</span>仓库<span lang="EN-US">ID, </span>理?span lang="EN-US">ID)</span>Q?span lang="EN-US"><br> <br> </span>  仓库Q?span lang="EN-US">Storehouse(</span>仓库<span lang="EN-US">ID, </span>存储物品<span lang="EN-US">ID, </span>数量<span lang="EN-US">)</span>?span lang="EN-US"><br> <br> </span>  q样的数据库表是W合<span lang="EN-US">BCNF</span>范式的,消除了删除异常、插入异常和更新异常?b><span lang="EN-US"><o:p></o:p></span></b></span></p> <p class="MsoNormal"><b><span style="font-family: 宋体;">范式应用<span lang="EN-US"><br> <br> </span></span></b><span style="font-family: 宋体;">  我们来逐步搞定一个论坛的数据库,有如下信息:<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">1</span>Q?用户Q用户名Q?span lang="EN-US">email</span>Q主,电话Q联pd址<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">2</span>Q?帖子Q发帖标题,发帖内容Q回复标题,回复内容<span lang="EN-US"> <br> <br> </span>  W一ơ我们将数据库设计ؓ仅仅存在表:<span lang="EN-US"><br> </span>  <span lang="EN-US"> <o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 90%;" border="1" cellpadding="0" cellspacing="0" width="90%"> <tbody><tr style=""> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">用户?span lang="EN-US"> <o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US">email <o:p></o:p></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">主页<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">电话<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">联系地址<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">发帖标题<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">发帖内容<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">回复标题<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">回复内容<span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> </tbody></table> </div> <p class="MsoNormal" style="margin-bottom: 12pt;"><span style="font-family: 宋体;" lang="EN-US"><br> </span><span style="font-family: 宋体;">  q个数据库表W合W一范式Q但是没有Q何一l候选关键字能决定数据库表的整行Q唯一的关键字D는户名也不能完全决定整个元l。我们需要增?span lang="EN-US">"</span>发帖<span lang="EN-US">ID"</span>?span lang="EN-US">"</span>回复<span lang="EN-US">ID"</span>字段Q即表修改为:<span lang="EN-US"><o:p></o:p></span></span></p> <div align="center"> <table class="MsoNormalTable" style="width: 90%;" border="1" cellpadding="0" cellspacing="0" width="90%"> <tbody><tr style=""> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">用户?span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US">email<o:p></o:p></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">主页<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">电话<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">联系地址<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">发帖<span lang="EN-US">ID<o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">发帖标题<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">发帖内容<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">回复<span lang="EN-US">ID<o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">回复标题<span lang="EN-US"><o:p></o:p></span></span></p> </td> <td style="padding: 1.5pt;"> <p class="MsoNormal"><span style="font-family: 宋体;">回复内容<span lang="EN-US"><o:p></o:p></span></span></p> </td> </tr> </tbody></table> </div> <p class="MsoNormal"><span style="font-family: 宋体;" lang="EN-US"><br> </span><span style="font-family: 宋体;">  q样数据表中的关键字<span lang="EN-US">(</span>用户名,发帖<span lang="EN-US">ID</span>Q回?span lang="EN-US">ID)</span>能决定整行:<span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(</span>用户?span lang="EN-US">,</span>发帖<span lang="EN-US">ID,</span>回复<span lang="EN-US">ID) ?(email,</span>主页<span lang="EN-US">,</span>电话<span lang="EN-US">,</span>联系地址<span lang="EN-US">,</span>发帖标题<span lang="EN-US">,</span>发帖内容<span lang="EN-US">,</span>回复标题<span lang="EN-US">,</span>回复内容<span lang="EN-US">)<br> <br> </span>  但是Q这L设计不符合第二范式,因ؓ存在如下军_关系Q?span lang="EN-US"><br> <br> </span>  <span lang="EN-US">(</span>用户?span lang="EN-US">) ?(email,</span>主页<span lang="EN-US">,</span>电话<span lang="EN-US">,</span>联系地址<span lang="EN-US">)<br> <br> </span>  <span lang="EN-US">(</span>发帖<span lang="EN-US">ID) ?(</span>发帖标题<span lang="EN-US">,</span>发帖内容<span lang="EN-US">)<br> <br> </span>  <span lang="EN-US">(</span>回复<span lang="EN-US">ID) ?(</span>回复标题<span lang="EN-US">,</span>回复内容<span lang="EN-US">)<br> <br> </span>  即非关键字段部分函数依赖于候选关键字D,很明显,q个设计会导致大量的数据冗余和操作异常?span lang="EN-US"><br> <br> </span>  我们数据库表分解ؓQ带下划U的为关键字Q:<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">1</span>Q?用户信息Q用户名Q?span lang="EN-US">email</span>Q主,电话Q联pd址<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">2</span>Q?帖子信息Q发?span lang="EN-US">ID</span>Q标题,内容<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">3</span>Q?回复信息Q回?span lang="EN-US">ID</span>Q标题,内容<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">4</span>Q?发脓Q用户名Q发?span lang="EN-US">ID<br> <br> </span>  Q?span lang="EN-US">5</span>Q?回复Q发?span lang="EN-US">ID</span>Q回?span lang="EN-US">ID<br> <br> </span>  q样的设计是满W?span lang="EN-US">1</span>?span lang="EN-US">2</span>?span lang="EN-US">3</span>范式?span lang="EN-US">BCNF</span>范式要求的,但是q样的设计是不是最好的呢?<span lang="EN-US"><br> <br> </span>  不一定?span lang="EN-US"><br> <br> </span>   观察可知Q第<span lang="EN-US">4</span>?span lang="EN-US">"</span>发帖<span lang="EN-US">"</span>中的<span lang="EN-US">"</span>用户?span lang="EN-US">"</span>?span lang="EN-US">"</span>发帖<span lang="EN-US">ID"</span>之间?span lang="EN-US">1</span>Q?span lang="EN-US">N</span>的关p,因此我们可以?span lang="EN-US">"</span>发帖<span lang="EN-US">"</span>合ƈ到第<span lang="EN-US">2</span>的<span lang="EN-US">"</span>帖子信息<span lang="EN-US">"</span>中;W?span lang="EN-US">5</span>?span lang="EN-US">"</span>回复<span lang="EN-US">"</span>中的<span lang="EN-US"> "</span>发帖<span lang="EN-US">ID"</span>?span lang="EN-US">"</span>回复<span lang="EN-US">ID"</span>之间也是<span lang="EN-US">1</span>Q?span lang="EN-US">N</span>的关p,因此我们可以?span lang="EN-US">"</span>回复<span lang="EN-US">"</span>合ƈ到第<span lang="EN-US">3</span>的<span lang="EN-US">"</span>回复信息<span lang="EN-US">"</span>中。这样可以一定量地减数据冗余,新的设计为:<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">1</span>Q?用户信息Q用户名Q?span lang="EN-US">email</span>Q主,电话Q联pd址<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">2</span>Q?帖子信息Q用户名Q发?span lang="EN-US">ID</span>Q标题,内容<span lang="EN-US"><br> <br> </span>  Q?span lang="EN-US">3</span>Q?回复信息Q发?span lang="EN-US">ID</span>Q回?span lang="EN-US">ID</span>Q标题,内容<span lang="EN-US"><br> <br> </span>  数据库表<span lang="EN-US">1</span>昄满所有范式的要求Q?span lang="EN-US"><br> <br> </span>  数据库表<span lang="EN-US">2</span>中存在非关键字段<span lang="EN-US">"</span>标题<span lang="EN-US">"</span>?span lang="EN-US">"</span>内容<span lang="EN-US">"</span>对关键字D?span lang="EN-US">"</span>发帖<span lang="EN-US">ID"</span>的部分函C赖,即不满W二范式的要求,但是q一设计q不会导致数据冗余和操作异常Q?span lang="EN-US"><br> <br> </span>  数据库表<span lang="EN-US">3</span>中也存在非关键字D?span lang="EN-US">"</span>标题<span lang="EN-US">"</span>?span lang="EN-US">"</span>内容<span lang="EN-US">"</span>对关键字D?span lang="EN-US">"</span>回复<span lang="EN-US">ID"</span>的部分函C赖,也不满W二范式的要求,但是与数据库?span lang="EN-US">2</span>怼Q这一设计也不会导致数据冗余和操作异常?span lang="EN-US"><br> <br> </span>  由此可以看出Qƈ不一定要满范式的要求,对于<span lang="EN-US">1</span>Q?span lang="EN-US">N</span>关系Q当<span lang="EN-US">1</span>的一边合q到<span lang="EN-US">N</span>的那边后Q?span lang="EN-US">N</span>的那边就不再满W二范式了,但是q种设计反而比较好Q?span lang="EN-US"><br> <br> </span>  对于<span lang="EN-US">M</span>Q?span lang="EN-US">N</span>的关p,不能?span lang="EN-US">M</span>一Ҏ<span lang="EN-US">N</span>一边合q到另一边去Q这样会D不符合范式要求,同时D操作异常和数据冗余?span lang="EN-US"> <br> </span>对于<span lang="EN-US">1</span>Q?span lang="EN-US">1</span>的关p,我们可以左边的<span lang="EN-US">1</span>或者右边的<span lang="EN-US">1</span>合ƈ到另一边去Q设计导致不W合范式要求Q但是ƈ不会D操作异常和数据冗余?span lang="EN-US"><br> <br> </span>  <b>l论</b><span lang="EN-US"><br> <br> </span>  满范式要求的数据库设计是结构清晰的Q同时可避免数据冗余和操作异常。这q意味着不符合范式要求的设计一定是错误的,在数据库表中存在<span lang="EN-US">1</span>Q?span lang="EN-US">1</span>?span lang="EN-US">1</span>Q?span lang="EN-US">N</span>关系q种较特D的情况下,合ƈD的不W合范式要求反而是合理的?span lang="EN-US"><br> <br> </span>  在我们设计数据库的时候,一定要时刻考虑范式的要求?/span></p> <img src ="http://www.tkk7.com/DenisLing/aggbug/24725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/DenisLing/" target="_blank">DenisLing</a> 2005-12-20 10:54 <a href="http://www.tkk7.com/DenisLing/archive/2005/12/20/24725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对spring事务cd详解的一点补充(关于嵌套事务Q?/title><link>http://www.tkk7.com/DenisLing/archive/2005/12/19/extendsOfSpring.html</link><dc:creator>DenisLing</dc:creator><author>DenisLing</author><pubDate>Mon, 19 Dec 2005 08:02:00 GMT</pubDate><guid>http://www.tkk7.com/DenisLing/archive/2005/12/19/extendsOfSpring.html</guid><wfw:comment>http://www.tkk7.com/DenisLing/comments/24641.html</wfw:comment><comments>http://www.tkk7.com/DenisLing/archive/2005/12/19/extendsOfSpring.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.tkk7.com/DenisLing/comments/commentRss/24641.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/DenisLing/services/trackbacks/24641.html</trackback:ping><description><![CDATA[     摘要: 可能大家对PROPAGATION_NESTEDq不怎么了解Q觉得有必要再补充一下^_^Q?nbsp; <a href='http://www.tkk7.com/DenisLing/archive/2005/12/19/extendsOfSpring.html'>阅读全文</a><img src ="http://www.tkk7.com/DenisLing/aggbug/24641.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/DenisLing/" target="_blank">DenisLing</a> 2005-12-19 16:02 <a href="http://www.tkk7.com/DenisLing/archive/2005/12/19/extendsOfSpring.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring事务cd解http://www.tkk7.com/DenisLing/archive/2005/12/18/spring.htmlDenisLingDenisLingSun, 18 Dec 2005 08:30:00 GMThttp://www.tkk7.com/DenisLing/archive/2005/12/18/spring.htmlhttp://www.tkk7.com/DenisLing/comments/24503.htmlhttp://www.tkk7.com/DenisLing/archive/2005/12/18/spring.html#Feedback2http://www.tkk7.com/DenisLing/comments/commentRss/24503.htmlhttp://www.tkk7.com/DenisLing/services/trackbacks/24503.html

PROPAGATION_REQUIRED,readOnlyPROPAGATION_REQUIRED

估计有好多朋友还没有弄清楚里面的值的意思,仔细看完下面应该知道自己什么情况下面应该用什么样的声明。^_^  阅读全文

DenisLing 2005-12-18 16:30 发表评论
]]>
spring声明式事务管理祥q?/title><link>http://www.tkk7.com/DenisLing/archive/2005/12/01/22096.html</link><dc:creator>DenisLing</dc:creator><author>DenisLing</author><pubDate>Thu, 01 Dec 2005 03:47:00 GMT</pubDate><guid>http://www.tkk7.com/DenisLing/archive/2005/12/01/22096.html</guid><wfw:comment>http://www.tkk7.com/DenisLing/comments/22096.html</wfw:comment><comments>http://www.tkk7.com/DenisLing/archive/2005/12/01/22096.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/DenisLing/comments/commentRss/22096.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/DenisLing/services/trackbacks/22096.html</trackback:ping><description><![CDATA[<p>Spring也提供了声明式事务管理。这是通过Spring AOP实现的?/p><p>Spring 中进行事务管理的通常方式是利用AOPQ面向切片编E)的方式,为普通javacd装事务控Ӟ它是通过动态代理实现的Q由于接口是延迟实例化的Q? spring在这D|间内通过拦截器,加蝲事务切片。原理就是这P具体l节请参考jdk中有兛_态代理的文档。本文主要讲解如何在spring中进行事 务控制?br>动态代理的一个重要特征是Q它是针Ҏ口的Q所以我们的dao要通过动态代理来让spring接管事务Q就必须在dao前面抽象Z个接口,当然如果没有q样的接口,那么spring会用CGLIB来解决问题,但这不是spring推荐的方式,所以不做讨?</p><p><i><span id="esuuayy" class="remark">大多数Spring用户选择声明式事务管理。这是最媄响应用代码的选择Q?因而这是和<span id="cmmesoc" class="emphasis"><em>非R入?/em></span>的轻量容器的观忉|一致的?</span></i></p><p>从考虑EJB CMT和Spring声明式事务管理的怼以及不同之处出发是很有益的?它们的基本方法是怼的:都可以指定事务管理到单独的方法;如果需要可以在事务?下文调用<tt class="literal"><font face="新宋?>setRollbackOnly()</font></tt>Ҏ。不同之处如下:</p><div id="wgukmku" class="itemizedlist"><ul type="disc"><li><p>不象EJB CMTl定在JTA上,Spring声明式事务管理可以在M环境下用?只需更改配置文gQ它可以和JDBC、JDO、Hibernate或其他的事务机制一起工?</p></li><li><p>Spring可以使声明式事务理应用到普通Java对象Q不仅仅是特D的c,如EJB</p></li><li><p>Spring提供声明?span class="emphasis"><em>回滚规则</em></span>QEJB没有对应的特性, 我们在下面讨论q个Ҏ。回滚可以声明式控制Q不仅仅是编E式?</p></li><li><p>Spring允许你通过AOP定制事务行ؓ。例如,如果需要,你可以在事务 回滚中插入定制的行ؓ。你也可以增加Q意的通知Q就象事务通知一栗?EJB CMTQ除了?tt class="literal"><font face="新宋?>setRollbackOnly()</font></tt>Q你没有办法?够媄响容器的事务理</p></li><li><p>Spring不提供高端应用服务器提供的跨远E调用的事务上下文传播。如 果你需要这些特性,我们推荐你用EJB。然而,不要L使用q些Ҏ。通常?们ƈ不希望事务跨远E调?/p></li></ul></div><p>回滚规则的概忉|很重要的Q它们得我们可以指定哪些异常应该发赯 动回滚。我们在配置文g中,而不是Java代码中,以声明的方式指定。因此,虽然我们?然可以编E调?tt class="literal"><font face="新宋?>TransactionStatus</font></tt>对象?<tt class="literal"><font face="新宋?>setRollbackOnly()</font></tt>Ҏ来回滚当前事务,多数时候我们可?指定规则Q如<tt class="literal"><font face="新宋?>MyApplicationException</font></tt>应该D回滚?q有显著的优点,业务对象不需要依赖事务基设施。例如,它们通常不需要引 入Q何Spring APIQ事务或其他M东西?/p><p>EJB的默认行为是遇到<span id="egwomma" class="emphasis"><em>pȝ异常</em></span>Q通常是运行时异常Q, EJB容器自动回滚事务。EJB CMT遇到<span id="coagkww" class="emphasis"><em>应用E序异常</em></span> Q除?span class="emphasis"><em>java.rmi.RemoteException</em></span>外的checked异常Q时?会自动回滚事务。虽然Spring声明式事务管理沿用EJB的约定(遇到unchecked 异常自动回滚事务Q,但是q是可以定制的?/p><p>按照我们的测试,Spring声明式事务管理的性能要胜qEJB CMT?/p><p>? 帔R过TransactionProxyFactoryBean讄Spring事务代理。我们需 要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当? 们定义TransactionProxyFactoryBeanӞ必须提供一个相关的 PlatformTransactionManager的引用和<span id="eeceykc" class="bold"><b>事务属?/b></span>?<span id="eswiwmu" class="bold"><b>事务属?/b></span>含有上面描述的事务定义?/p><pre class="programlisting"><bean id="petStore" <br> class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><br> <property name="transactionManager"><ref bean="transactionManager"/></property><br> <property name="target"><ref bean="petStoreTarget"/></property><br> <property name="transactionAttributes"><br> <props><br> <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop><br> <prop key="update*">PROPAGATION_REQUIRED</prop><br> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop><br> </props><br> </property><br></bean></pre><p>? 务代理会实现目标对象的接口:q里是id为petStoreTarget的bean。(使用 CGLIB也可以实现具体类的代理。只要设|proxyTargetClass属性ؓtrue可以? 如果目标对象没有实现M接口Q这自动设|该属性ؓtrue。通常Q我们希望面向接口而不? cȝE。)使用proxyInterfaces属性来限定事务代理来代 理指定接口也是可以的Q一般来说是个好xQ。也可以通过?<tt class="literal"><font face="新宋?>org.springframework.aop.framework.ProxyConfig</font></tt>l承或所有AOP代理工厂׃n 的属性来定制TransactionProxyFactoryBean的行为?</p><p>q里的transactionAttributes属性定义在 <tt class="literal"><font face="新宋?>org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource</font></tt> 中的属性格式来讄。这个包括通配W的Ҏ名称映射是很直观的。注?insert*的映的值包括回滚规则。添加的<tt class="literal"><font face="新宋?>-MyCheckedException</font></tt> 指定如果Ҏ抛出<tt class="literal"><font face="新宋?>MyCheckedException</font></tt>或它的子c,事务?会自动回滚。可以用逗号分隔定义多个回滚规则?font color="#ff0000"><strong>-前缀强制回滚Q?前缀指定提交</strong></font>Q这允许即抛出unchecked异常时也可以提交事务Q当然你自己要明白自?在做什么)?/p><p><tt class="literal"><font face="新宋?>TransactionProxyFactoryBean</font></tt>允许你通过 “preInterceptors”和“postInterceptors”属性设|“前”或“后”通知来提供额外的 拦截行ؓ。可以设|Q意数量的“前”和“后”通知Q它们的cd可以?<tt class="literal"><font face="新宋?>Advisor</font></tt>Q可以包含一个切入点Q, <tt class="literal"><font face="新宋?>MethodInterceptor</font></tt>或被当前Spring配置支持的通知cd Q例?tt class="literal"><font face="新宋?>ThrowAdvice</font></tt>Q?<tt class="literal"><font face="新宋?>AfterReturningtAdvice</font></tt>?tt class="literal"><font face="新宋?>BeforeAdvice</font></tt>Q?q些都是默认支持的)。这些通知必须支持实例׃n模式。如果你需要高UAOP?性来使用事务Q如有状态的maxinQ那最好用通用?<tt class="literal"><font face="新宋?>org.springframework.aop.framework.ProxyFactoryBean</font></tt>Q?而不?tt class="literal"><font face="新宋?>TransactionProxyFactoryBean</font></tt>实用代理创徏者?/p><p>也可以设|自动代理:配置AOP框架Q不需要单独的代理定义cd可以生成cȝ 代理?/p>附两个spring的事务配|例子:<br><prop key="add"><br>     PROPAGATION_REQUIRES_NEW, -MyException <br></prop><br>注:上面的意思是addҎ独占一个事务,当事务处理过E中产生MyException异常或者该异常的子cd回滚该事务?br><br><prop key="loadAll"><br>    PROPAGATION_SUPPORTS, ISOLATION_READ_COMMITED, Readonly<br></prop><br>注:表示loadAllҎ支持事务Q而且不会d没有提交事务的数据。它的数据ؓ只读Q这h助于提高d的性能Q?br><br>附A Spring中的所有事务策?br><br>PROPAGATION_MANDATORY<br>PROPAGATION_NESTED <br>PROPAGATION_NEVER <br>PROPAGATION_NOT_SUPPORTED<br>PROPAGATION_REQUIRED<br>PROPAGATION_REQUIRED_NEW<br>PROPAGATION_SUPPORTS<br><br>附B Spring中所有的隔离{略Q?br><br>ISOLATION_DEFAULT<br>ISOLATION_READ_UNCOMMITED<br>ISOLATION_COMMITED<br>ISOLATION_REPEATABLE_READ<br>ISOLATION_SERIALIZABLE<img src ="http://www.tkk7.com/DenisLing/aggbug/22096.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/DenisLing/" target="_blank">DenisLing</a> 2005-12-01 11:47 <a href="http://www.tkk7.com/DenisLing/archive/2005/12/01/22096.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>webwork开发团队加入StrutsQ吃惊)http://www.tkk7.com/DenisLing/archive/2005/11/28/21596.htmlDenisLingDenisLingMon, 28 Nov 2005 00:47:00 GMThttp://www.tkk7.com/DenisLing/archive/2005/11/28/21596.htmlhttp://www.tkk7.com/DenisLing/comments/21596.htmlhttp://www.tkk7.com/DenisLing/archive/2005/11/28/21596.html#Feedback6http://www.tkk7.com/DenisLing/comments/commentRss/21596.htmlhttp://www.tkk7.com/DenisLing/services/trackbacks/21596.html早上一q来看到下面的新L觉惊讶的要死Q不知道和我一样在struts和webwork之间一直在徘徊的朋友们看了׃么感觉。本来我的态度是想慢慢攑ּstruts的…?看样子要重新看待struts了。原文如下:

WebWork joining Struts


Yes, . The WebWork development team (Jason and I) have been working with the Struts development team (Don Brown and Ted Husted) and have come to the conclusion that the best thing for Java community would be to merge WebWork in to Struts.

Read Ted's email here, but the gist of it is this: WebWork is a great technology, and Struts is a great community. It's a perfect match and bringing the two together will only be better for WebWork and Struts users alike. The only down side for me is that I'll be working less with OpenSymphony, but I believe that is a small price for all the great benefits that come from this merger.

Just to be clear, WebWork is not going away. WebWork 2.2 is still coming out any day now, and there may even be a WebWork 2.3. But new minor/major versions won't be coming out under the WebWork name for much longer. Instead, they will be released under the Struts incubator program with the intent to eventually become Struts Action Framework 2.0.

So don't worry, WebWork 2.1.8, 2.2.1, and other bug fix releases will continue to come out and we will support the WebWork community as long as needed. In addition, we'll make compatibility with both Struts and WebWork a high priority, so future releases may help with that. To be clear: no one is leaving WebWork and it will continue to be supported for a very long time.

With this renewed energy, larger development team, and larger community, the combined efforts of Struts and WebWork will surely make the Struts platform the easiest, fastest, and most powerful Java web framework available. We hope that all the WebWork users and developers are as excited about this as we are and are ready to take WebWork to the next level.

原文地址Qhttp://www.opensymphony.com/webwork/

以前一直在struts和webwork之间犹UQ看来struts气数未尽呀。apachel织q是比较只值得信赖的。呵?



DenisLing 2005-11-28 08:47 发表评论
]]>
自定义标{获取struts中action的全部\径(原创Q?/title><link>http://www.tkk7.com/DenisLing/archive/2005/11/21/20781.html</link><dc:creator>DenisLing</dc:creator><author>DenisLing</author><pubDate>Mon, 21 Nov 2005 07:52:00 GMT</pubDate><guid>http://www.tkk7.com/DenisLing/archive/2005/11/21/20781.html</guid><wfw:comment>http://www.tkk7.com/DenisLing/comments/20781.html</wfw:comment><comments>http://www.tkk7.com/DenisLing/archive/2005/11/21/20781.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/DenisLing/comments/commentRss/20781.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/DenisLing/services/trackbacks/20781.html</trackback:ping><description><![CDATA[      ׃目里面由需要一个form可以提交多个actionQ本来可以用 dispatch值来实现Q后来考虑到要使用validator框架验证Q。后来考虑的方案ؓ使用js来控制form的流向,例如<br>        <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">form.action</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">'/bookstore/checkId.</span><span style="color: rgb(0, 0, 255);">do</span><span style="color: rgb(0, 0, 0);">'</span></div> <br> 不过新的问题来了Q如何能不用hardcode而拿到我要的action的实际\径呢Q比如我定义的struts-config文g里面的action?nbsp; <br> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">path</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">/checkId</span><span style="color: rgb(0, 0, 0);">"</span></div> 但是实际解释后的path是:<br> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">actionQ?</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">bookstore</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">checkId.</span><span style="color: rgb(0, 0, 255);">do</span><span style="color: rgb(0, 0, 0);">'</span></div> ? ~和后面的后缀.do都是Ҏ你的目部v的\径和你在web.xml中配|的mapping的后~有关p,如果我把内容写死到jsp中那以后我要是想? checkId.doҎcheckId.action那就要更改jspQ由于struts本来提供的几个taglib里面?br> <br> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">html:form action</span><span style="color: rgb(0, 0, 0);">="</span><span style="color: rgb(0, 0, 0);">/checkId"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">></span></div> <br> l合了一下决定还是自己写个taglib来实玎ͼ其实只需要照着struts 中的 FormTag.java 文g依葫芦画瓢就可以了,一下ؓ本h的代码部?br> <br> StrutsActionCustomTag.java<br> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);"> com.denis.framework.common.taglib.strutsActionExt;<br><br></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> javax.servlet.http.HttpServletResponse;<br></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> javax.servlet.jsp.JspException;<br></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> javax.servlet.jsp.tagext.TagSupport;<br><br></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.apache.struts.taglib.TagUtils;<br><br><img id="Codehighlighter1_288_1030_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_288_1030_Closed_Text.style.display='none'; Codehighlighter1_288_1030_Open_Image.style.display='inline'; Codehighlighter1_288_1030_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> StrutsActionCustomTag </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> TagSupport </span><span id="Codehighlighter1_288_1030_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_288_1030_Open_Text"><span style="color: rgb(0, 0, 0);">{<br><br>    </span><span style="color: rgb(0, 0, 255);">protected</span><span style="color: rgb(0, 0, 0);"> String actionName </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br>    <br><img id="Codehighlighter1_370_394_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_370_394_Closed_Text.style.display='none'; Codehighlighter1_370_394_Open_Image.style.display='inline'; Codehighlighter1_370_394_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedSubBlock.gif" align="top">    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> String getActionName() </span><span id="Codehighlighter1_370_394_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_370_394_Open_Text"><span style="color: rgb(0, 0, 0);">{<br>        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> actionName;<br>    }</span></span><span style="color: rgb(0, 0, 0);"><br><br><img id="Codehighlighter1_443_478_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_443_478_Closed_Text.style.display='none'; Codehighlighter1_443_478_Open_Image.style.display='inline'; Codehighlighter1_443_478_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedSubBlock.gif" align="top">    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> setActionName(String actionName) </span><span id="Codehighlighter1_443_478_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_443_478_Open_Text"><span style="color: rgb(0, 0, 0);">{<br>        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.actionName </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> actionName;<br>    }</span></span><span style="color: rgb(0, 0, 0);"><br><br><img id="Codehighlighter1_526_934_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_526_934_Closed_Text.style.display='none'; Codehighlighter1_526_934_Open_Image.style.display='inline'; Codehighlighter1_526_934_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedSubBlock.gif" align="top">    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> doStartTag() </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> JspException </span><span id="Codehighlighter1_526_934_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_526_934_Open_Text"><span style="color: rgb(0, 0, 0);">{<br><br>        StringBuffer results </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> StringBuffer();<br>        HttpServletResponse response </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"><br>            (HttpServletResponse) </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.pageContext.getResponse();<br>        <br>        results.append(response.encodeURL( TagUtils.getInstance().getActionMappingURL( </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.actionName , </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.pageContext)) );<br><br>        TagUtils.getInstance().write(pageContext, results.toString());<br><br>        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> (EVAL_BODY_INCLUDE);<br>    }</span></span><span style="color: rgb(0, 0, 0);"><br><br><img id="Codehighlighter1_963_1028_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_963_1028_Closed_Text.style.display='none'; Codehighlighter1_963_1028_Open_Image.style.display='inline'; Codehighlighter1_963_1028_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedSubBlock.gif" align="top">    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> release() </span><span id="Codehighlighter1_963_1028_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_963_1028_Open_Text"><span style="color: rgb(0, 0, 0);">{<br>        </span><span style="color: rgb(0, 0, 255);">super</span><span style="color: rgb(0, 0, 0);">.release();<br>        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.actionName </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> ;<br><br>    }</span></span><span style="color: rgb(0, 0, 0);"><br>}</span></span></div> <br> <br> tld定义部分<br> <br> framework-struts.tld<br> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 255);"><?</span><span style="color: rgb(255, 0, 255);">xml version="1.0" encoding="UTF-8"</span><span style="color: rgb(0, 0, 255);">?></span><span style="color: rgb(0, 0, 0);"><br><br></span><span style="color: rgb(0, 0, 255);"><!</span><span style="color: rgb(255, 0, 255);">DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">taglib</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br><br></span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">tlibversion</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">1.0</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">tlibversion</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    <</span><span style="color: rgb(128, 0, 0);">jspversion</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">1.1</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">jspversion</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    <</span><span style="color: rgb(128, 0, 0);">shortname</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">framework</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">shortname</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    <</span><span style="color: rgb(128, 0, 0);">uri</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">http://www.denisFramework.org/Framework-Tag</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">uri</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    <</span><span style="color: rgb(128, 0, 0);">tag</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    <</span><span style="color: rgb(128, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">getActionUrl</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    <</span><span style="color: rgb(128, 0, 0);">tagclass</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">com.denis.framework.common.taglib.strutsActionExt.StrutsActionCustomTag</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">tagclass</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    <</span><span style="color: rgb(128, 0, 0);">bodycontent</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">empty</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">bodycontent</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    <</span><span style="color: rgb(128, 0, 0);">attribute</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">         <</span><span style="color: rgb(128, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">actionName</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">         <</span><span style="color: rgb(128, 0, 0);">required</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">required</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">         <</span><span style="color: rgb(128, 0, 0);">rtexprvalue</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">rtexprvalue</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">    </</span><span style="color: rgb(128, 0, 0);">attribute</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">tag</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br><br></span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">taglib</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br><br><br> </span></div> <br> ok ! 直接在jsp中如下用即可取到action的真正\?br> <br> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);"> <br><img id="Codehighlighter1_4_25_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_4_25_Closed_Text.style.display='none'; Codehighlighter1_4_25_Open_Image.style.display='inline'; Codehighlighter1_4_25_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);"><%</span><span id="Codehighlighter1_4_25_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_4_25_Open_Text"><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">@ page language</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">java</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span></span><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);">%></span><span style="color: rgb(0, 0, 0);"><br><img id="Codehighlighter1_31_101_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_31_101_Closed_Text.style.display='none'; Codehighlighter1_31_101_Open_Image.style.display='inline'; Codehighlighter1_31_101_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);"><%</span><span id="Codehighlighter1_31_101_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_31_101_Open_Text"><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">@ taglib uri</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">http://jakarta.apache.org/struts/tags-bean</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);"> prefix</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">bean</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span></span><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);">%></span><span style="color: rgb(0, 0, 0);"> <br><img id="Codehighlighter1_108_178_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_108_178_Closed_Text.style.display='none'; Codehighlighter1_108_178_Open_Image.style.display='inline'; Codehighlighter1_108_178_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);"><%</span><span id="Codehighlighter1_108_178_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_108_178_Open_Text"><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">@ taglib uri</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">http://jakarta.apache.org/struts/tags-html</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);"> prefix</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">html</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span></span><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);">%></span><span style="color: rgb(0, 0, 0);"><br><img id="Codehighlighter1_184_247_Closed_Image" style="display: none;" onclick="this.style.display='none'; Codehighlighter1_184_247_Closed_Text.style.display='none'; Codehighlighter1_184_247_Open_Image.style.display='inline'; Codehighlighter1_184_247_Open_Text.style.display='inline';" src="../../Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);"><%</span><span id="Codehighlighter1_184_247_Closed_Text" style="border: 1px solid rgb(128, 128, 128); display: none; background-color: rgb(255, 255, 255);"><img src="../../Images/dot.gif"></span><span id="Codehighlighter1_184_247_Open_Text"><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">@ taglib uri</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">/WEB-INF/framework-struts.tld</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);"> prefix</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">=</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">framework</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);">"</span><span style="color: rgb(0, 0, 0); background-color: rgb(245, 245, 245);"> </span></span><span style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 0);">%></span><span style="color: rgb(0, 0, 0);"><br> <br></span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">html</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"> <br>    </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">head</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br>        </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">title</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">JSP for loginForm form</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">title</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br>    </span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">head</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br>    </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">body</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br>        </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">framework:getActionUrl </span><span style="color: rgb(255, 0, 0);">actionName</span><span style="color: rgb(0, 0, 255);">="login"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/></span><span style="color: rgb(0, 0, 0);"><br>        </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">html:form </span><span style="color: rgb(255, 0, 0);">action</span><span style="color: rgb(0, 0, 255);">="/login"</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br>            name : </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">html:text </span><span style="color: rgb(255, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">="name"</span><span style="color: rgb(0, 0, 255);">/><</span><span style="color: rgb(128, 0, 0);">html:errors </span><span style="color: rgb(255, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">="name"</span><span style="color: rgb(0, 0, 255);">/><</span><span style="color: rgb(128, 0, 0);">br</span><span style="color: rgb(0, 0, 255);">/></span><span style="color: rgb(0, 0, 0);"><br>            password : </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">html:password </span><span style="color: rgb(255, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">="password"</span><span style="color: rgb(0, 0, 255);">/><</span><span style="color: rgb(128, 0, 0);">html:errors </span><span style="color: rgb(255, 0, 0);">property</span><span style="color: rgb(0, 0, 255);">="password"</span><span style="color: rgb(0, 0, 255);">/><</span><span style="color: rgb(128, 0, 0);">br</span><span style="color: rgb(0, 0, 255);">/></span><span style="color: rgb(0, 0, 0);"><br>            </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">html:submit</span><span style="color: rgb(0, 0, 255);">/><</span><span style="color: rgb(128, 0, 0);">html:cancel</span><span style="color: rgb(0, 0, 255);">/></span><span style="color: rgb(0, 0, 0);"><br>        </span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">html:form</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br>    </span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">body</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">html</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br><br> </span></div> <br> <br> 大家要是有更好的解决Ҏ希望能指正!谢谢Q?img src ="http://www.tkk7.com/DenisLing/aggbug/20781.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/DenisLing/" target="_blank">DenisLing</a> 2005-11-21 15:52 <a href="http://www.tkk7.com/DenisLing/archive/2005/11/21/20781.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Spring 更好地处?Struts 动作 (转自ibm 个h感觉受益非浅)http://www.tkk7.com/DenisLing/archive/2005/11/21/20779.htmlDenisLingDenisLingMon, 21 Nov 2005 07:42:00 GMThttp://www.tkk7.com/DenisLing/archive/2005/11/21/20779.htmlhttp://www.tkk7.com/DenisLing/comments/20779.htmlhttp://www.tkk7.com/DenisLing/archive/2005/11/21/20779.html#Feedback2http://www.tkk7.com/DenisLing/comments/commentRss/20779.htmlhttp://www.tkk7.com/DenisLing/services/trackbacks/20779.htmlStruts Recipes 的合著?George Franciscus 介l另一个重大的 Struts 整合H门 —?q次是将 Struts 应用E序导入 Spring 框架。请跟随 GeorgeQ他向您展C如何改? Struts 动作Q得管?Struts 动作像理 Spring beans 那样。结果是一个增强的 web 框架Q这个框架可以方便地利用 Spring AOP 的优ѝ?/font>

您肯定已l听说过控制反{ (IOC) 设计模式Q因为很长一D|间以来一直在传关于它的信息。如果您在Q何功能中使用q?Spring 框架Q那么您q道其原理的作用。在本文中,我利用这一原理把一?Struts 应用E序注入 Spring 框架Q您亲w体会到 IOC 模式的强大?/font>

一?Struts 应用E序整合q?Spring 框架h多方面的优点。首先,Spring 是ؓ解决一些关? JEE 的真实世界问题而设计的Q比如复杂性、低性能和可试性,{等。第二,Spring 框架包含一?AOP 实现Q允许您面向方面技术应用于面向对象的代码。第三,一些h可能会说 Spring 框架只有处理 Struts ?Struts 处理自己好。但是这是观炚w题,我演CZU将 Struts 应用E序整合?Spring 框架的方法后Q具体由您自己决定用哪一U?/font>

我所演示的方法都是执行v来相对简单的Q但是它们却h明显不同的优炏V我为每一U方法创Z一个独立而可用的例子Q这h可以完全理解每U方法? 请参?下蝲 部分获得完整例子源代码。请参阅 参考资?/a>Q下?Struts MVC ?Spring 框架?/font>

Z?Spring q么了不P

Spring 的创立?Rod Johnson 以一U批判的眼光看待 Java?企业软g开发,q且提议很多企业N都能够通过战略C?IOC 模式Q也UC依赖注入Q来解决。当 Rod 和一个具有奉献精的开放源码开发者团队将q个理论应用于实跉|Q结果就产生?Spring 框架。简a之,Spring 是一个轻型的容器Q利用它可以使用一个外?XML 配置文g方便地将对象q接在一赗每个对象都可以通过昄一? JavaBean 属性收C个到依赖对象的引用,留给您的单Q务就只是在一?XML 配置文g中把它们q接好?/font>

IOC ?Spring

IOC 是一U应用E序逻辑外在化的设计模式Q所以它是被注入而不是被写入客户Z码中。将 IOC 与接口编E应用结合,像 Spring 框架那样Q生了一U架构,q种架构能够减少客户机对特定实现逻辑的依赖。请参阅 参考资?/a> 了解更多关于 IOC ?Spring 的信息?/font>

? 赖注入是一个强大的Ҏ,但是 Spring 框架能够提供更多Ҏ。Spring 支持可插拔的事务理器,可以l您的事务处理提供更q泛的选择范围。它集成了领先的持久性框Ӟq且提供一个一致的异常层次l构。Spring q提供了一U用面向方面代码代替正常的面向对象代码的简单机制?/font>

Spring AOP 允许您?i>拦截?/i> 在一个或多个执行点上拦截应用E序逻辑。加强应用程序在拦截器中的日志记录逻辑会生一个更可读的、实用的代码基础Q所以拦截器q泛用于日志记录。您很快׃看到Qؓ了处理横切关注点QSpring AOP 发布了它自己的拦截器Q您也可以编写您自己的拦截器?/font>





整合 Struts ?Spring

? Struts 怼QSpring 可以作ؓ一?MVC 实现。这两种框架都具有自q优点和缺点,管大部分h同意 Struts ?MVC 斚w仍然是最好的。很多开发团队已l学会在旉紧迫的时候利?Struts 作ؓ构造高品质软g的基。Struts h如此大的推动力,以至于开发团队宁愿整?Spring 框架的特性,而不愿意转换?Spring MVC。没必要q行转换Ҏ来说是一个好消息。Spring 架构允许您将 Struts 作ؓ Web 框架q接到基?Spring 的业务和持久层。最后的l果是现在一切条仉具备了?/font>

在接下来的小H门中,您将会了解到三种?Struts MVC 整合?Spring 框架的方法。我揭C每U方法的~陷q且Ҏ它们的优炏V?一旦您了解到所有三U方法的作用Q我会向您展示一个o人兴奋的应用E序Q这个程序用的是这三种Ҏ中我最喜欢的一U?/font>





三个窍?/span>

接下来的每种整合技术(或者窍门)都有自己的优点和特点。我偏爱其中的一U,但是我知道这三种都能够加深您?Struts ?Spring 的理解。在处理各种不同情况的时候,q将l您提供一个广阔的选择范围。方法如下:

  • 使用 Spring ?ActionSupport cL?Structs
  • 使用 Spring ?DelegatingRequestProcessor 覆盖 Struts ? RequestProcessor
  • ?Struts Action 理委托l?Spring 框架

装蝲应用E序环境

无论您用哪U技术,都需要?Spring ?ContextLoaderPlugin ?Struts ?ActionServlet 装蝲 Spring 应用E序环境。就像添加Q何其他插件一P单地向您?struts-config.xml 文gd该插Ӟ如下所C:


<plug-in className=
"org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property=
"contextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>


前面已经提到q,?下蝲 部分Q您能够扑ֈq三个完全可使用的例子的完整源代码。每个例子都Z个书c搜索应用程序提供一U不同的 Struts ?Spring 的整合方法。您可以在这里看C子的要点Q但是您也可以下载应用程序以查看所有的l节?/font>





H门 1. 使用 Spring ?ActionSupport

手动创徏一?Spring 环境是一U整?Struts ?Spring 的最直观的方式。ؓ了它变得更单,Spring 提供了一些帮助。ؓ了方便地获得 Spring 环境Q?font size="3">org.springframework.web.struts.ActionSupport cL供了一?getWebApplicationContext() Ҏ。您所做的只是?Spring ?ActionSupport 而不?font size="3"> Struts Action cL展您的动作,如清?1 所C:


清单 1. 使用 ActionSupport 整合 Struts

package ca.nexcel.books.actions;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import org.springframework.context.ApplicationContext;
import org.springframework.web.struts.ActionSupport;

import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;

public class SearchSubmit extends ActionSupport { |(1)


public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {

DynaActionForm searchForm = (DynaActionForm) form;
String isbn = (String) searchForm.get("isbn");

//the old fashion way
//BookService bookService = new BookServiceImpl();

ApplicationContext ctx =
getWebApplicationContext(); |(2)
BookService bookService =
(BookService) ctx.getBean("bookService"); |(3)

Book book = bookService.read(isbn.trim());

if (null == book) {
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError
("message.notfound"));
saveErrors(request, errors);
return mapping.findForward("failure") ;
}

request.setAttribute("book", book);
return mapping.findForward("success");
}
}


让我们快速思考一下这里到底发生了什么。在 (1) 处,我通过?Spring ?ActionSupport c而不?Struts ?Action c进行扩展,创徏了一个新?Action?/font>?(2) 处,我?getWebApplicationContext() Ҏ获得一?ApplicationContext?/font>Z获得业务服务Q我使用?(2) 处获得的环境?(3) 处查找一?Spring bean?/font>

q? U技术很单ƈ且易于理解。不q的是,它将 Struts 动作?Spring 框架耦合在一赗如果您x换掉 SpringQ那么您必须重写代码。ƈ且,׃ Struts 动作不在 Spring 的控制之下,所以它不能获得 Spring AOP 的优ѝ当使用多重独立?Spring 环境Ӟq种技术可能有用,但是在大多数情况下,q种Ҏ不如另外两种Ҏ合适?/font>





H门 2. 覆盖 RequestProcessor

?Spring ?Struts 动作中分L一个更巧妙的设计选择。分ȝ一U方法是使用 org.springframework.web.struts.DelegatingRequestProcessor cL覆盖 Struts ?font size="3"> RequestProcessor 处理E序Q如清单 2 所C:


清单 2. 通过 Spring ?DelegatingRequestProcessor q行整合

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
<form-beans>
<form-bean name="searchForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="isbn" type="java.lang.String"/>
</form-bean>

</form-beans>

<global-forwards type="org.apache.struts.action.ActionForward">
<forward name="welcome" path="/welcome.do"/>
<forward name="searchEntry" path="/searchEntry.do"/>
<forward name="searchSubmit" path="/searchSubmit.do"/>
</global-forwards>

<action-mappings>
<action path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
<action path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
<action path="/searchSubmit"
type="ca.nexcel.books.actions.SearchSubmit"
input="/searchEntry.do"
validate="true"
name="searchForm">
<forward name="success" path="/WEB-INF/pages/detail.jsp"/>
<forward name="failure" path="/WEB-INF/pages/search.jsp"/>
</action>

</action-mappings>

<message-resources parameter="ApplicationResources"/>

<controller processorClass="org.springframework.web.struts.
DelegatingRequestProcessor"/> |(1)

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>


<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="csntextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>

</struts-config>


我利用了 <controller> 标记来用 DelegatingRequestProcessor 覆盖默认?Struts RequestProcessor?/font>下一步是在我?Spring 配置文g中注册该动作Q如清单 3 所C:


清单 3. ?Spring 配置文g中注册一个动?/b>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>

<bean name="/searchSubmit"
class="ca.nexcel.books.actions.SearchSubmit"> |(1)
<property name="bookService">
<ref bean="bookService"/>
</property>
</bean>
</beans>


注意Q在 (1) 处,我用名U属性注册了一?beanQ以匚w struts-config 动作映射名称?code>SearchSubmit 动作揭示了一?JavaBean 属性,允许 Spring 在运行时填充属性,如清?4 所C:


清单 4. h JavaBean 属性的 Struts 动作

package ca.nexcel.books.actions;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;

import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;

public class SearchSubmit extends Action {

private BookService bookService;
public BookService getBookService() {
return bookService;
}

public void setBookService(BookService bookService) { | (1)
this.bookService = bookService;
}

public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {

DynaActionForm searchForm = (DynaActionForm) form;
String isbn = (String) searchForm.get("isbn");

Book book = getBookService().read(isbn.trim()); |(2)

if (null == book) {
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound"));
saveErrors(request, errors);
return mapping.findForward("failure") ;
}

request.setAttribute("book", book);
return mapping.findForward("success");
}

}


在清?4 中,您可以了解到如何创徏 Struts 动作。在 (1) 处,我创Z一?JavaBean 属性?code>DelegatingRequestProcessor? 动地配置q种属性。这U设计 Struts 动作q不知道它正?Spring 理Qƈ且您能够利?Sping 的动作管理框架的所有优炏V由于您?Struts 动作注意不到 Spring 的存在,所以您不需要重写您?Struts 代码可以用其他控制反转容器来替换?Spring?/font>

DelegatingRequestProcessor Ҏ的确比第一U方法好Q但是仍然存在一些问题。如果您使用一个不同的 RequestProcessorQ?/font>则需要手动整?Spring ?DelegatingRequestProcessor?/font>d的代码会造成l护的麻烦ƈ且将来会降低您的应用E序的灵zL。此外,q有q一些用一pd命o来代?Struts RequestProcessor 的传闅R?q种改变会对这U解x法的使用寿命造成负面的媄响?/font>





H门 3. 动作管理委托给 Spring

一个更好的解决Ҏ是将 Strut 动作理委托l?Spring。您可以通过?struts-config 动作映射中注册一个代理来实现。代理负责在 Spring 环境中查?Struts 动作。由于动作在 Spring 的控制之下,所以它可以填充动作?JavaBean 属性,qؓ应用诸如 Spring ?AOP 拦截器之cȝҎ带来了可能?

清单 5 中的 Action cM清单 4 中的相同。但?struts-config 有一些不同:


清单 5. Spring 整合的委托方?/b>

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
<form-beans>
<form-bean name="searchForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="isbn" type="java.lang.String"/>
</form-bean>

</form-beans>

<global-forwards type="org.apache.struts.action.ActionForward">
<forward name="welcome" path="/welcome.do"/>
<forward name="searchEntry" path="/searchEntry.do"/>
<forward name="searchSubmit" path="/searchSubmit.do"/>
</global-forwards>

<action-mappings>
<action path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
<action path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
<action path="/searchSubmit"
type="org.springframework.web.struts.DelegatingActionProxy" |(1)
input="/searchEntry.do"
validate="true"
name="searchForm">
<forward name="success" path="/WEB-INF/pages/detail.jsp"/>
<forward name="failure" path="/WEB-INF/pages/search.jsp"/>
</action>

</action-mappings>

<message-resources parameter="ApplicationResources"/>


<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>


<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>


</struts-config>


清单 5 是一个典型的 struts-config.xml 文gQ只有一个小的差别。它注册 Spring 代理cȝ名称Q而不是声明动作的cdQ如Q?Q处所C。DelegatingActionProxy cM用动作映名U查?Spring 环境中的动作。这是我们使用 ContextLoaderPlugIn 声明的环境?/font>

一?Struts 动作注册Z?Spring bean 是非常直观的Q如清单 6 所C。我利用动作映射使用 <bean> 标记的名U属性(在这个例子中?"/searchSubmit"Q简单地创徏了一?bean。这个动作的 JavaBean 属性像M Spring bean 一栯填充Q?


清单 6. ?Spring 环境中注册一?Struts 动作

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>

<bean name="/searchSubmit"
class="ca.nexcel.books.actions.SearchSubmit">
<property name="bookService">
<ref bean="bookService"/>
</property>
</bean>

</beans>






动作委托的优?/span>

动作委托解决Ҏ是这三种Ҏ中最好的。Struts 动作不了?SpringQ不对代码作M改变可用于?Spring 应用E序中?font size="3">RequestProcessor 的改变不会媄响它Qƈ且它可以利用 Spring AOP Ҏ的优点?

动作委托的优点不止如此。一旦让 Spring 控制您的 Struts 动作Q您可以?Spring l动作补充更强的zd。例如,没有 Spring 的话Q所有的 Struts 动作都必LU程安全的。如果您讄 <bean> 标记?singleton 属性ؓ“false”,那么不管用何U方法,您的应用E序都将在每一个请求上有一个新生成的动作对象。您可能不需要这U特性,但是把它攑֜您的工具׃? 很好。您也可以利?Spring 的生命周期方法。例如,当实例化 Struts 动作Ӟ<bean> 标记?init-method 属性被用于q行一个方法。类似地Q在从容器中删除 bean 之前Qdestroy-method 属性执行一个方法。这些方法是理昂贵对象的好办法Q它们以一U与 Servlet 生命周期相同的方式进行管理?/font>





拦截 Struts

? 面提到过Q通过?Struts 动作委托l?Spring 框架而整?Struts ?Spring 的一个主要的优点是:您可以将 Spring ?AOP 拦截器应用于您的 Struts 动作。通过?Spring 拦截器应用于 Struts 动作Q您可以用最的代h处理横切x炏V?/font>

虽然 Spring 提供很多内置拦截器,但是我将向您展示如何创徏自己的拦截器q把它应用于一?Struts 动作。ؓ了用拦截器Q您需要做三g事:

  1. 创徏拦截器?/font>
  2. 注册拦截器?/font>
  3. 声明在何处拦截代码?/font>

q看h非常单的几句话却非常强大。例如,在清?7 中,我ؓ Struts 动作创徏了一个日志记录拦截器? q个拦截器在每个Ҏ调用之前打印一句话Q?/font>


清单 7. 一个简单的日志记录拦截?/b>

package ca.nexcel.books.interceptors;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class LoggingInterceptor implements MethodBeforeAdvice {

public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("logging before!");
}
}


q个拦截器非常简单?code>before() Ҏ在拦截点中每个方法之前运行。在本例中,它打印出一句话Q其实它可以做您惛_的Q何事。下一步就是在 Spring 配置文g中注册这个拦截器Q如清单 8 所C:


清单 8. ?Spring 配置文g中注册拦截器

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>

<bean name="/searchSubmit"
class="ca.nexcel.books.actions.SearchSubmit">
<property name="bookService">
<ref bean="bookService"/>
</property>
</bean>

<!-- Interceptors -->
<bean name="logger"
class="ca.nexcel.books.interceptors.LoggingInterceptor"/> |(1)

<!-- AutoProxies -->
<bean name="loggingAutoProxy"
class="org.springframework.aop.framework.autoproxy.
BeanNameAutoProxyCreator"> |(2)
<property name="beanNames">
<value>/searchSubmit</valuesgt; |(3)
</property>
<property name="interceptorNames">
<list>
<value>logger</value> |(4)
</list>
</property>
</bean>

</beans>


您可能已l注意到了,清单 8 扩展?清单 6 中所C的应用E序以包含一个拦截器。具体细节如下:

  • ?(1) 处,我注册了q个拦截器?/font>
  • ?(2) 处,我创Z一?bean 名称自动代理Q它描述如何应用拦截器。还有其他的Ҏ定义拦截点,但是q种Ҏ常见而简ѝ?/font>
  • ?(3) 处,我将 Struts 动作注册为将被拦截的 bean。如果您惌拦截其他?Struts 动作Q则只需要在 "beanNames" 下面创徏附加?<value> 标记?/font>
  • ?(4) 处,当拦截发生时Q我执行了在 (1) 处创建的拦截?bean 的名U。这里列出的所有拦截器都应用于“beanNames”?/font>

是q样。就像这个例子所展示的,您?Struts 动作|于 Spring 框架的控制之下,为处理您?Struts 应用E序提供了一pd全新的选择。在本例中,使用动作委托可以L地利?Spring 拦截器提?Struts 应用E序中的日志记录能力?/font>





l束?/span>

在本文中Q您已经学习了将 Struts 动作整合?Spring 框架中的三种H门。?Spring ?ActionSupport 来整?StrutsQ第一U窍门中是q样做的Q简单而快P但是会将 Struts 动作?Spring 框架耦合在一赗如果您需要将应用E序ULC个不同的框架Q则需要重写代码。第二种解决Ҏ通过委托 RequestProcessor 巧妙地解开代码的耦合Q但是它的可扩展性不强,q且?Struts ?RequestProcessor 变成一pd命oӞq种Ҏ持l不了很长时间。第三种Ҏ是这三种Ҏ中最好的Q将 Struts 动作委托l?Spring 框架可以使代码解耦,从而您可以在您的 Struts 应用E序中利?Spring 的特性(比如日志记录拦截器)?/p>

三种 Struts-Spring 整合H门中的每一U都被实现成一个完整可用的应用E序。请参阅 下蝲 部分仔细研究它们?/font>






下蝲
描述名字大小 下蝲Ҏ
ActionSupport sample codej-sr2-actionsupport.zip5 MB  FTP
RequestProcessor sample codej-sr2-requestprocessor.zip5 MB  FTP
Delegate sample codej-sr2-delegate.zip5 MB  FTP


DenisLing 2005-11-21 15:42 发表评论
]]>
վ֩ģ壺 ݺȾƷѹۿ| ѿƬAëƬѿ| ŮƵ| ŮƵ| 97ۺɫ| ѵһƬվ| avþþþòվ| aɫëƬѲƵ| ѿŮҹƬ| ۺһ| þAV| ˾޾ƷӰwww| ֳִˬƵ| ĻѸ | ƵĻ| Ʒ޾Ʒպѷ| Ļ| Ů18ëƬaëƬ| 99ƵѹۿƵ| ޸߹ۿ| þþƷרѶ| ѨƬ߹ۿ| ɫAëƬѿ| ɫƵۿһ| þþƷAVӰ| ҹ޹Ƭ̨| պAV뾫Ʒ| AV˵߹ۿ| һavĻ| Ļ뾫ƷԴþ| պ˳վ| AVĻ| ޾Ʒsuvһ88| ŷAVר| ޳aƬ߹ۿ| avۺavһ| AV˾Ʒպ| ޾ƷƷƷ| һësuvÿĹվ| h߿Ƶվ| ĻƵ|