??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲乱亚洲乱妇无码,亚洲色偷偷偷鲁综合,亚洲日本国产乱码va在线观看http://www.tkk7.com/jinfeng_wang/category/1002.htmlG-G-S,D-D-U!zh-cnFri, 16 Apr 2010 12:45:10 GMTFri, 16 Apr 2010 12:45:10 GMT60|络服务器设计的模型及一些设计方法zzhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318495.htmljinfeng_wangjinfeng_wangFri, 16 Apr 2010 03:36:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318495.htmlhttp://www.tkk7.com/jinfeng_wang/comments/318495.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2010/04/16/318495.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/318495.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/318495.html http://blog.csdn.net/proad/archive/2008/04/16/2296925.aspx


1. 常用服务器模?/strong>
a.q代服务器:只有一个进E?U程处理h。一般ؓ单进E?加上select多\复用,非阻塞socket?br /> b.q代/q发混合型服务器Q^时P代处理,Ҏ耗大的请求ƈ发处理。处理请求时讄一个超Ӟ当请求的处理旉时Ӟ创徏一个进E?U程Q把处理转给新的q程/U程处理Q主q程/U程l箋处理其他h?br /> c.q发服务器:多个q程/U程q发处理h?/p>

2. 以上三类的服务器比较
q代服务器:最单,性能不高?br /> q发服务器:性能较高Q但l构相对比较复杂Q开发难度中{?br /> q代/q发混合型服务器Q性能不错Q但l构通常比单U的q发服务器更复杂?/p>

3. 多进E的q发服务?/strong>
a. 每个q接fork一个进E:主进Eaccpetq接Q有新连接到来时fork一个进E,然后l箋acceptQ等待新的连接。数据传输由子进E处理,处理完后子进Eexit。每个子q程只处理一个连接?br /> b. Preforkq程Q主q程预先fork一些进E,各个子进E竞争acceptQ然后处理数据传输。一个子q程可以处理一个连接,也可以同时处理多个连接(通过select{)?br /> c. Preforkq程Q由父进EaccepthQ通过管道{发fd到子q程Q子q程收到fd后,处理数据传输Q处理结束后通知父进E。父q程处理的事情比较简单,Ҏ监控子进E?/p>

以上3U方式性能比较Q?br /> a.每个q接fork一个进E:处理smtp{状态较多,数据量比较大时比较简单实用,M性能不大好?br /> b.Preforkq程Q各个子q程竞争acceptQ比较简单,性能不错?br /> c.Preforkq程Q由父进EaccepthQ通过管道{发fd到子q程Q代码复杂,性能一般不如上一U?/p>

4. 多线E的q发服务?/strong>
a.每个q接一个线E?br /> b.Prethread多个U程Q各个线E互斥accept
c.Prethread多个U程Q主U程acceptq分发连接给子线E?/p>

5. 多进E与多线E的比较
使用U程的模型:性能比用进E要高,但代码比较复杂,对代码质量要求更高,U程出错后可能会影响到所有线E,多进E的模式一个进E出错一般不会媄响其他进E?br /> 多线E模型共享数据比较简单有效,多进E模型共享数据比较麻烦,效率也不如线E?/p>

6. 一些流行的|络服务器采用的模型

Sendmail: 采用多进E,每个q接fork一个进E?
每个q接fork一个子q程
子进E只处理一个连?br /> 子进Efork一个localmailq程Q可以由用户自己~写Q,通过道把数据{llocalmail处理Q把邮g处理业务逻辑独立出来
优点Q结构简单,不用l护复杂的状态机

Apache1.3:采用多进E? preforkq程
子进E竞争acceptQ每ơ只处理一个连?br /> 主进E不acceptQ根据负载情况调整子q程数量
子进E运行一D|间后Q主q程会让它退出,然后创徏一个新的进E,防止内存泄漏{?br /> 主进E通过shared memory监控子进E?/p>

UdQQ: Prefork多个q程Q竞争accept,
典型的一问一{TCP服务器,l构?br /> 每个q程通过select可以同时处理多个q接
采用q种l构的原因有Q?br /> 每秒h<1000Q可以满?br /> l构单,Ҏ开发、维?/p>

jinfeng_wang 2010-04-16 11:36 发表评论
]]>
力_法分?/title><link>http://www.tkk7.com/jinfeng_wang/archive/2010/03/19/315853.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Thu, 18 Mar 2010 16:27:00 GMT</pubDate><guid>http://www.tkk7.com/jinfeng_wang/archive/2010/03/19/315853.html</guid><wfw:comment>http://www.tkk7.com/jinfeng_wang/comments/315853.html</wfw:comment><comments>http://www.tkk7.com/jinfeng_wang/archive/2010/03/19/315853.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jinfeng_wang/comments/commentRss/315853.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jinfeng_wang/services/trackbacks/315853.html</trackback:ping><description><![CDATA[  <p>A)<span style="font-family: 'QS 明朝'">?/span><span style="font-family: SimSun">?/span><span style="font-family: 'QS 明朝'">人民共和?/span><span style="font-family: SimSun">力_</span><span style="font-family: 'QS 明朝'">合同?/span></p> <p><a >http://www.molss.gov.cn/gb/news/2007-06/30/content_184630.htm</a></p> <p>B)<span style="font-family: 'QS 明朝'">?/span><span style="font-family: SimSun">?/span><span style="font-family: 'QS 明朝'">人民共和?/span><span style="font-family: SimSun">力_</span><span style="font-family: 'QS 明朝'">合同?/span><span style="font-family: SimSun">?/span><span style="font-family: 'QS 明朝'">施条?/span><span style="font-family: 'QS 明朝'">(</span><span style="font-family: SimSun">解释力_法实?/span><span style="font-family: 'QS 明朝'">)</span></p> <p><a >http://www.gov.cn/flfg/2008-09/19/content_1099500.htm</a></p> <p>C)<span style="font-family: SimSun">关于立力_关系有关事项的通知</span></p> <p><a >http://www.law-lib.com/law/law_view.asp?id=92395</a></p> <p>D)<span style="font-family: SimSun">上v市女职工力_保护办法</span></p> <p><a >http://www.shanghai.gov.cn/shanghai/node2314/node3124/node3125/node3133/userobject6ai655.html</a></p> <p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">·<span style="font: 7pt 'Times New Roman'">                     </span><strong>C)</strong></span><strong><span style="font-family: SimSun">的相兛_容:</strong></span></p> <p>     <span style="font-family: SimSun">用h单位未与力_者签订劳动合同,<strong><span style="color: red">认定双方存在力_关系</strong>时可参照下列凭证Q?/span></span></p> <p>(<span style="font-family: SimSun">一</span>)<span style="font-family: SimSun">工资支付凭证或记?/span>(<span style="font-family: SimSun">职工工资发放花名?/span>)<span style="font-family: SimSun">、缴U_社会保险费的记录;</span></p> <p>(<span style="font-family: SimSun">?/span>)<span style="font-family: SimSun">用h单位向劳动者发攄<strong><span style="color: red">“工作?#8221;?#8220;服务?#8221;{能够证明n份的证g</strong>Q?/span></span></p> <p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">·<span style="font: 7pt 'Times New Roman'">                     </span><strong>B) </strong></span><strong><span style="font-family: SimSun">的相兛_容:</strong></span></p> <p style="margin-left: 69pt; text-indent: -48pt; tab-stops: list 69.0pt">W六?span style="font: 7pt 'Times New Roman'">        <span style="font-family: SimSun">用h单位自用工之日v<span style="color: blue">过一个月不满一q?/span>未与力_者订立书面劳动合同的Q应当依?span style="color: blue">力_合同法第八十二条的规定向力_者每月支付两倍的工资Qƈ与劳动者补订书面劳动合?/span>Q劳动者不与用人单位订立书面劳动合同的Q用人单位应当书面通知力_者终止劳动关p,<span style="color: blue">q依照劳动合同法W四十七条的规定支付l济补偿</span>?/span></span><strong><span style="color: red">(1</strong></span><strong><span style="color: red; font-family: SimSun">Q相当于l?/strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">倍工资,</strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">Q补合同Q?/strong></span><strong><span style="color: red">3</strong></span><strong><span style="color: red; font-family: SimSun">Q如果辞退Q再按照有合同补偿)</strong></span></p> <p style="margin-left: 21pt"><span style="font-family: SimSun">W二十七条 力_合同法第四十七条规定?strong><span style="color: red">l济补偿的月工资按照力_者应得工资计,包括计时工资或者计件工资以及奖?/strong><span style="color: red">?/span></span></span></p> <p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">·<span style="font: 7pt 'Times New Roman'">                     </span><strong>A)</strong></span><strong><span style="font-family: SimSun">的相兛_容:</strong></span></p> <p>     <span style="font-family: SimSun">W四十二条 力_者有下列情Ş之一的,用h单位<strong><span style="color: red">不得依照</strong>本法W四十条、第四十一条的规定解除力_合同Q?/span></span></p> <p><strong><span style="color: red">        </strong></span><strong><span style="color: red; font-family: SimSun">Q四Q女职工在孕期、期、哺x?/strong></span></p> <p> <span style="font-family: SimSun"> W四十七条 l济补偿按劳动者在本单位工作的q限Q?strong><span style="color: red">每满一q支付一个月工资的标准向力_者支付。六个月以上不满一q的Q按一q计;</strong>不满六个月的Q向力_者支付半个月工资的经补ѝ?/span></span></p> <p>     <span style="font-family: SimSun">W八十二条 <strong><span style="color: red">用h单位自用工之日v过一个月不满一q未与劳动者订立书面劳动合同的Q应当向力_者每月支付二倍的工资?/strong></span></span></p> <p><strong><span style="color: red">    </strong></span><span style="font-family: SimSun">用h单位q反本法规定不与力_者订?strong><span style="color: red">无固定期限劳动合?/strong>的,自应当订立无固定期限力_合同之日起向力_者每?strong><span style="color: red">支付二倍的工资</span></strong>?/span></span></p> <p><strong><span style="color: red">     </strong></span><span style="font-family: SimSun">W八十七条 用h<strong><span style="color: red">单位q反本法</strong>规定解除或者终止劳动合同的Q应?strong><span style="color: red">依照本法W四十七?/span></strong>规定的经补?strong><span style="color: red">标准的二?/span></strong>向劳动者支付赔偉K?/span></span></p> <p> <span style="font-family: SimSun">W十四条 无固定期限劳动合同,是指用h单位与劳动者约定无定l止旉的劳动合同?/span></p> <p>    <span style="font-family: SimSun">用h单位与劳动者协商一_可以订立无固定期限劳动合同。有下列情Ş之一Q劳动者提出或者同意箋订、订立劳动合同的Q除力_者提立固定期限劳动合同外Q应?strong><span style="color: red">订立无固定期限劳动合?/strong>Q?/span></span></p> <p>    <span style="font-family: SimSun">Q一Q劳动者在该用人单?span style="color: red">q箋<strong>工作满十q?/strong>的;</span></span></p> <p>    <span style="font-family: SimSun">Q二Q用人单位初ơ实行劳动合同制度或者国有企业改刉新订立劳动合同时Q劳动者在该用人单位连l工作满十年且距法定退休年龄不_q的Q?/span></p> <p>    <span style="font-family: SimSun">Q三Q?strong><span style="color: red">q箋订立二次固定期限力_合同</strong>Q且力_者没有本法第三十九条和第四十条第一V第二项规定的情形,l订力_合同的?/span></span></p> <p>    <span style="font-family: SimSun">用h单位<strong><span style="color: red">自用工之日v满一q不与劳动者订立书面劳动合同的Q视为用人单位与力_者已订立无固定期限劳动合?/strong>?/span></span></p> <p><strong> </strong></p> <p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">·<span style="font: 7pt 'Times New Roman'">                     </span><strong>D) </strong></span><strong><span style="font-family: SimSun">的相兛_容:</strong></span></p> <p><span style="font-family: SimSun">W十一?/span><span style="font-family: SimSun">对妊娠期的女职工Q?strong><span style="color: red">不应廉其劳动时?/strong>Q?/span></span></p> <p><span style="font-family: SimSun">W十四条</span><span style="font-family: SimSun">奌工假分别按下列情况执行Q?/span></p> <p>     <span style="font-family: SimSun">Q一Q单胎顺产者,l予<span style="color: red">产假九十天,其中产前休息十五天,产后休息七十五天?/span></span></p> <p><span style="font-family: SimSun">W十五条</span><span style="font-family: SimSun">奌工生育后Q在其婴儿一周岁内应照顾其在每班力_旉?span style="color: red">授^两次Q包括h工喂养)?span style="color: red">每次</span>单胎U授x间ؓ<span style="color: red">三十分钟</span>Q亦可将两次授^旉合ƈ使用。多胞胎生育者,每多生一胎,每次Z^旉增加三十分钟?/span></span></p> <p> <span style="font-family: SimSun">W十八条</span><span style="font-family: SimSun">奌工在<span style="color: red">产假期间的工资照发。按本规定n受的<span style="color: red">产前假和Z^假的工资</span>按本人原工资?span style="color: red">癑ֈ之八十发l?/span>。单位增加工资时Q女职工按规定n受的产前假、假、哺乛_Q应作出勤对待?/span></span></p> <p><strong><span style="color: red">    </strong></span></p> <p style="margin-left: 36pt; text-indent: -36pt; tab-stops: list 0cm"><span style="font-family: Symbol">·<span style="font: 7pt 'Times New Roman'">                     </span><strong><span style="font-family: SimSun">l论Q?/span></strong></span></p> <p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">1Q?span style="font: 7pt 'Times New Roman'">      </span></strong><strong><span style="color: red; font-family: SimSun">认定力_关系Q工作证</span></strong></span></p> <p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">2Q?span style="font: 7pt 'Times New Roman'">      </span></strong><strong><span style="color: red; font-family: SimSun">是否{֐?/span></strong></span></p> <p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">3Q?span style="font: 7pt 'Times New Roman'">      </span></strong><strong><span style="color: red; font-family: SimSun">如果没签合同Q怎么补偿Q?/span></strong></span><span style="color: red">1</span><span style="color: red; font-family: SimSun">Q?strong>相当于给</strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">倍工资,</strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">Q补合同Q?/strong></span><strong><span style="color: red">3</strong></span><strong><span style="color: red; font-family: SimSun">Q如果辞退Q再按照有合同补偿)</strong></span></p> <p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">4Q?span style="font: 7pt 'Times New Roman'">      </span></strong><strong><span style="color: red; font-family: SimSun">如果是固定合同,怎么补偿Q?/span></strong></span><strong><span style="color: red">N+1</strong></span><strong><span style="color: red; font-family: SimSun">Q?/strong></span></p> <p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">5Q?span style="font: 7pt 'Times New Roman'">      </span></strong><strong><span style="color: red; font-family: SimSun">如果是无期合同,</span></strong></span><strong><span style="color: red">2</strong></span><strong><span style="color: red; font-family: SimSun">?/strong></span></p> <p style="margin-left: 36pt; text-indent: -27pt; tab-stops: list 36.0pt"><strong><span style="color: red">6Q?span style="font: 7pt 'Times New Roman'">      </span></strong><strong><span style="color: red; font-family: SimSun">孕妇怎么处理Q?/span></strong></span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333">1</span><span style="background: silver; color: #333333; font-family: SimSun">、公司辞退孕妇的补偿情冉|准是怎样Q?/span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">{:发放工资到哺x满;按工作年限计经补偉K?/span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333">2</span><span style="background: silver; color: #333333; font-family: SimSun">、公司是否可以以我的考核和我是孕产妇不能胜Q工作为由Ҏq行降职降降薪处理Q?/span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">{:不可以?/span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">我们的工资分为基本工资(U占</span><span style="background: silver; color: #333333">1/4)+</span><span style="background: silver; color: #333333; font-family: SimSun">岗位工资</span><span style="background: silver; color: #333333">+</span><span style="background: silver; color: #333333; font-family: SimSun">l效工资{。是否可能出现只要不降低我的基本工资是合法的行为?</span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">{:不合理。工资是包括了岗位工资和l效工资?/span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333">3</span><span style="background: silver; color: #333333; font-family: SimSun">、如果公怾法破产,我是否有向集团主张赔偿的权利Q?/span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">{:破也可以主张权利,在破产胦产中优先演戏ѝ?/span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333">4</span><span style="background: silver; color: #333333; font-family: SimSun">、如果可能需要诉诸法律,我应该准备哪些方面的举证Q?/span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">{:存在力_关系的证据最重要Q此外,工资条、怀孕的证据、结婚证、准生证</span></p> <p style="margin-left: 9pt"><span style="background: silver; color: #333333; font-family: SimSun">也比较重要?/span><span style="background: silver; color: #333333; font-family: SimSun">Q?/span><strong><span style="background: silver; color: red; font-family: SimSun">按照力_?/span></strong><strong><span style="background: silver; color: red">42</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">条,不得解除三期【孕期、期、哺x】妇奟뀂那么如果一定要q反力_法解除劳动关p,只能按照q反力_法,按照W八十七条进行二倍赔偿,也就?/span></strong><strong><span style="background: silver; color: red">3</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">倍)</span></strong></p> <p style="margin-left: 9pt"><strong><span style="font-size: 13.5pt; color: #333333; font-family: 'QS 明朝'">案例</span></strong><strong><span style="font-size: 13.5pt; color: #333333">:</span></strong></p> <p style="margin-left: 9pt"><strong><span style="font-size: 13.5pt; color: #333333"><a >http://www.tianya.cn/publicforum/content/law/1/119373.shtml</a> </span></strong></p> <p style="margin-left: 9pt"><span style="background: silver; font-family: 'QS 明朝'">案情Q?/span><span style="background: silver">A</span><span style="background: silver; font-family: 'QS 明朝'">公司辞退</span><span style="background: silver">B</span><span style="background: silver; font-family: 'QS 明朝'">?/span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">Q不?/span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver">B</span><span style="background: silver; font-family: 'QS 明朝'">可能存在?/span><span style="background: silver; font-family: SimSun">q错</span><span style="background: silver; font-family: 'QS 明朝'">Q假</span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver">A</span><span style="background: silver; font-family: 'QS 明朝'">毫无道理毫无依据的辞退</span><span style="background: silver">B</span><span style="background: silver; font-family: 'QS 明朝'">?/span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">Q?/span></p> <p style="margin-left: 9pt"><span style="background: silver; font-family: 'QS 明朝'">  </span><span style="background: silver; font-family: 'QS 明朝'">一</span><span style="background: silver; font-family: SimSun">审结</span><span style="background: silver; font-family: 'QS 明朝'">果:<strong><span style="color: red">?/span></strong></span><strong><span style="background: silver; color: red; font-family: SimSun">?/span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">?/span></strong><strong><span style="background: silver; color: red; font-family: SimSun">?/span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">孕期?/span></strong><strong><span style="background: silver; color: red; font-family: SimSun">?/span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">、全</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">额</span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">期(</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">?/span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">?/span></strong><strong><span style="background: silver; color: red; font-family: SimSun">q?/span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">加了</span></strong><strong><span style="background: silver; color: red">15</span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">天)?/span></strong><strong><span style="background: silver; color: red; font-family: SimSun">?/span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">?/span></strong><strong><span style="background: silver; color: red">75%</span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">的哺x?/span></strong><strong><span style="background: silver; color: red; font-family: SimSun">?/span></strong><span style="background: silver; font-family: 'QS 明朝'">Qƈ以入</span><span style="background: silver; font-family: SimSun">职时?/span><span style="background: silver; font-family: 'QS 明朝'">至三期届</span><span style="background: silver; font-family: SimSun">满ؓ力_</span><span style="background: silver; font-family: 'QS 明朝'">合同</span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">pd</span><span style="background: silver; font-family: SimSun">l?/span><span style="background: silver; font-family: 'QS 明朝'">?/span><span style="background: silver; font-family: SimSun">间计</span><span style="background: silver; font-family: 'QS 明朝'">在</span><span style="background: silver; font-family: SimSun">职时?/span><span style="background: silver; font-family: 'QS 明朝'">Q然后以</span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">?/span><span style="background: silver; font-family: SimSun">职时?/span><span style="background: silver; font-family: 'QS 明朝'">按照?/span><span style="background: silver; font-family: SimSun">力_</span><span style="background: silver; font-family: 'QS 明朝'">合同法》第八十七条?/span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">?/span><strong><span style="background: silver; color: red; font-family: SimSun">赔偿</span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">金(卛_法解除的</span></strong><strong><span style="background: silver; color: red; font-family: SimSun">补偿</span></strong><strong><span style="background: silver; color: red; font-family: 'QS 明朝'">金的双倍)</span></strong><span style="background: silver; font-family: 'QS 明朝'">。一</span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">不是我代理的?/span></p> <p style="margin-left: 9pt"><span style="background: silver; font-family: 'QS 明朝'">  </span><span style="background: silver; font-family: 'QS 明朝'">?/span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver">A</span><span style="background: silver; font-family: 'QS 明朝'">公司扑ֈ我,我想当然的以</span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">Q按照?/span><span style="background: silver; font-family: SimSun">力_</span><span style="background: silver; font-family: 'QS 明朝'">合同法》第八十七条?/span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">定,</span><span style="background: silver; font-family: SimSun">力_</span><span style="background: silver; font-family: 'QS 明朝'">者可?/span><span style="background: silver; font-family: SimSun">选择</span><span style="background: silver; font-family: 'QS 明朝'">要求</span><span style="background: silver; font-family: SimSun">l箋</span><span style="background: silver; font-family: 'QS 明朝'">履行Q不要求</span><span style="background: silver; font-family: SimSun">l箋</span><span style="background: silver; font-family: 'QS 明朝'">履行的,</span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">?/span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">支付双?/span><span style="background: silver; font-family: SimSun">补偿</span><span style="background: silver; font-family: 'QS 明朝'">卛_Q一</span><span style="background: silver; font-family: SimSun">?/span><span style="background: silver; font-family: 'QS 明朝'">判决属适用法律</span><span style="background: silver; font-family: SimSun">错误</span><span style="background: silver; font-family: 'QS 明朝'">?/span></p> <img src ="http://www.tkk7.com/jinfeng_wang/aggbug/315853.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2010-03-19 00:27 <a href="http://www.tkk7.com/jinfeng_wang/archive/2010/03/19/315853.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单点登陆(SSO)lg的设计与实现 zzhttp://www.tkk7.com/jinfeng_wang/archive/2008/03/07/184540.htmljinfeng_wangjinfeng_wangFri, 07 Mar 2008 08:36:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2008/03/07/184540.htmlhttp://www.tkk7.com/jinfeng_wang/comments/184540.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2008/03/07/184540.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/184540.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/184540.html



  先说几句废话Q自我感觉此Ҏq不错,臛_解决了安全性的问题Q也实现了统一dQ能跨^収ͼ跨服务期Q跨域名Q当焉要相应的联盟站点的支持,但从原理上绝对能跨^台。设计和具体实现的描q比较长Q今天先介绍一部分


1引言

1.1 ~写目的

详细说明单点dlg(SSO)的设计思想和实现方法,是日后该lgl护和扩展工作的基本依据文档。预期读者是要实现单点登?SSO)pȝ的系l设计h员,pȝ开发h员,pȝl护人员?

1.2 背景

说明Q?

  1. 待开发Y件系l的名称Qjillzhang的SSOlg
  2. 本项目的d提出者ؓjillzhang、开发者ؓjillzhang、用户ؓ有用h合需求^台的开发和设计人员?

1.3 定义

SSO是Single Sign On的羃写,该技术主要用于用h合?br /> 认证中心Q认证中心是用户注册Q成员站点管理,用户dQ验证登录信息,保存d 信息Q颁发登录认证的中心站点?nbsp;
成员站点: 成员站点是遵从认证中心规则,享用认证中心l一用户的站炏V?nbsp; 
注册站点Q?/strong>如果x为成员站点,必须先在认证中心q行站点登记Q登记后Q认证中心会保存注册站点的配|信息,q将该配|信息发l注册站炏V注册站点也需保存q些配置信息Q供日后与认证中心交互时候用?nbsp; 
联盟用户Q指在认证中心注册的用户Q这些用戯被所有的成员站点所׃n?br /> dhQ指成员站点向认证中心发出的带有站点配置的用L录请求信息?br /> dhQ只用户向认证中心发出的要求退出登录的h?nbsp; 
dh验证Q?/strong>指的是认证中心根据存储的站点信息Ҏ员站点的dh信息q行? 源和真实性的验证?br /> dh验证Q?/strong>指认证中心在接受来自成员站点的登求的时候,对请求的来源和真实性进行的验证
d{复Q?/strong>指认证中心对l过验证的登录请求作出的{复信息。该{复包含用户的登录信息?br /> 在线联盟用户?/strong>Q指的是在成员站点中Q在U的联盟用户数量?nbsp; 
在线联盟用户列表Q指的是在成员站点中Q在U的联盟用户的列表信息?nbsp;
d站点清单Q?/strong>是由认证中心l护的用Ld站点信息Q当用户注销的时候,会遍历此清单Q逐个d?

1.4 参考资?

本组件的设计和实现参考了下面的系l和书籍

  1. 《数字签名技术原理及技术?

2 E序pȝ的结?

本组件包括下面几个应用接口,分别如下Q?

  1. ISiteQISite是用于描q和操作成员站点的接?
  2. IUser : IUser是用于描q和操作联盟用户的接?
  3. IServer:IServer是认证中心处理登录请求和dh的接?
  4. IClient: IClient是成员站点发出登录请求和处理d{复的接?
  5. IUserLoginListQIUserLoginList是描q和操作用户d站点清单的接?
  6. ILoginRequestQ是记录和操作成员站点发送登录请求的接口?
  7. ILoginRequestContainerQ用于保存和l护dh列表的接?
  8. IUserStateContainerQ是联盟站点中保存用联盟用户d信息的接口?

它们的定义如下:

lg的工作流E描q如下:

  1. W一步,首先注册联盟站点Q注册联盟站点用到接口ISite
  2. W二步:注册好联盟站点之后,认证中心生的站点配置信息Q包括站点编P站点公钥Q站点私钥,认证中心的登录地址Q认证中心登出地址Q存储到联盟站点本地?
  3. 在认证中心上注册一新用P注册用户需要用IUser接口
  4. 在联盟站点对认证中心发出dh
  5. 认证中心验证dh
  6. 在认证中心进行登?
  7. d成功后,保存d据Q认证中心对联盟站点发送登录答复,q将此次d记录到登录站Ҏ?
  8. 联盟站点接收到登录答复后Q先q性验证,正确后,Ҏd{复中的信息产生用户d据Qƈ且更新联盟用L录数和登录列?
  9. 在联盟站点中发出dh
  10. 认证中心验证dhQ正的话,销毁认证中心用L录票据,通过用户的登录站Ҏ单,逐个调用联盟站点的登出页?
  11. 在认证中心回调联盟站点的d늚时候,联盟站点会在d中销毁各个的d据Qƈ更新在线用户数和用户列表?

 

3 ISite接口设计说明 

3.1 接口描述

ISite接口包括7个属性和2个方法,分别用于在认证中心用于描q和操作站点的配|?

信息?














其中Q各个属性的含义如下

属性名U?/span>

cd

含义

SiteID

string

站点~号Q用于表C站点的唯一性?/span>

HomePage

string

当登录请求中未提供来源网址的时候,d{复发送的地址

LogOutUrl

string

在进行统一d的时候,回调的联盟站炚w面地址Q这个页面会负责销毁本站的d据信息?/span>

PublicKey

string

用于数据交换时加密或{֐用的公钥

PublicAndPrivateKey

string

用于数据交换时加密或{֐用的U钥

FromUrlKey

string

用于指示联盟站点在发送登录请求和认证站点q行h验证的时候来源网址存储位置?/span>

UidField

string

用于指示联盟站点在发送登录请求和认证站点q行h验证的时候用户信息的存储位置?/span>

q包括两个方法,分别为:

Ҏ?/span>

含义和作?/span>

Add

d新的联盟站点?/span>

Validate

验证联盟对象是否已经存在

3.2功能

该接口能在认证中心完成新联盟站点d操作Q添加之前可以验证站Ҏ否存在?

3.3 默认实现

在SSOlg中,已经实现了一个默认的ISite对象。ؓDefaultServer/ DefaultSite.csQ它放|在认证中心根目录下的sites.config文g作ؓ存储介质Q通过AddҎd新联盟站点后的效果ؓQ附件中的site.config文gQ可自行下蝲文g后,看其l构?

 

 

4 IUser接口设计说明

4.1接口描述

IUser接口包括2个属性和2个方法,用于在认证中心端描和操作q联盟用戗?

其中Q各个属性的含义如下

属性名U?/span>

cd

含义

Uid

string

用户~号Q是用户的标?/span>

Pwd

string

用户密码

q包括两个方法,分别为:

Ҏ?/span>

含义和作?/span>

Validate

验证用户是否存在

Register

d新用?/span>

4.2功能

该接口能在认证中心完成新联用h加操作,d之前可以验证用户是否存在?

4.3 默认实现

在SSOlg中,已经实现了一个默认的IUser对象。ؓDefaultServer/ DefaultUser.csQ它放|在认证中心根目录下的users.config文g作ؓ存储介质Q通过RegisterҎd新联盟用L效果为:附g中的users.config文gQ可自行下蝲文g后,看其l构?

 

 

5 IUserLoginList接口设计说明

5.1接口描述

IUserLoginList接口包括3个方法,用于在认证中心描q和操作用户d的站Ҏ单?

q包括三个方法,分别为:

Ҏ?/span>

含义和作?/span>

Add

验证用户是否存在

GetLoginSites

获取用户的登录站Ҏ?/span>

DeleteUser

删除用户的登录站Ҏ单数?/span>

5.2功能

该接口在认证中心用于用户记录和维护用L录的站点清单  

5.3 默认实现

在SSOlg中,已经实现了一个默认的IUserLoginList对象。ؓDefaultServer/ UserLoginLog.csQ它通过一个Collection对象来实现用L录站Ҏ单的l护工作?

 

 

6 IServer接口设计说明

6.1接口描述

IServer接口包括2个属性和5个方法,用于接收Q验证登录请求,发送登录答复,接搜Q验证登求,创徏本地d据Q维护用L录清单?

两个属性ؓQ?

属性名U?/span>

cd

含义

Site

ISite

当前上下文处理请求和{复的站点对?/span>

Uid

string

当前处理的上下文中的用户~号

 

q包括三个方法,分别为:

Ҏ?/span>

含义和作?/span>

CheckUser

验证用户对象是否存在

CheckExistToken

验证d据已经存在

SaveToken

在认证中心本C存登录票?/span>

Jump

通过url跌{Q发送登录答?/span>

LogOut

l一d?/span>

6.2功能

该接口在认证中心Q用于接Ӟ验证dhQ发送登录答复,接搜Q验证登求,创徏本地d据Q维护用L录清?

6.3 默认实现

在SSOlg中,已经实现了一个默认的IServer对象。ؓDefaultServer/ LoginRequest.cs?

 

 

7 ILoginRequest接口设计说明

7.1接口描述

ILoginRequest接口包括2个属性,用于记录和描q联盟站点的dhQ这些信息在发出dh的时候创建,在收到登录答复的时候销毁。用于确保登录答复的不可复用性?

两个属性ؓQ?

属性名U?/span>

cd

含义

Identity

string

dh标志W,该标志符会发送给服务端,服务端在发送登录答复的时候会回传该标志,联盟站点会根据此标志来验证请求是否是伪造的?/span>

TimeStamp

DateTime

h的时间戳

7.2功能

该接口在联盟站点Q用于记录和描述联盟站点的登录请求,q些信息在发出登录请求的时候创建,在收到登录答复的时候销毁。用于确保登录答复的不可复用性?.3 默认实现

7.3 默认实现

在SSOlg中,已经实现了一个默认的ILoginRequest对象。ؓDefaultServer/ LoginRequest.cs?

 

8 ILoginRequestContainer接口设计说明

8.1接口描述

ILoginRequestContainer接口包括3个方法,用于在联盟站点中记录和维护登录请?

 

Ҏ?/span>

含义和作?/span>

Add

ddh信息

Check

查登录请求是否存?/span>

Remove

销毁存在的dh

8.2功能

该接口在联盟站点Q用于在联盟站点中记录和l护dh

8.3 默认实现

在SSOlg中,已经实现了一个默认的ILoginRequestContainer对象。ؓDefaultServer/ LoginRequestContainer.cs?

 

9 IUserStateContainer接口设计说明

9.1接口描述

IUserStateContainer接口包括5个方法,用于在联盟站点中记录和维护在U联盟用户信?

 

Ҏ?/span>

含义和作?/span>

Add

dd用户

GetList

获取在线用户清单

Check

查某个用h否已l在U?/span>

Remove

U除某个在线用户?/span>

GetUserCount

获取在线用户个数

9.2功能

该接口在联盟站点Q用于在联盟站点中记录和l护在线联盟用户信息

9.3 默认实现

在SSOlg中,已经实现了一个默认的IUserStateContainer对象。ؓDefaultServer/ UserState.cs?

 

 

10 IClient接口设计说明

10.1接口描述

IClient接口包括6个属性和2个方法,用于发出dh和登?

8个属性ؓQ?

属性名U?/span>

cd

含义

SiteID

string

站点~号

PrivateKey

string

数据交换时加密或者签名用的公?/span>

LoginAddress

string

认证中心d地址

LogoutAddress

string

认证中心d地址

Uid

string

d的用L?/span>

TimeOut

int

d{复的超时时_单位s

UidField

string

ddh中的用户信息的存储位|?/span>

FromUrlField

string

dh中的来源|址存储位置

2个方法ؓ

Ҏ?/span>

含义和作?/span>

Login

发出dhQƈ处理d{复

LogOut

d

10.2功能

该接口在联盟站点Q用于发出登录请求和dh

10.3 默认实现

在SSOlg中,已经实现了一个默认的IClient对象。ؓDefaultServer/ DefaultClient.cs

 

11 本系l的安全?

11.1 dh的格?

联盟站点向认证中心发送的dh格式如下Q?

站点信息+dh~号+旉?I用户信?对站点信息和d清秋L{֐信息?br /> 除了{֐信息之外的全部信息均为明文传送,但因为重要的数据均经q数字签名,l果是站点信息和dh~号是不能被改的,保证了认证中心收到的dh的真实性?

11.2 d{复的格?

认证中心发给联盟站点的登录答复格式如?

d用户信息+dh~号+旉?对用户信息和dh号和旉戳的{֐信息
其中d用户信息是经q非对称加密的。请求号和时间戳因ؓl过{֐Q故也不能篡改,q样可以保证联盟站Ҏ到的d{复的真实性和完整性。ƈ且非正常联盟站点无法解密用户信息Q也无法从中获取好处?nbsp; 

幅太大Q下面还有很长的内容要说Q先发布以下Q感兴趣的朋友可以先下蝲E序试使用。以后,我会逐渐dSql ? Oracle的实现。您也可以根据接口规范,开发符合自ql需求的SSOpȝQ今天先到这?br />
E序文gQ?a href="/Files/jillzhang/SSO.rar">/Files/jillzhang/SSO.rar


更新Q新增登录流E图Q?br />
[原创]单点登陆(SSO)lg的设计与实现?d程?/a> 








新增d程?2008-02-02



上面是整体流E图Q这个SSOlg在安全上有了很充分的考虑Q可以说是非常安全,那么下面看看dh数据的格式,和ؓ何它能保证真实性和完整?br />


q样Q当数据在传输过E中Q如果站点编P用户~号Q请求号L一做M的修改,当认证中心接收到数据之后Q均无法与签名信息进行匹配。凡是认证中心能验证通过的请求均为合法的Q真实的Q完整的h信息?br />
d{复的格式如下图所C?br />
因ؓdP旉戻I用户信息均加入数字签名信息,所以这些数据在传输中不能被伪造和改Q而用户信息经q非对称性加密,也防止非真正h发送者能解析出用户信息,q样在接受和发送请求和响应的时候,实Cl对的安全?br /> 当然不是没有破熾Q破l在于当h{复未到达联盟站点之前,有h截获q先于正常用L录了联盟站点Q此时我们可以将用户的ip信息作ؓ{复数据的一部分Q加入签名,以此实现很高的安全保?br />
d程?br />




jinfeng_wang 2008-03-07 16:36 发表评论
]]>
大嘴日语的破?/title><link>http://www.tkk7.com/jinfeng_wang/archive/2007/04/10/109767.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Tue, 10 Apr 2007 14:58:00 GMT</pubDate><guid>http://www.tkk7.com/jinfeng_wang/archive/2007/04/10/109767.html</guid><wfw:comment>http://www.tkk7.com/jinfeng_wang/comments/109767.html</wfw:comment><comments>http://www.tkk7.com/jinfeng_wang/archive/2007/04/10/109767.html#Feedback</comments><slash:comments>44</slash:comments><wfw:commentRss>http://www.tkk7.com/jinfeng_wang/comments/commentRss/109767.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jinfeng_wang/services/trackbacks/109767.html</trackback:ping><description><![CDATA[<p> <br>最q想要一个背单词的Y?br><br>自己做一个容易,词库比较ȝ?br><br>在网上找啊找Q都没啥特别好用?br><br>后来q上了《大嘴日语?br><br>从大?.0开始,没有破解版可以下蝲<br>Q自׃是做软g的,q想破解别h的免费用QsighQ?br><br>下了个最新的6.0 和可以破解的2.0<br><br>来回把词库拷贝,居然发现大嘴用的的DBISAM文g数据?br><br>不厚道的找东西,破解<br><br>不厚道的来回倒腾数据Q现在词库已l在我的Access中了?br><br>对于我来_数据才是重要的?br>TTSQ其他功能,都是可以做出来的?br><br>软g的漏z到底在哪儿Q?br><br>怎么保软g没有漏洞Q?br><br>大嘴?.0?.0Q做了加密功夫Q一直没有破解版出Q?br><br>竟然q有q么大的一个后门?br><br>不得不值得好好的思量一番周边Y件的质量?br><br>参见Q?a href="http://www.tkk7.com/jinfeng_wang/archive/2007/02/14/99819.html">http://www.tkk7.com/jinfeng_wang/archive/2007/02/14/99819.html</a><br><br>btw: 个h研究Q不盗版吧 ^_^<br></p> <img src ="http://www.tkk7.com/jinfeng_wang/aggbug/109767.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-04-10 22:58 <a href="http://www.tkk7.com/jinfeng_wang/archive/2007/04/10/109767.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>人员、资源、操作及q三者构成的权限控制http://www.tkk7.com/jinfeng_wang/archive/2007/02/14/99819.htmljinfeng_wangjinfeng_wangWed, 14 Feb 2007 06:53:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2007/02/14/99819.htmlhttp://www.tkk7.com/jinfeng_wang/comments/99819.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2007/02/14/99819.html#Feedback5http://www.tkk7.com/jinfeng_wang/comments/commentRss/99819.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/99819.html
在谈到其安全性的时候,很多的都是从“网l安全”的角度ȝ待问题,D不知,堡垒
的内部是最最不安全的。对付“黑客攻几Z是pȝ理员所要面对的问题Q而如何更好的
加强堡垒内部自n的安全,是在WebE序的设计中需要考虑的问题?br />
pȝ理员所要面对的|络d、操作系l 安全不是我所考虑的问题,如何加强Webpȝ
自n的健h我所最最兛_的事情。?br />
从“构造URL”攻d“注入SQL文”攻击,都是属于q分信Q用户输入Q而造成的安全问题?br />q恰恰应该是由应用程序自w加以重视、解决的问题?br />
Z角色的安全控制已l逐渐的被大家逐渐的接受,每个用户被分配ؓ不同的角Ԍ不同的角?br />h不同的操作权限?但是如何划分角色、用戗操作权限,则是需要认真对待的问题?br />
举例Q?br />一个MISpȝ中,员工有查询工资的权限Q但是某个员工是否具有查询其他员工的权限呢?

不能深入的追问问题,详细的分辨清楚系l中到底有多角艌Ӏ每个用h在的角色Q是不能完成安全控制的?br />


btw: 以上的问题,大家不妨在自qcMpȝ中自己去查一下,有此问题的占l大多数吧?br />看过此文的,愿意回答“是”“否”的Q可以留aQ 也当作一个调查吧?/font>


上面的这个例子,是一个很成熟的办公系l中存在的问题。用客Lscript脚本Q控制了用户的界面操作,D不知maxthon可以解除这个限制。此pȝ中,用户的请求都被整理ؓURLQget方式提交Q,虽然URL中的键值含义ƈ不是很明显,但是q是可以试着L击,获取U密?br />
认真的核查用L输入Q利用AOP部vQ细密的对用L输入q行核查Q是很有必要的事情?br />
某个人、某个资源、某个操作,q三个要素组l在一起则是:某个人对某个资源q行某项操作
实际情况下,许多人、许多资源、对每个资源冰存在着多个操作?br />
h、资源、操作进行划分,可以得到Q?br />具体的某一cMhQ可以对某些资源Q进行某些的操作Q?q就是具体的某项权限限制?br />    某一cMhQ则可以归纳艌Ӏ?br />    Ҏ些资源的某些操作Q则可以归纳为工作Q务?br />也就是说Q整个系l是“某个角色去完成某些工作dQ而具体的一个帐户属于某个角Ԍ某项工作则具体的是指Ҏ个资源进行某个操作”?br />
相对来说Q系l中的h员是最Ҏ辨认的,pȝ中的资源也是可以在系l的功能调查时分清楚的,pȝ中的操作则是最复杂、最隑ֈ清晰Q甚臛_pȝ完成旉会变化的?br />
只有分L清楚了系l中的h、资源、操作,才能辨别清楚pȝ中的具体的权限限制?br />
“基于角色的安全控制”这L提法Q只提及了hQ未能强调将资源、操作进行规c,q是很不充分的一U提法?br />
在Webpȝ中,pȝ在设计的q程中,分清楚资源Q分清楚操作Q极大羃每个页面的功能、提高页面功能的原子性,q也是权限控制对pȝ设计提出的一要求?br />
前面提及使用AOPq行权限控制Q现在简qC下各部g的功能:
   业务模块Q-完成具体的对某个资源的操作;
   前台面模块Q- 完成整体面的整合;
   安全控制模块Q-实现安全控制功能Q完成h员、角艌Ӏ工作的逻辑判断Q?br />   AOP配置整合模块Q-_合安全控制模块和业务模块;


在于如何去解冻I而是如何d现。隐藏v来的问题更是危险?br />
而如何发现问题,则完全是一个素质、能力的事情Q也许这是下一个话题?br />

jinfeng_wang 2007-02-14 14:53 发表评论
]]>
buying notbookhttp://www.tkk7.com/jinfeng_wang/archive/2007/02/02/97420.htmljinfeng_wangjinfeng_wangFri, 02 Feb 2007 01:21:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2007/02/02/97420.htmlhttp://www.tkk7.com/jinfeng_wang/comments/97420.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2007/02/02/97420.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/97420.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/97420.html发信? 水木C֌ (Fri Feb  2 00:30:29 2007), 站内

本来看中的是nc6000,觉得性h比不错,但是昨天mm转了一圈之后,定在了T40?br />
中午11点半从东门出发,骑R
先去北大南门吃饭Q不?br />到太qxC一块三星银?盘盒Q?70 + 50 = 520
近1点了Q:Q?br />
中v传一圈,回到580柜台QT40摆了好几収ͼ分两U?br />一U就是迅?.5G/512M/40G/DVD/ATI 7500 32M/   3800
另外一U多了蓝牙、无U,光驱是DVD-CDRW  4000
同时问了nc6000的h|高分?500

蓝牙没用QCDRW也没用,是奇怪ؓ什么迅驰还不带无线|卡
加网卡还要另?0Q讲h果,于是不要|卡了,反正暂时用不?br />
开始挑机器Q只摆了4台第一U机?br />让老板再拿出几収ͼ被告知只有这几台Q感觉必然说谎阿
没办法,埋头?br />
先看屏幕Q把亮度都调到最高,开始对?br />有一台的屏幕很亮Q但是用手按水LU很严重
q有一台屏q发黄,直接淘汰
最后选了一台水波纹不是很明昄Q但是显C的颜色不是很鲜艻I没有W一台的颜色正,昑־有点灰灰?br />
键盘都不错,不a

l箋Q因旉回实验室有事Q很多没很仔l测
ntest看屏Q没看出什么问题,也许是自己太菜吧
erest看配|,W合
cpu-z看cpu和内存,发现两条内存牌子不一P一个英飞铃Q一个金士顿Q让老板l换成一LQ于是老板把另外一个机器拆开Q找C条英飞铃Q给我按上。在另外一台机器上看内存,发现竟然q有C的?br />super-pi计算100万,用了1?4U,另外一台用??9U。测?200位的Q初始化用了39U,没l,回来也没全测完,明天一?br />mentest内存,了200%?br />hdtune硬盘,没问?br />
试了一下光驱,发现读CD的时候还很安静,但是读DVDQ找了一个划的比较厉害的Q的时候风扇就响的利害了,没办法,说风扇没法换Q我也不懂,忍了

看电池,只有两台机器有电池,于是到带蓝牙的机器上拿了一块用q?5ơ的Q可是健L冉|C差。不懂。那掉电源显C能用1时Q另外一个用q?18ơ,看情况昄良好Q但是显C只能用44分钟。拿了第一?br />
q里发现一个问题,拔掉甉|屏幕会闪Q而且每个机器都是q样Q不知道会有什么隐患。不爽的是我挑的q台屏幕黑的旉比别的长Q大牛给分析一下?br />
又看了看biosQ对比了一下序列号Q没啥问题。别的也不知道看啥了

xQ换?0G的硬盘,?0G的换到移动硬盘盒?br />看了一下机器外观,发现上盖上有条划痕,我忍
让老板l擦了擦机器
送一个包Q好?br />一个IBM鼠

说声谢谢Q然后走人,被叫回来Q忘了给׃Q:Q?br />
回来了3DMARKQ?004?br />大牛说说Q我q需要做些什么测试?机器可能有些什么问题?
争取3天内解决出现的问题?br />
over
菜鸟W一ơ在中vC西,多谢一勺等大牛的帖子指?br />Ƣ迎点评


Q=Q=Q=Q=Q=
sp2004使劲跑一晚上



jinfeng_wang 2007-02-02 09:21 发表评论
]]>
MindManager6使用体会http://www.tkk7.com/jinfeng_wang/archive/2007/01/27/96267.htmljinfeng_wangjinfeng_wangSat, 27 Jan 2007 05:45:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2007/01/27/96267.htmlhttp://www.tkk7.com/jinfeng_wang/comments/96267.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2007/01/27/96267.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/96267.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/96267.html  在这?a >MindManager的免贚wd后面Q?a >94smart{朋友热情怂恿我写一教E,今天准备试着写一点儿Q不q不能算是教E,只是光掠媄Q介l一下在使用中曾l我带来惊喜的几个亮点而已?/p>

  一直希望有一个电子化的工兯够方ѝŞ象的整理头脑中O无边际的杂ؕxQ就像铅W和白纸能够做到的那P但是又能避免写满东西的白U怸易传播和保存的缺炏V?/p>

  最初通过一?a >介绍文章Q看CFreeMindQ著名的开源free思维理工具Q优势是明显的,比如Q?

  1. 跨^台。除了Windows之外Q也提供了Mac OS X、Linux{版本,实际上,它支持所有的操作pȝ?br />
  2. 免费使用。不需要Q何破解和注册码之c,可以心安理得的不花钱永远使用它?br />
  3. 功能比较强大Q基本的思维导图应该具备的功能都有,也可以发布到web上?br />
  4. MyQ但是可定制E度依然很好Q当然这是针寚w些动手能力较高的用户而言Q对我这样不会写代码的hQ这个方面的Ҏƈ不在考虑之列?/li>

  使用的时候需要先安装java的运行库Q有炚w烦,而且关键是有一些操作方式,个h感觉不太手Q导致思\频频被打断,被迫开始摸索用的ҎQ这样对于一个普通的使用者来_学习的时间成本便上升了,后来不得不尝试了商业软gQ?a >MindManagerQ这ƾY件ƈ不开源,也不能跨q_Q只支持Windowsq一家系l,但是׃很好的迎合了windows软g的操作方式,大大降低了熟Ewindows软g用户的学习成本,更和officepd软g做到了紧密整合,数据在其中流动非帔R畅?/p>

  W一个o我激动的MindManager应用是Web2.0周刊的制作,我当时的需要就是每天用最单的Ҏ攉相关信息Q包含链接、笔记或评论、分cȝ信息Q在周末的时候统一整理一下,直接输出相应的html面Q可以上传到服务器上供访问,MindManager刚好可以q乎完美的实玎ͼQ?a Save as Webpages..."中找到?/p>

  实际上无需什么教E,安装完MindManager之后Q“help”和"Learning Center"都是非常的使用教程Q而且后者还是直观的视频模式Q快速浏览一下,可以对MindManagerq款软g有大致的了解了?/p>

  在“Learn More”中的“提C和技巧”用了MindManager的格式来展示Q很有意思,在这里可以学到“生成图片格式”、“格式编排”、“浏览导䏀、“编辑技巧”等斚w的知识?/p>

  MindManager6分ؓ基础版和专业版,两个版本共有的一些新Ҏ包括:

  1. 大纲~辑模式?view"--"outline"
  2. 制表制图?topic"--"Spreadsheet"
  3. l织l构囑ָ局Q可用来展示团队和公司的l织l构?format"--"topic..."之后选择"Subtopics Layout"的标{,然后选择"Org-Chart"
  4. 输出到powerpoint?format"--之后选择"Microsoft PowerPoint Slides..."
  5. 从IE导入。如果用IE的话Q可以通过点击工具栏的按钮d某个|页的标题和链接到MindManager中自动生成一个topic?br />
  6. 支持掌上电脑手写W记及大UӀ?topic"--"notes"以及"view"--"outline"
  7. 分类U,可以把同cȝtopics用一条线划到一P以示区别?br />
  8. 自动~号?Format"--"Numberling..."
  9. 自动q,可以重新摆放topic的位|,使其看v来更协调?view"--"balance map"
  10. note中的拼写查?topic"--"notes"
  11. 特别的粘贴。可以选择需要以何种格式_脓剪脓板中的内宏V?edit"--"paste special"

  而只在MindManager6专业版中才有的特性如下:

  1. 导出到visio?format"--"Microsoft Visio Stencils...","File"--"export"--"Microsoft Visio Export"
  2. 链接到excel表格?insert"--"Microsoft Excel Range..."
  3. 插入附g?file"--"Add Attachment..."
  4. 强qo器?edit"--"filter"-"power filter"
  5. 强选择?edit"--"select"--"power edit"
  6. 自定义属性?topic"--"Custom Properties..."
  7. 加入书签?topic"--"bookmark"
  8. 评论模式Q可以区分别人所作的评论Qƈ方便的拒l或者接受?tools"--"start review"
  9. 闚w提示?topic"--"alert..."
  10. 文本记号。希望和你进行对话的使用者可以在你制作到导图上用文本记Ptext markerQ,标记Z们的意见?topic"--"test marker"
  11. 记时器?tools"--"timer"
  12. 标签?topic"--"label..."

  如果你主要用Windowspȝ工作Q而且office也始l在你的电脑中占有一席之圎ͼ最后,你也不在乎花一些美刀或者勇于想办法不花q些刀Q来得到一个真正强大、全能的思维导图工具的话Q选择MindManager pro 6吧,应该不会后悔?/p>

jinfeng_wang 2007-01-27 13:45 发表评论
]]>
试的全路经覆盖http://www.tkk7.com/jinfeng_wang/archive/2007/01/05/91877.htmljinfeng_wangjinfeng_wangThu, 04 Jan 2007 17:20:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2007/01/05/91877.htmlhttp://www.tkk7.com/jinfeng_wang/comments/91877.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2007/01/05/91877.html#Feedback2http://www.tkk7.com/jinfeng_wang/comments/commentRss/91877.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/91877.html
在Junit/Nunit试出现之后Q出C一个工具Jcover/Ncover,此工具代码覆盖率分析工具Q可以分析测试代码的试范围的覆盖率?br />
W一ơ知道此工具的时候,相当的兴奋,因ؓq样可以L的把握项目中的测试代码情c在看到自己的每行代码都被测试之后,相当的幸啊Q再加上Maven{工具可以自动连跑,那是_保证了单元测试的覆盖率了啊?br />
正是因ؓ不假思烦的信任,D了问题的出现QCover工具的覆盖,是代码行的覆盖,而不是代码Step的覆盖。所谓的代码行,是指代码中可以被执行到的具体某物理行Q但是Step则是指每一步逻辑。对于if (a==b||c==d||e==f)q样的判断,应该是有三个step在其中的。正是由于信MCover工具Q导致代码覆盖率不够Q未能测试到e==f的判断,D了一个bug在最后才被发现。问题发现的迟Q付出的代h大?/p>

上面已经说明了全路径覆盖的含义(目前Cover工具无法辑ֈ的功能)Q那么全路径覆盖是不是很有必要且一定要的呢Q答案是“YES?做到全\径覆盖的试是很痛苦的一件事情,但是Q当你从全\径覆盖中扑ֈ重大问题Ӟ才会回头来看“如果我做了全副该测试,q段路径的错误逻辑׃会出现的”?/p>

拿上篇"CheckedException VS UncheckedException"中的例子Q当代码l构逐渐演化为多出入口调用C模块Ӟ“C处不能决定具体的出错信息”。但是在代码中,如果恰恰是?C处误认ؓ可以军_错误消息"Ӟ对于q个“误操作”,可以通过全\径覆盖发现这个问题。if(a==b||c==d||e==f) {throw new MyException("error msg.")}Q这L一行代码,需要面对三U问题去报出错信息,其负担太重,情况复杂Q然后有了错误代码)?/p>

如果做了全\径覆盖,可以走到Qe==fQ的判断Q此时即可发现错误消息不正确的问题?/p>

如何才能保证完成全\径覆盖呢Q?br />1Q手工debug跟踪Q保证每一步都走到Q对于最后的(e==f)Q跟t的好辛苦阿Q创造这L条gQ走到e==fQ就好篏的?br />2Q利用Ncover的功能,对于q样的复杂逻辑Q手工进行debug跟踪?br />3)拆开代码Qؓ三行Q每个step为单独的一行)Q利用NCover自动分析?哈,老师教过?Q不允许出现q于复杂的代?q个原则被发挥到极致了?/p>

jinfeng_wang 2007-01-05 01:20 发表评论
]]>
错误处理的恢?/title><link>http://www.tkk7.com/jinfeng_wang/archive/2006/07/10/57571.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Mon, 10 Jul 2006 14:52:00 GMT</pubDate><guid>http://www.tkk7.com/jinfeng_wang/archive/2006/07/10/57571.html</guid><wfw:comment>http://www.tkk7.com/jinfeng_wang/comments/57571.html</wfw:comment><comments>http://www.tkk7.com/jinfeng_wang/archive/2006/07/10/57571.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jinfeng_wang/comments/commentRss/57571.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jinfeng_wang/services/trackbacks/57571.html</trackback:ping><description><![CDATA[错误处理的恢复一直是Ҏ被恢复的问题Q?br />一个状态机中,出现错误的时候,一定要及时C正状态机的状态?br />上面的一句话可能是很Ҏ理解的一句话Q?br />但是在实际运用中Q如何去真的体会到状态机的存在,及时q行错误恢复<br />却不是一件很Ҏ能够做到的事情?br /><br />之所以在?NET C#中用Unchecked Exception”,很大的一个原?-“很多时候是用户是没法去做错误修复的”,q真的是很奇怪的一个理由,而且q个理由竟然被很多h怿了?br /><br />今天才意识到错误处理的恢复是自己没有遇到的一个重要的问题Q胆战心惊!<img src ="http://www.tkk7.com/jinfeng_wang/aggbug/57571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2006-07-10 22:52 <a href="http://www.tkk7.com/jinfeng_wang/archive/2006/07/10/57571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ADO.NET Connection Status Maphttp://www.tkk7.com/jinfeng_wang/archive/2006/06/03/50173.htmljinfeng_wangjinfeng_wangSat, 03 Jun 2006 13:35:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2006/06/03/50173.htmlhttp://www.tkk7.com/jinfeng_wang/comments/50173.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2006/06/03/50173.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/50173.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/50173.html

jinfeng_wang 2006-06-03 21:35 发表评论
]]>
Checked Exception VS UnChecked Excetion (l?)http://www.tkk7.com/jinfeng_wang/archive/2006/06/03/50170.htmljinfeng_wangjinfeng_wangSat, 03 Jun 2006 13:22:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2006/06/03/50170.htmlhttp://www.tkk7.com/jinfeng_wang/comments/50170.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2006/06/03/50170.html#Feedback5http://www.tkk7.com/jinfeng_wang/comments/commentRss/50170.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/50170.html    假设我的团队正在开发一个库E序Q由于某U原因,现在希望能够得到所有最外层 API 所抛出的所有异常的cd、各自的信息、ƈ且能够附上各U异常所出现的原因和解决办法。如果开发过E中内部使用的是 Unchecked Exception Q那么对于这个Q务简直就ȝ了。没办法Q开发h员一个个的自我进行检查然后统计吧Q但是往往q样的统计M有漏|之鱹{现在的 MSDN 中的异常信息p糕的很Q最底层的公有库的异怿息内容可能完整一点,但是上层的库的异怿息糟p的不行Q根本不能完整的报全所有出错的可能性?/span>

你可以想象的出,一个库函数的异怿息不完整Q对于他的用h_是多么不友好的事情。假?/span> MSDN ?/span> File.Open() 会抛?/span> IOException Q你的程序就很难惛_很规矩的?/span> IOException 做了 catch Q然后提C用h查相应位|的文g是否存在 / 被打开{。别指望 MSDN 的那些信息能够对l端用户有多大的帮助Q太多不懂计机的h在傻呆呆的握着鼠标了。再加上 MicroSoft 的提CZ息本w就存在着“答非所问”,“莫名其妙”的事情Q用L到这些情况就更不知道怎么解决问题了。再加上自己的应用程序中会弹Z个个“蹩脚”的q行旉误的错误框,真的不是一个很如意的创作?/span>

        但是Q如果用的?/span> Checked Exception Q这时候编译器会强q你的外部接口的异常相当的完_最L可以做到?/span> MSDN 的异常类型齐整?/span>

 

 

 

 



jinfeng_wang 2006-06-03 21:22 发表评论
]]>
数据库驱动程序的试需要注意的问题http://www.tkk7.com/jinfeng_wang/archive/2006/05/28/48597.htmljinfeng_wangjinfeng_wangSun, 28 May 2006 07:52:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2006/05/28/48597.htmlhttp://www.tkk7.com/jinfeng_wang/comments/48597.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2006/05/28/48597.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/48597.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/48597.html 1. 不要用TestCase的构造函数初始化FixtureQ而要?br />setUp()和tearDown()Ҏ?/font>

2. 不要依赖或假定测试运行的序Q因为JUnit利用
Vector保存试Ҏ。所以不同的q_会按不同?br />序从Vector中取出测试方法?

3. 避免~写有副作用的TestCase。例如:如果随后?br />试依赖于某些特定的交易数据Q就不要提交交易?br />据。简单的会滚可以了?/font>

  对于我们来说Q有时是必须要提交,以至于有副作用的?/font>
  例如Q在执行“插入“后Q数据库昄会多Z条数
据来。那么必d随后每个试自己消除自己的副
作用?/font>
  在这里,是自己“再删除刚插入的数据”。(q时?br />需要考虑到这个善后的工作不能自己׃能有副作用,
  删除多了其他的数据)?/font>
 
  q里的副作用q指“媄响到周围环境”,因ؓ我们?br />在工作的人比较多Q所以最好大家的试服务器能?br />分开来,
 例如一个h一个Database实例Q可以徏得稍微小一
点)或者一个h一个数据库Q?/font>   注意这些个Z?br />有区别的内容用常量在每个q所有程序中?br />用。而不是分布在各个位置?/font>   否则以后要改换测?br />服务器,所有的E序都需要改动?/font>
 
  Z保证试E序能够很容易的到处执行Q请保证
大家的数据库服务器的试数据全部一致?/font>  否则Q?br />׃能做到很Ҏ得拿到FJ也可以很Ҏ的运行,
所以需要准备“测试数据集“?/font> 包括QSchema ,table Q?br />stored procedure{数据库对象的结构一_  q包
括数据库的数据内容保持一致?/font>

4. 当承一个测试类Ӟ记得调用父类的setUp()?br />tearDown()Ҏ?

5. 测试代码和工作代码攑֜一P一边同步编?br />和更新。(使用Ant中有支持junit的task.Q?

6. 试cd试Ҏ应该有一致的命名Ҏ。如?br />工作cd前加上test从而Ş成测试类名?
可能q里我们需要改动,函数名和我们的试?br />例的~号一致v来?/font>

7. 保试与时间无养I不要依赖使用q期的数?br />q行试。导致在随后的维护过E中很难重现试?

8. 如果你编写的软g面向国际市场Q编写测试时?br />考虑国际化的因素。不要仅用母语的Localeq行试?

9. 可能地利用JUnit提供地assert/failҎ以及
异常处理的方法,可以使代码更为简z?
 
q个内容有其关键Qassert语句的好坏直接媄?br />到测试的正确性?/font> 因ؓassert是用于当前试
的正确性的?/font>

10.试要尽可能地小Q执行速度快?


==========
1Q将所有的数据库的试数据用ODBCE序自动
生成的?用户可以单的修改ConnectionStringQ?br />然后q行E序Q就可以创徏生成?/font>据库/数据?br />?存储l构Qƈ且自动插入数据?br />
 
   2Qؓ了保证多个测试h员的不干扎ͼ分别
各自单独使用自己的数?/font>库。否则会因ؓ一个自
q错误Q媄响别人的工作?/font>
 
   3Q在自己的程序中Q所有涉及环境的内容都用
单独攑ֈ一个类中,用static
帔R׃n使用Q这?br />׃于很Ҏ的更换环境再q行试Q做到很?br />易的UL试环境Q?/font>
 
   4Q关于数据库表结构,我徏议测试表中含有一
个主键,我们在插入数据的?/font>候,保证试用例Q?br />试用例E序Q测试用例程序中的数据,q三?br />的编号一致v来。便于出现问题时Q可以排除数据?/font>


jinfeng_wang 2006-05-28 15:52 发表评论
]]>
Checked Exception VS UnChecked Excetion (l?http://www.tkk7.com/jinfeng_wang/archive/2006/05/12/45911.htmljinfeng_wangjinfeng_wangFri, 12 May 2006 12:21:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2006/05/12/45911.htmlhttp://www.tkk7.com/jinfeng_wang/comments/45911.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2006/05/12/45911.html#Feedback2http://www.tkk7.com/jinfeng_wang/comments/commentRss/45911.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/45911.html上篇Q?a href="/jinfeng_wang/archive/2006/05/11/45726.html">http://www.tkk7.com/jinfeng_wang/archive/2006/05/11/45726.html

先来回复两个回帖Q?br />"你可以把IO{异常{化成你类库中中定义的异常。当然你定义的异常是Checked Exception q是 UnChecked Excetion 那你自己定了?"

假设我按照这条徏议去做了Q那么我可以抛出XXXLibException。假设我的异帔R用的是CheckedExceptionQ那么客L序员可以捕捉它。但是对于不同的出错原因Q例如不同的原因Q包括无权限、硬盘满、U盘被拔了{等Q导致无法正常写日志文gQ,E序都是捕捉XXXLibExceptionQ那么客L序员无法根据不同的异常d相应的处理(例如提示用户修改权限、直接启用备用目录,直接退出程序)。MQ如果异常类型不同,客户E序可以Ҏ“异常类型”做不同的工作(~译器+工具可以实现自动代码生成Q;但是如果全部合ƈZ个异常,那么客户E序只能Ҏ“ExceptionMessage”尝试着做不同的工作Q恰恰目前没有办法完成自动编码)?br />


"要知?JDK ?FileWriter 是可以抛?IOException 的子cȝQ只要文档够详l,Java代码中也可以只去捕捉更明l的异常Q?也可以就捕捉q新抛出包装过的异常(甚至是RuntimExceptionQ,除非呆板地去捕获每个异常Q不然代码怎么会丑陋呢Q?

RuntiomeExceptionQ也是UncheckedExceptionQ类?NET的ExceptionQ,它不会要求客户代码强行捕捉异常,据此我写了下面的一个程序:
private void button1_Click(object sender, System.EventArgs e)
  {
   throw new Exception("s");
  }
     我只试了.NET的程序,出现的界面大家自p 。因为UncheckedException没有要求客户E序L捉(客户E序员不能自觉的发现库中抛出的各U异常)Q让最l用L接面对这L异常Q是一个道L事情么?



jinfeng_wang 2006-05-12 20:21 发表评论
]]>
Checked Exception VS UnChecked Excetionhttp://www.tkk7.com/jinfeng_wang/archive/2006/05/11/45726.htmljinfeng_wangjinfeng_wangThu, 11 May 2006 13:18:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2006/05/11/45726.htmlhttp://www.tkk7.com/jinfeng_wang/comments/45726.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2006/05/11/45726.html#Feedback4http://www.tkk7.com/jinfeng_wang/comments/commentRss/45726.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/45726.html 1 ?/span> .NET Framework IO Interface  and  JDK IO Interface

1.1 Q?/span> .NET Framework 1.1

   public StreamWriter(    string path  );

异常

异常cd

条g

UnauthorizedAccessException

讉K被拒l?/span>

ArgumentException

path 为空字符?/span> ("") ?/span>

ArgumentNullException

path 为空引用Q?/span> Visual Basic 中ؓ Nothing Q?/span>

DirectoryNotFoundException

指定的\径无效,比如在未映射的驱动器上?/span>

PathTooLongException

指定的\径、文件名或者两者都出了系l定义的最大长度。例如,在基?/span> Windows 的^CQ\径必d?/span> 248 个字W,文g名必d?/span> 260 个字W?/span>

IOException

path 包含不正或无效的文件名、目录名或卷标的语法?/span>

SecurityException

调用Ҏ有所要求的权限?/span>

 

1.2 JDK 1.4.2 :

public FileWriter(String fileName)  throws IOException

				Constructs a FileWriter object given a file name. 
		

Parameters:

fileName - String The system-dependent filename.

Throws:

IOException - if the named file exists but is a directory rather than a regular file, does not exist but cannot be created, or cannot be opened for any other reason

 

2 、解?/span>

.NET ?/span> Excetpion ?/span> Unchecked 异常Q客L不要求去 Check 代码Q但?/span> JAVA 的绝大部?/span> Checked 异常Q它要求客户端的代码异常?/span>

假设一个这L场景Q方?/span> OutMethod 调用 InnerMethod Q而内部方?/span> InnerMethod 抛出的异?/span> InnerException ?/span>

对于 Java ?/span> CheckedException Q或?/span> OutMethod L?/span> InnerException Q或?/span> OutMethod 捕捉 InnerException Q然后做处理Q?/span>

 

再来观察一?/span> JDK ?/span> FileWriter 的异常声明,我没有详l测试其在各U可能出错情况下抛出?/span> IOException 的消息,但是其分c远q不?/span> .NET ?/span> StreamWriter 。假?/span> Java 想照?/span> .NET ?/span> StreamWriter Q对?/span> Java 的用者来_无异于恶梦。外部的代码需要捕获如此多的异常消息(不捕捉就会在 OutMethod 抛出一大堆的异常,问题l箋传播下去Q这?/span> CheckException 的一个弱点)。也许正是出于这L问题Q所以此?/span> Java 接口的异常声明比较简单?/span>

那么假设我是一个库设计者,正在用到?/span> IO 。如果我使用 .NET q行开发,对于 IOException 来说Q我是否有必要捕捉呢Q捕捉的目的是ؓ了“处理”,那么对于库设计者,昄q时候需要通知其“客L序员”出错的原因Q所以这里的库设计者的行ؓ最好就是“不处理”。如果处理,那只能是?/span> catch 、再 throw ”。那么这L处理昄是无意义的,因ؓ原始异常已经以提醒客户E序员出错的原因了。如果捕捉,那代码会特别的丑陋(直接 catch Exception 的行为是不可取的Q?/span>

 

CheckedException 的另外一个缺点就是“将 Exceotion 加入?/span> Interface 的规格声明“。假?/span> OutMethod 调用?/span> InnerMethod Q此?/span> InnerMethod 的设计者需要增加一个异常,那么会直接媄响到 OutMethod 。当然这里的 InnerMethod 的设计者此时已l做了“修Ҏ口声明“的行ؓ?/span>

 

 


   随后待箋...... 

 

 



jinfeng_wang 2006-05-11 21:18 发表评论
]]>
试、构建和重构(zz)http://www.tkk7.com/jinfeng_wang/archive/2006/04/26/43358.htmljinfeng_wangjinfeng_wangWed, 26 Apr 2006 08:52:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2006/04/26/43358.htmlhttp://www.tkk7.com/jinfeng_wang/comments/43358.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2006/04/26/43358.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/43358.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/43358.html试、构建和重构
NUnit2.0详细使用Ҏ
重构啊重?/a>
.Net Code Cover
让代码更h可测试?/a>
NMock --- 从零开?/a>
Unit Test : rules,design and strategy
Concurrent connection limit
Log4Net Appender ?ADONetAppender
Bug理的流E和几个重点
把单元测试代码跟目代码攑֜一个工E中
Subversion配置安装教程Q三Q?
Subversion配置安装教程Q二Q?
Subversion配置安装教程Q一Q?/a>
敏捷QAMQ:TDD(Test Driven DevelopmentQ实践与变化-->TADQTest Assist Development)
如何?.CS文g中加入版本跟t信息?
推荐一个关?架构"的演C文E?PPT)
什麼是 LoadRunnerQ?
推荐一个不错的VS.NET集成单元试工具TestDriven.NET
实战dailybuild-cc.net的配|?/a>
[译] NMock 两分钟教E?/a>
[译] NMock ?/a>
试驱动开的的实例
让代码更h可测试?/a>
重构QRefactoringQ技巧读书笔?之三
W一ơ用CVS后的程结Q其实VSS也一P
我也再补充一个NANT使用注意事项
重构QRefactoringQ技巧读书笔?之二
重构QRefactoringQ技巧读书笔?之一
Bugzilla明用手?/a>
Daily Build 的链?/a>
Test-Driven Development In .NET 部分译文
有关于Refactor(重构)与Source(?的比?/a>
l于完成了DailyBuild
用MSBuild.... DailyBuild和Y件开发流E的东东
DailyBuild全攻?/a>
关于Peer Review、代码评审和试驱动{?/a>
试开发驱动实?/a>


jinfeng_wang 2006-04-26 16:52 发表评论
]]>
q求代码质量: 不要被覆盖报告所qh(zz)http://www.tkk7.com/jinfeng_wang/archive/2006/04/26/43340.htmljinfeng_wangjinfeng_wangWed, 26 Apr 2006 08:24:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2006/04/26/43340.htmlhttp://www.tkk7.com/jinfeng_wang/comments/43340.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2006/04/26/43340.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/43340.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/43340.html试覆盖工具对单元测试具有重要的意义Q但是经常被误用。这个月QAndrew Glover 会在他的新系?—?q求代码质量 中向您介l值得参考的专家意见。第一部分深入Cl覆盖报告中数字的真实含义。然后他会提出您可以早q经常地利用覆盖来确保代码质量的三个Ҏ?/blockquote>

您还记得以前大多数开发h员是如何q求代码质量的吗。在那时Q有技巧地攄 main() Ҏ被视为灵zM适当的测试方法。经历了漫长的道路以后,现在自动试已经成ؓ高质量代码开发的基本保证Q对此我很感谢。但是这q不是我所要感谢的全部。Java?开发h员现在拥有很多通过代码度量、静态分析等Ҏ来度量代码质量的工具。我们甚臛_l设法将重构分类成一pd便利的模式!

要获得有关代码质量问题的{案Q您可以讉K?Andrew Glover L?Code Quality 论坛?

所有的q些新的工具使得保代码质量比以前简单得多,不过您还需要知道如何用它们。在q个pd中,我将重点阐述有关保证代码质量的一些有时看上去有点秘的东ѝ除了带您一L悉有关代码质量保证的众多工具和技术之外,我还ؓ您说明:

  • 定义q有效度量最影响质量的代码方面?
  • 讑֮质量保证目标q照此规划您的开发过E?
  • 定哪个代码质量工具和技术可以满x的需要?
  • 实现最佛_践(清除不好的)Qɼ保代码质量及早q经常地 成ؓ开发实践中L且有效的斚w?

在这个月Q我首先看?Java 开发h员中最行也是最Ҏ的质量保证工具包Q测试覆盖度量?/p>

谨防上当

q是一个晚上鏖战后的早晨,大家都站在饮水机边上。开发h员和理人员们了解到一些经q良好测试的cd以达到超q?90% 的覆盖率Q正在高兴地互换着 NFL 风格的点心。团队的集体信心I前高涨。从q处可以听到 “放d重构吧?的声韻Ig~陷已成为遥q的记忆Q响应性也已微不道。但是一个很的反对声在_

奛_们,先生们,不要被覆盖报告所愚弄?/p>

现在Q不要误解我的意思:q不是说使用试覆盖工具是愚蠢的。对单元试范例Q它是很重要的。不q更重要的是您如何理解所得到的信息。许多开发团队会在这儿犯W一个错?/p>

高覆盖率只是表示执行了很多的代码Qƈ不意味着q些代码?i>很好?/i> 执行。如果您x的是代码的质量,必ȝ地理解试覆盖工具能做什么,不能做什么。然后您才能知道如何使用q些工具去获取有用的信息。而不是像许多开发h员那P只是满于高覆盖率?/p>



回页?/font>


试覆盖度量

试覆盖工具通常可以很容易地d到确定的单元试q程中,而且l果可靠。下载一个可用的工具Q对您的 Ant ?Maven 构徏脚本作一些小的改动,您和您的同事有了在饮水上谈论的一U新报告Q?i>试覆盖报告。当 foo ?bar q样的程序包令h惊奇地显C?i>?/i> 覆盖率时Q您可以得到不小的安慰。如果您怿臛_您的部分代码可以保证?“没?BUG?的,您会觉得很安心。但是这样做是一个错误?/p>

存在不同cd的覆盖度量,但是l大多数的工具会x行覆?/i>Q也叫做语句覆盖。此外,有些工具会报?i>分支覆盖。通过用一个测试工h行代码库q捕h个测试过E中与被 “触及?的代码对应的数据Q就可以获得试覆盖度量。然后这些数据被合成盖报告。在 Java 世界中,q个试工具通常?JUnit 以及名ؓ Cobertura、Emma ?Clover {的覆盖工具?/p>

行覆?/i>只是指出代码的哪些行被执行。如果一个方法有 10 行代码,其中?8 行在试中被执行Q那么这个方法的行覆盖率?80%。这个过E在M层次上也工作得很好:如果一个类?100 行代码,其中?45 行被触及Q那么这个类的行覆盖率就?45%。同P如果一个代码库包含 10000 个非注释性的代码行,在特定的试q行中有 3500 行被执行Q那么这D代码的行覆盖率是 35%?/p>

报告分支覆盖 的工兯囑ֺ量决{点Q比如包含逻辑 AND ?OR 的条件块Q的覆盖率。与行覆盖一P如果在特定方法中有两个分支,q且两个分支在测试中都被覆盖Q那么您可以说这个方法有 100% 的分支覆盖率?/p>

问题是,q些度量有什么用Q很明显Q很Ҏ获得所有这些信息,不过您需要知道如何用它们。一些例子可以阐明我的观炏V?/p>



回页?/font>


代码覆盖在活?/font>

我在清单 1 中创Z一个简单的cM具体表述cdơ的概念。一个给定的cd以有一q串的父c,例如 VectorQ它的父cL AbstractListQ?code>AbstractList 的父cd?AbstractCollectionQ?code>AbstractCollection 的父cd?ObjectQ?/p>
清单 1. 表现cdơ的c?/b>
												
														package com.vanward.adana.hierarchy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Hierarchy {
  private Collection classes;
  private Class baseClass;

  public Hierarchy() {
    super();
    this.classes = new ArrayList();
  }

  public void addClass(final Class clzz){
    this.classes.add(clzz);
  }
  /**
   * @return an array of class names as Strings
   */
  public String[] getHierarchyClassNames(){
    final String[] names = new String[this.classes.size()];        
    int x = 0;
    for(Iterator iter = this.classes.iterator(); iter.hasNext();){
       Class clzz = (Class)iter.next();
       names[x++] = clzz.getName();
    }        
    return names;
  }

  public Class getBaseClass() {
    return baseClass;
  }

  public void setBaseClass(final Class baseClass) {
    this.baseClass = baseClass;
  }
}

												
										

正如您看到的Q清?1 中的 Hierarchy cd有一?baseClass 实例以及它的父类的集合。清?2 中的 HierarchyBuilder 通过两个复制 buildHierarchy 的重载的 static Ҏ创徏?Hierarchy cR?/p>
清单 2. cdơ生成器
												
														package com.vanward.adana.hierarchy;

public class HierarchyBuilder {  

  private HierarchyBuilder() {
    super();		
  }

  public static Hierarchy buildHierarchy(final String clzzName) 
    throws ClassNotFoundException{
      final Class clzz = Class.forName(clzzName, false, 
          HierarchyBuilder.class.getClassLoader());        
      return buildHierarchy(clzz);
  }

  public static Hierarchy buildHierarchy(Class clzz){
    if(clzz == null){
      throw new RuntimeException("Class parameter can not be null");
    }

    final Hierarchy hier = new Hierarchy();
    hier.setBaseClass(clzz);

    final Class superclass = clzz.getSuperclass();

    if(superclass != 
      null && superclass.getName().equals("java.lang.Object")){
       return hier; 
    }else{      
       while((clzz.getSuperclass() != null) && 
          (!clzz.getSuperclass().getName().equals("java.lang.Object"))){
             clzz = clzz.getSuperclass();
             hier.addClass(clzz);
       }	        
       return hier;
    }
  }      
}

												
										





回页?/font>


现在是测试时_

有关试覆盖的文章怎么能缺测试案例呢Q在清单 3 中,我定义了一个简单的有三个测试案例的 JUnit 试c,它将试图执行 Hierarchy cd HierarchyBuilder c:


清单 3. 试 HierarchyBuilderQ?/b>
												
														package test.com.vanward.adana.hierarchy;

import com.vanward.adana.hierarchy.Hierarchy;
import com.vanward.adana.hierarchy.HierarchyBuilder;
import junit.framework.TestCase;

public class HierarchyBuilderTest extends TestCase {
  
  public void testBuildHierarchyValueNotNull() {        
     Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);
     assertNotNull("object was null", hier);
  }

  public void testBuildHierarchyName() {        
     Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);
     assertEquals("should be junit.framework.Assert", 
       "junit.framework.Assert", 
         hier.getHierarchyClassNames()[1]);      
  }

  public void testBuildHierarchyNameAgain() {        
     Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);
     assertEquals("should be junit.framework.TestCase", 
       "junit.framework.TestCase", 
         hier.getHierarchyClassNames()[0]);      
  }
 
}

												
										

因ؓ我是一个狂热的试人员Q我自然希望q行一些覆盖测试。对?Java 开发h员可用的代码覆盖工具中,我比较喜Ƣ用 CoberturaQ因为它的报告很友好。而且QCorbertura 是开放源码项目,它派生出?JCoverage 目的前w?/p>



回页?/font>


Cobertura 的报?/font>

q行 Cobertura q样的工具和q行您的 JUnit 试一L单,只是有一个用专门逻辑在测试时查代码以报告覆盖率的中间步骤Q这都是通过工具?Ant d?Maven 的目标完成的Q?/p>

正如您在?1 中看到的Q?code>HierarchyBuilder 的覆盖报告说明部分代?i>没有 被执行。事实上QCobertura 认ؓ HierarchyBuilder 的行覆盖率ؓ 59%Q分支覆盖率?75%?/p>
?1. Cobertura 的报?/b>

q样看来Q我的第一ơ覆盖测试是p|的。首先,带有 String 参数?buildHierarchy() ҎҎ没有被测试。其ơ,另一?buildHierarchy() Ҏ中的两个条g都没有被执行。有的是,所要关注的正是W二个没有被执行?if 块?/p>

因ؓ我所需要做的只是增加一些测试案例,所以我q不担心q一炏V一旦我到达了所x的区域,我就可以很好地完成工作。注意我q儿的逻辑Q我使用试报告来了解什?i>没有 被测试。现在我已经可以选择使用q些数据来增强测试或者l工作。在本例中,我准备增强我的测试,因ؓ我还有一些重要的区域未覆盖?/p>

CoberturaQ第二轮

清单 4 是一个更新过?JUnit 试案例Q增加了一些附加测试案例,以试囑֮全执?HierarchyBuilderQ?


清单 4. 更新q的 JUnit 试案例
												
														package test.com.vanward.adana.hierarchy;

import com.vanward.adana.hierarchy.Hierarchy;
import com.vanward.adana.hierarchy.HierarchyBuilder;
import junit.framework.TestCase;

public class HierarchyBuilderTest extends TestCase {
  
  public void testBuildHierarchyValueNotNull() {        
     Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);
     assertNotNull("object was null", hier);
  }

  public void testBuildHierarchyName() {        
     Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);
     assertEquals("should be junit.framework.Assert", 
       "junit.framework.Assert", 
         hier.getHierarchyClassNames()[1]);      
  }

  public void testBuildHierarchyNameAgain() { zo       
     Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);
     assertEquals("should be junit.framework.TestCase", 
       "junit.framework.TestCase", 
         hier.getHierarchyClassNames()[0]);      
  }

  public void testBuildHierarchySize() {        
     Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);
     assertEquals("should be 2", 2, hier.getHierarchyClassNames().length);
  }

  public void testBuildHierarchyStrNotNull() throws Exception{
    Hierarchy hier = 
       HierarchyBuilder.
       buildHierarchy("test.com.vanward.adana.hierarchy.HierarchyBuilderTest");
    assertNotNull("object was null", hier);
  }

  public void testBuildHierarchyStrName() throws Exception{        
    Hierarchy hier = 
       HierarchyBuilder.
       buildHierarchy("test.com.vanward.adana.hierarchy.HierarchyBuilderTest");
    assertEquals("should be junit.framework.Assert", 
      "junit.framework.Assert",
        hier.getHierarchyClassNames()[1]);
  }

  public void testBuildHierarchyStrNameAgain() throws Exception{
    Hierarchy hier = 
       HierarchyBuilder.
       buildHierarchy("test.com.vanward.adana.hierarchy.HierarchyBuilderTest");
    assertEquals("should be junit.framework.TestCase", 
      "junit.framework.TestCase",
        hier.getHierarchyClassNames()[0]);      
  }

  public void testBuildHierarchyStrSize() throws Exception{        
     Hierarchy hier = 
        HierarchyBuilder.
        buildHierarchy("test.com.vanward.adana.hierarchy.HierarchyBuilderTest");
     assertEquals("should be 2", 2, hier.getHierarchyClassNames().length);        
  }

  public void testBuildHierarchyWithNull() {
     try{
       Class clzz = null;
       HierarchyBuilder.buildHierarchy(clzz);
       fail("RuntimeException not thrown");
     }catch(RuntimeException e){}
  }
}

												
										

当我使用新的试案例再次执行试覆盖q程Ӟ我得C如图 2 所C的更加完整的报告。现在,我覆盖了未测试的 buildHierarchy() ҎQ也处理了另一?buildHierarchy() Ҏ中的两个 if 块。然而,因ؓ HierarchyBuilder 的构造器?private cd的,所以我不能通过我的试cL试它Q我也不兛_Q。因此,我的行覆盖率仍然只有 88%?/p>
?2. 谁说没有W二ơ机?/b>

正如您看到的Q用一个代码覆盖工?i>可以 揭露重要的没有相应测试案例的代码。重要的事情是,在阅L告(特别 是覆盖率高的Q时需要小心,它们也许隐含危险的信息。让我们看看两个例子Q看看在高覆盖率后面隐藏着什么?/p>



回页?/font>


条g带来的麻?/font>

正如您已l知道的Q代码中的许多变量可能有多种状态;此外Q条件的存在使得执行有多条\径。在留意q些问题之后Q我在清单 5 中定义一个极其简单只有一个方法的c:


清单 5.您能看出下面的缺陷吗Q?
												
														package com.vanward.coverage.example01;

public class PathCoverage {

  public String pathExample(boolean condition){
    String value = null;
    if(condition){
      value = " " + condition + " ";
    }
    return value.trim();
  }
}

												
										

您是否发C清单 5 中有一个隐藏的~陷呢?如果没有Q不要担心,我会在清?6 中写一个测试案例来执行 pathExample() Ҏq确保它正确地工作:


清单 6. JUnit 来救_
												
														package test.com.vanward.coverage.example01;

import junit.framework.TestCase;
import com.vanward.coverage.example01.PathCoverage;

public class PathCoverageTest extends TestCase {

  public final void testPathExample() {
    PathCoverage clzzUnderTst = new PathCoverage();
    String value = clzzUnderTst.pathExample(true);
    assertEquals("should be true", "true", value);
  }
}

												
										

我的试案例正确q行Q我的神奇的代码覆盖报告Q如下面?3 所C)使我看上d个超U明星,试覆盖率达C 100%Q?/p>
?3. 覆盖率明?

我想现在应该到饮水机边上去说了,但是{等Q我不是怀疑代码中有什么缺陷呢Q认真检查清?5 会发玎ͼ如果 condition ?falseQ那么第 13 行确实会抛出 NullPointerException?i>YeeshQ这儿发生了什么?

q表明行覆盖的确不能很好地指C测试的有效性?/p>



回页?/font>


路径的恐?/font>

在清?7 中,我定义了另一个包?indirect 的简单例子,它仍然有不能容忍的缺陗请注意 branchIt() Ҏ?if 条g的后半部分。(HiddenObject cd在清?8 中定义。)


清单 7. q个代码_?/b>
												
														package com.vanward.coverage.example02;

import com.acme.someotherpackage.HiddenObject;

public class AnotherBranchCoverage {
   
  public void branchIt(int value){
    if((value > 100) || (HiddenObject.doWork() == 0)){
      this.dontDoIt();
    }else{
      this.doIt();
    }
  }                             

  private void dontDoIt(){
    //don't do something...
  }

  private void doIt(){
    //do something!
  }   
}

												
										

呀Q清?8 中的 HiddenObject ?i>有害?/i>。与清单 7 中一P调用 doWork() Ҏ会导?RuntimeExceptionQ?/p>
清单 8. 上半部分Q?
												
														package com.acme.someotherpackage.HiddenObject;

public class HiddenObject {

  public static int doWork(){
    //return 1;
    throw new RuntimeException("surprise!");
  }
}

												
										

但是我的可以通过一个良好的试捕获q个异常Q在清单 9 中,我编写了另一个好的测试,以图挽回我的明星光环Q?/p>
清单 9. 使用 JUnit 规避风险
												
														package test.com.vanward.coverage.example02;

import junit.framework.TestCase;
import com.vanward.coverage.example02.AnotherBranchCoverage;

public class AnotherBranchCoverageTest extends TestCase {
    
  public final void testBranchIt() {
    AnotherBranchCoverage clzzUnderTst = new AnotherBranchCoverage();
    clzzUnderTst.branchIt(101);
  }    
}

												
										

您对q个试案例有什么想法?您也怼写出更多的测试案例,但是误想一下清?7 中不定的条件有不止一个的~短操作会如何。设惛_果前半部分中的逻辑比简单的 int 比较更复杂,那么?/i> 需要写多少试案例才能满意Q?/p>

仅仅l我数字

现在Q对清单 7?? 的测试覆盖率的分析结果不再会使您感到惊讶。在?4 的报告中昄我达C 75% 的行覆盖率和 100% 的分支覆盖率。最重要的是Q我执行了第 10 行!


?4.愚弄的报?/b>

从第一印象看,q让我骄傌Ӏ但是这个报告有什么误导吗Q只是粗略地看一看报告中的数字,会导致您怿代码是经q?i>良好试?/i>。基于这一点,您也怼认ؓ出现~陷的风险很低。这个报告ƈ不能帮助您确?or ~短操作的后半部分是一个定时炸弹!





回页?/font>


质量试

我不止一ơ地_您可以(而且应该Q用测试覆盖工具作为您的测试过E的一部分。但?i>不要被覆盖报告所愚弄。关于覆盖报告您需要了解的主要事情是,覆盖报告最好用来检查哪些代?i>没有l过 充分的测试。当您检查覆盖报告时Q找低的|q了解ؓ什么特定的代码没有l过充分的测试。知道这些以后,开发h员、管理h员以?QA 专业人员可以在真正需要的地方使用试覆盖工具。通常有下列三U情况:

  • 估计修改已有代码所需的时?
  • 评估代码质量
  • 评定功能试

现在我可以断定对试覆盖报告的一些用方法会您引入歧途,下面q些最佛_践可以得测试覆盖报告可以真正ؓ您所用?/p>

1. 估计修改已有代码所需的时?/font>

对一个开发团队而言Q针对代码编写测试案例自然可以增加集体的信心。与没有相应试案例的代码相比,l过试的代码更Ҏ重构、维护和增强。测试案例因为暗CZ代码在测试工作中?i>如何 工作的,所以还可以充当内行的文档。此外,如果被测试的代码发生改变Q测试案例通常也会作相应的改变Q这与诸如注释和 Javadoc q样的静态代码文档不同?/p>

在另一斚wQ没有经q相应测试的代码更难于理解和安全?/i> 修改。因此,知道代码有没有被试Qƈ看看实际的测试覆盖数|可以让开发h员和理人员更准地预知修改已有代码所需的时间?/p>

再次回到饮水上,可以更好地阐明我的观炏V?/p>

市场部的 LindaQ“我们想让系l在用户完成一W交易时?x 工作。这需要多长时间。我们的用户需要尽快实现这一功能。?

理人员 JeffQ“让我看看,q个代码?Joe 在几个月前编写的Q需要对业务层和 UI 做一些变动。Mary 也许可以在两天内完成q项工作。?

LindaQ“JoeQ他是谁Q?

JeffQ“哦QJoeQ因Z不知道自己在q什么,所以被我解雇了。?

情况g有点不妙Q不是吗Q尽如此,Jeff q是Q务分配给?MaryQMary 也认够在两天内完成工?—?切地说Q在看到代码之前Ҏq么认ؓ的?/p>

MaryQ“Joe 写这些代码时是不?i>睡着?/i>Q这是我所见过的最差的代码。我甚至不能认q是 Java 代码。除非推倒重来,要不我根本没法修攏V?

情况?“饮水机?团队不妙Q不是吗Q但是我们假设,如果在这个不q的事g的当初,Jeff ?Mary 拥有一份测试报告,那么情况会如何呢Q当 Linda 要求实现新功能时QJeff 做的W一件事是查以前生成的覆盖报告。注意到需要改动的软g包几乎没有被覆盖Q然后他׃?Mary 商量?/p>

JeffQ“Joe ~写的这个代码很差,l大多数没经q测试。您认ؓ要支?Linda 所说的功能需要多长时_?

MaryQ“这个代码很混ؕ。我甚至都不想看到它。ؓ什么不?Mark 来做呢??

JeffQ“因?Mark 不编写测试,刚被我解雇了。我需要您试q个代码q作一些改动。告诉我您需要多长时间。?

MaryQ“我臛_需要两天编写测试,然后我会重构q个代码Q增加新的功能。我xd需要四天吧。?

正如他们所说的Q知识的力量是强大的。开发h员可以在试图修改代码之前 使用覆盖报告来检查代码质量。同P理人员可以使用覆盖数据更好C计开发h员实际所需的时间?/p>

2. 评估代码质量

开发h员的试可以降低代码中存在缺L风险Q因此现在很多开发团队在新开发和更改代码的同旉要编写单元测试。然而正如前面所提到?Mark 一Pq不L在编码的同时q行单元试Q因而会D低质量代码的出现?/p>

监控覆盖报告可以帮助开发团队迅速找Z断增长的没有 相应试的代码。例如,在一周开始时q行覆盖报告Q显C项目中一个关键的软g包的覆盖率是 70%。如果几天后Q覆盖率下降C 60%Q那么您可以推断Q?/p>

  • 软g包的代码行增加了Q但是没有ؓC码编写相应的试Q或者是新增加的试不能有效地覆盖新代码Q?br />
  • 删除了测试案例?br />
  • 上述两种情况都发生了?

能够监控事情的发展,无疑是g好事。定期地查阅报告使得讑֮目标Q例如获得覆盖率、维护代码行的测试案例的比例{)q监控事情的发展变得更ؓҎ。如果您发现试没有如期~写Q您可以提前采取一些行动,例如对开发h员进行培训、指导或帮助。与其让用户 “在使用中?发现E序~陷Q这些缺h应该在几个月前通过单的试暴露出来Q,或者等到管理h员发现没有编写单元测试时再感到惊Ӟ和愤怒)Q还不如采取一些预防性的措施?/p>

使用覆盖报告来确保正的试是一伟大的实践。关键是要训l有素地完成q项工作。例如,使每晚生成ƈ查阅覆盖报告成ؓq箋累计 q程的一部分?/p>

3. 评定功能试

假设覆盖报告在指?i>没有l过 _试的代码部分方面非常有效,那么质量保证人员可以使用q些数据来评定与功能试有关的关注区域。让我们回到 “饮水机?团队来看?QA 的负责h Drew 是如何评?Joe 的代码的Q?/p>

Drew ?Jeff _“我们ؓ下一个版本编写了试案例Q我们注意到很多代码没有被覆盖。那好像是与股票交易有关的代码。?

JeffQ“哦Q我们在q个领域有好些问题。如果我是一个赌徒的话,我会对这个功能区域给予特别的x。Mary 正在对这个应用程序做一些其他的修改 —?她在~写单元试斚w做得很好Q但是这个代码也太差了点。?

DrewQ“是的,我正在确定工作的资源和别,看上L没必要那么担心了Q我估计我们的团队会对股交易模块引赯够的x。?

知识再次昄了其强大的力量。与其他软g生命周期中的风险承担者(例如 QAQ配合,您可以利用覆盖报告所提供的信息来降低风险。在上面的场景中Q也?Jeff 可以?Drew 的团队提供一个早期的不包?Mary 的所有修改的版本。不q无论如何,Drew 的团队都应该x应用E序的股交易方面,与其他具有相应单元测试的代码相比Q这个地方似乎存在更大的~陷风险?/p>



回页?/font>


试有什么好?/font>

对单元测试范例而言Q测试覆盖度量工h一个有点奇怪的l成部分。对于一个已存在的有益的q程Q覆盖度量可以增加其深度和精度。然而,您应该仔l地阅读代码覆盖报告。单独的高覆盖率q不能确保代码的质量。对于减缺P代码的高覆盖q不是必要条Ӟ管高覆盖的代码的确更少 有缺陗?/p>

试覆盖度量的窍门是使用覆盖报告扑և未经 试的代码,分别在微观和宏观两个U别。通过从顶层开始分析您的代码库Q以及分析单个类的覆盖,可以促进深入的覆盖测试。一旦您能够l合q些原则Q您和您的组l就可以在真正需要的地方使用覆盖度量工具Q例如估计一个项目所需的时_持箋监控代码质量以及促进?QA 的协作?/p>


jinfeng_wang 2006-04-26 16:24 发表评论
]]>
或许对YM很不公^,但他会勇敢的去面对不可能的Q?zz from hchttp://www.tkk7.com/jinfeng_wang/archive/2006/03/14/35197.htmljinfeng_wangjinfeng_wangTue, 14 Mar 2006 03:16:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2006/03/14/35197.htmlhttp://www.tkk7.com/jinfeng_wang/comments/35197.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2006/03/14/35197.html#Feedback1http://www.tkk7.com/jinfeng_wang/comments/commentRss/35197.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/35197.html
    q个世界上有很多奇怪的不公q?比如说你永远没办法理解ؓ什么中国的要黑会这么多,一个像YMq样对中国体育做出如此多贡献而且公众形象完美无缺的年Mh到底哪里得罪了他?会让他们如此不遗余力的去黑他.
    
     你同h办法理解,在这个如今充满了高薪低能和满大话的NBA联盟里面,像YMq样一个勤勤恳?谦虚谨慎的h居然会排在被高估球员榜的W二?唯一排在他前面的那个人目前球队成l联盟倒第一而他却自U自׃ؓ天下W一PG,而那个拿着上千万年?自称自己是联盟第二中锋如今却只能l一个塞内加无名小子打替补的丹皮尔却可以在被高估傍上名落孙?

     今天的比赛如果以一个要qL角度看或许ƈ不糟p?YMl箋不错的发?拿下全场最漂亮的数?25?0??助而且只有一个失?火箭在TMAC和威思利两大d同时受伤的情况下(TMAC是火第一得分?威思利是火最准的外线投手和最好的外线防守队员),仍然跟卫冕冠?d成W高达26?负的马刺拼C最?是的,q个l果很另人欣C.但如果你看了赛后国媒体的报?你的心情恐怕就没有q么ƣ慰?

     YAHOO的赛后报道用了一半以上的文字Lq基诺比例和芬利在YM面前的那两个扣篮,同时q不忘附上这两个人在赛后采访中对q两个扣感?YAHOO对这两个扣篮的描q相当的生动,l对能让你有w其境的感?而如果你惌力不够的话也不要?要黑电台ESPN今天晚上肯定会把q两个扣放?00ơ的.接下来他们又不忘夸奖TD在第四节的表.,当然最后也提了一下YM25分的全场最高分,可他们同时强调了17分是上半场得到的.NBA.COM的报道也大同异,重点描述了那两个扣篮?特别说明了YM在马刺反比赛的W三节里只得C2?没错,q就是美国媒体对q场比赛的赛后分?无视YM在马刺多人包多w守下L42分钟是多么的不易,无视火箭的h员不整以及角色球员跟马刺队员的差?他们只是一股脑地把火箭输球的责d推给了YM,把他描述成一个关键时L法得分ƈ且被个子暴头的软蛋.

     q确实是很不公^,但现实就是这么的D忍,成王败寇是竞技Z永远不变的真?作ؓ领袖人物,只要球队输球,不论你个人的表现如何,你都要去承担责Q,像今天湖l了音?KB也没在媒体的赛后分析里得C么好?国媒体的宠儿KB且如此待遇,YM更不用说了.国的媒体从来就对他十分的苛d~Z耐心.像巴克利q样伟大的球员当q居然只看了5场比赛就lYM判了d,说他永远得不?9?投c_更甚,他在当了评论员后,只要提到YM׃停的YM的极限也是当年的荷Ch史密?q些NBA的老一代对外籍球员(特别YMq是亚洲球员)的藐视与不屑是根p固的.所以在YM拿到d军之?永远不要指望q些专家们会lYM什么公正的评h.

     在竞技体育里面,q有一条真理跟成王败寇同样不可颠覆,那就是ONE PERSON DOSENT MAKE A TEAM,没有人可以靠一׃力去赢得比赛,q已l被证明了无数次?

    狼王KG是一个非常好的例?作ؓ联盟的效率王,KGq些q的表现一直惊人的E_,单看个h数据他几乎年q都是MVP的水?但角色球员的不同却决定了他球队的成W.当他w边有好的帮手的时?KG可以带队打进襉K册,拿下MVP.可当角色球员的实力不的时?虽然他个C旧神勇无?但球队只能常q止步季后赛W一?甚至在最q两q连l无~PLAYOFF.

    KB的情况也是如?今年他个人的表现已经接近半神,q_得分?5,单场81分都是近乎神奇的表演,可即便他个h能力如此,再加上菲这L大师指教,湖h如今仍然只有33?1负的季后赛边~成l?在球?哥奥多姆受伤的三场比赛里,KB們ְ全力仍不能避免湖Zq|,不仅被步行者横?6?甚至被联盟垫底的q拿下.而在不堪回首的去q?׃伤病和角色球员能力不?KB在最?0场比赛里孤掌N,湖h不得不最l吞??8负的苦果.

    火箭的一哥TMAC当年也有跟KBcM的经?02-03赛季,打出职业生最佌现的他在拿下得分王的同时入选联盟第一阵容,而且当时术的阵容虽然受到HILL合同的媄响算不上豪华,但v码还有最佳第六h阿姆思特朗和最x人米勒这L当不错的选手.管如此,球队的最l成l也只有42?0?q西部第九的火箭成W都比他强.而且q个成Wq是在当时整体实力薄q东部取得?03-04赛季,失去了阿姆思特朗和c_q两位帮?TAMC虽然q可拿下得分?但球队开?0场比赛里只有1?9?最l联盟垫?

    现在的YM获得的评仯没有KG,KB,TMAC那么?可摆在他面前?0场比赛却比当q的KB,TMAC?0要恐?在主力受?龙套实力不济的情况下,YM要率领球寚w对一个真正魔鬼的赛程.先是q箋8场面对胜?成的Ҏ,包括与西部霸d牛马刺的4?外加客场挑战对火势在必得的黄蜂和复仇心切的快船.而在四月?q有一?q客在等待着他们.火箭要想q入PLAYOFF的话,在这鬼般的20场比赛里L要拿?4Z是70%的胜?在TMAC和威思利都受伤的情况?q已l不能说是严ȝ考验,而完全算是一个不可能完成的Q?如果从纸面上的实力分?如果Ҏ完全正常发挥而火其他球员不常,那么qYM在这20场比赛里场场拿下30/10,火箭胜利的场ơ也不会过5?
            
    事实上除了发生奇q外,火箭成W不佳而YM数据是最?0场里可能出现的最乐观的情况了.但如果真的出现这U情?不要天真的指望美国媒体会因ؓYM数据把他说成孤胆英?他们才不会把火箭成W不佳的责dl给赛程,角色球员的实力和病榻上的TMAC.无视YM的努?把他说成一个无法领导球队的软蛋和废物才是他们的方式.不要怀?整整四年以来,他们一直在不遗余力的这么做.l对不要d望他们会lYM一个公q的评h.

    很奇?当YM面对不可能的d和很可能随之而来的不公正的评L时?我这个要q居然一点也不ؓ他担?估计q也是看YM打球多年ȝ出来的吧.因ؓ从YM出道那天开?挑战不可能的d对他来说像家常侉K一?我已l记不清q些q来他搞定了多少所谓的"不可??

    q记得十q前?如果有h跟我?那个在卢家湾体育Z一场比赛要?0个跟头的大竹杆有一天会过WZZ,会颠覆八一王朝,我肯定会对他蔑视的一W?q?不可?q三个字都懒得说,而如果谁当时说YM会进NBA,而且会成为状元秀,他n旁的朋友说不定会立刻煽他一耛_,告诉?你Y快醒?别TMD大白天说梦话.

    q记得四q前?NBA的名宿查斯爵士曄毫不犹U的宣?单场19分是YM不可能完成的d,他甚至ؓ此打赌在几亿电视观众面前M驴屁?

    q记得两q前的夏天吗?全世界的人都认ؓ中国队不可能战胜塞黑q入奥运??q被许多成BT要迷的CCTV5都放弃对YM的期望了,CCTV5先是在下午的奥运会报道里调侃YM的胡?接下来更是在塞黑和中国的生死大战前一个小时就宣布八强寚w是欧z冠军立陶宛对世界冠军塞?

    q上面那些往事你都记不清?那你M会忘记就在仅仅三个月以前,q有9成的球迷不相信今q的YM可以打出20/10的^均数?认ؓq绝Ҏ不可能的d?

    当然q次YM面对的挑战比上面那些更加可?以火现在的情况和赛E来?惌qPLAYOFF,q是状态最x的飞ZҎ?没有逆天的好q气也是完全没有希望?理性的来看,火箭胜少负多是肯定的,甚至很有可能像去q的KB和前q的MD那样20场比赛里1胜N?

   但我怿YM不会被失败击?q在接下来?0场比赛里全负,qNBA.COM的首大标题变成"YM是个废物."我仍然相信他不会?因ؓ如果他是一个这么容易就下的h,早在十几q前,姚妈妈领着q是孩子的YM满怀希望的去看国内的球名宿,却得C一?"没有天赋,难成大气,q不及WZZ."的评语的时?他就会放弃NBA的梦想了如果YM是那么容易放弃的?那么早在02q先是国安兵|世界锦标赛和釜山亚运?然后他作为NBA状元却在W一场比赛一分ؓ得的时候就垮了.正因去这些种U的压力和不公正的评价他都抗了过?所以我怿不管接下来的火箭队成l如?不管国的专家媒体在赛季l束会给YM一个什么样的评?他都会精饱满的出现在今q夏天的世界锦标赛上,I上国家队的战袍,像全世界展现他FIBA比赛里第一中锋的威?而在接下来的06-07赛季,他也一定会再次生龙z虎的去l箋搏杀,毫不q疑的面Ҏ?

    我最早看YM打球的时候也不喜Ƣ他,直到他去了NBA才出于同胞的原因开是支持他.如今看YM打球看了q么多年,虽然谈不上对真正的YM有多么了?但也多少可以看到他某些真实的一?YM作ؓ一个来自篮球第三世界的外籍球员,能够在n体素质BT如云的NBA走到今天q步,l对不是靠他那除了n高外一无是处的w体素质.扒掉q个男h所谓天才的外衣,真正支持他成功的是他惊h的勤奋和面对挫折时超乎寻常的坚强意志.正像YM的主教练范甘q说的那?M一个h如果能像YM那么努力的话,他都会取得自己所能取得的最大成?在NBA?凭借父母给的好w板而在生理上比YM"汉"的h多得Cq来,但这些h中能在心理上比YM坚强?汉"却只是屈指可?而这才是是我现在喜欢,怿YM的最大原?

jinfeng_wang 2006-03-14 11:16 发表评论
]]>
Comparing Web Frameworks (zz)http://www.tkk7.com/jinfeng_wang/archive/2005/04/30/3959.htmljinfeng_wangjinfeng_wangSat, 30 Apr 2005 03:01:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2005/04/30/3959.htmlhttp://www.tkk7.com/jinfeng_wang/comments/3959.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2005/04/30/3959.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/3959.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/3959.htmldownload URL : https://equinox.dev.java.net/framework-comparison/WebFrameworks.pdf

Comparing Web Frameworks:
Struts, Spring MVC, WebWork, Tapestry &
JSF
Matt Raible
www.raibledesigns.com
!ww.raibledesigns.co"

Who is Matt Raible?
. Developing websites since 1994 (before Netscape 1.0)
- Developing in J2EE webapps since 1999
. Committer on several open source projects:Roller
Weblogger, XDoclet, Struts Menu, Display Tag, AppFuse
. J2EE 5.0 Expert Group Member
. Author: Spring Live (SourceBeat) and contributor to
Pro JSP (Apress)
!ww.raibledesigns.co" !ww.springlive.co"

Framework Experience
. Struts: used since June 2001 - same time 1.0 was
released.
. Spring MVC: used since January 2004 - before 1.0
was released.
. WebWork: used since July 2004.
. Tapestry: used since July 2004.
. JSF: used since July 2004 - both Sun’s RI and
MyFaces.
!ww.raibledesigns.co"

Meet the Candidates
!ww.raibledesigns.co"

Struts
. Pros:
. The “Standard?- lots of Struts jobs
. Lots of information and examples
. HTML tag library is one of the best
. Cons:
. ActionForms - they’re a pain
. Can’t unit test - StrutsTestCase only does integration
. Mailing list volume is overwhelming
!ww.raibledesigns.co"

Spring MVC
!ww.raibledesigns.co"
. Pros:
. Lifecyle for overriding binding, validation, etc.
. Integrates with many view options seamlessly: JSP/JSTL,
Tiles, Velocity, FreeMarker, Excel, XSL, PDF
. Inversion of Control makes it easy to test
. Cons:
. Not many using it
. Requires writing lots of code in JSPs
. Almost too flexible - no common parent Controller

WebWork
!ww.raibledesigns.co"
. Pros:
. Simple architecture - easy to extend
. Tag Library is easy to customize - backed by Velocity
. Interceptors are pretty slick
. Cons:
. Documentation only recently written, few examples
. Client-side validation immature

Tapestry
!ww.raibledesigns.co"
. Pros:
. Very productive once you learn it
. Templates are HTML - great for designers
. Healthy and smart user community
. Cons:
. Documentation very conceptual, rather than pragmatic
. Steep learning curve - very few examples
. Impossible to test - page classes are abstract

JSF
!ww.raibledesigns.co"
. Pros:
. J2EE Standard - lots of demand and jobs
. Fast and easy to develop with
. Rich Navigation framework
. Cons:
. Tag soup for JSPs
. Immature technology - doesn’t come with everything
. No single source for implementation

Controllers and Views
. Struts: UserAction extends DispatchAction
. Spring MVC: UserFormController extends
SimpleFormController
. WebWork: UserAction extends ActionSupport
. Tapestry: UserForm extends BasePage
. JSF: UserForm
!ww.raibledesigns.co"

List Screens
. How easy is it to integrate a sortable/
pageable list of data?
. Struts, Spring MVC and WebWork can all
use Tag Libraries like the Display Tag
. Tapestry has a contrib:Table component
. JSF has a dataTable with no sorting - have
to write your own logic if you want it
!ww.raibledesigns.co"

Bookmarking and URLs
. Using container-managed authentication (or other filterbased
security systems) allow users to bookmark pages.
They can click the bookmark, login and go directly to the
page.
. WebWork has namespaces - makes it easy
. Struts and Spring allow full URL control
. Tapestry has ugly URLs - difficult to segment the app for
different roles
. JSF does a POST for everything
!ww.raibledesigns.co"

Validation
. Validation should be easy to configure, be robust on the
client side and either provide good out of the box messages
or allow you to easily customize them.
. Struts and Spring MVC use Commons Validator - a
mature solution
. WebWork uses OGNL for powerful expressions -
client-side support very new
. Tapestry has very robust validation - good messages
without need to customize
. JSF - ugly default messages, but easiest to configure
!ww.raibledesigns.co"

Testability
. Struts - can use StrutsTestCase
. Spring and WebWork allow easy testing with
mocks (i.e. EasyMock, jMock, Spring Mocks)
. Tapestry is impossible to test because page classes
are abstract
. JSF page classes can be easily tested and actually
look a lot like WebWork actions
!ww.raibledesigns.co"

Success Messages
. The duplicate-post problem, what is it?
. Easiest way to solve: redirect after POST
. Struts is the only framework that allows success
messages to live through a redirect
. Spring and WebWork require custom solutions
. Tapestry requires you to throw an Exception to redirect
. JSF requires a custom solution, i18n messages difficult to
get in page beans
!ww.raibledesigns.co"

Spring Integration
. All frameworks have integration with Spring
. Struts: ContextLoaderPlugin and Base classes
. WebWork: SpringObjectFactory
. Tapestry: override base engine, grab from servlet
context, put into global map
. JSF: DelegateVariableResolver or JSF-Spring Library
!ww.raibledesigns.co"

Internationalization
. JSTL’s <fmt:message> tag makes it easy
. No standard for getting i18n messages in
controller classes
. Struts, Spring and JSF encourage one
ResourceBundle per locale
. WebWork and Tapestry advocate separate
files for each page/action
!ww.raibledesigns.co"

Page Decoration
. Used Tiles since it first came out in 2001
. SiteMesh is much easier to setup and use
. Tiles can be used in Struts, Spring and JSF
. Requires configuration for each page
. SiteMesh can be used with all frameworks
. Requires very little maintenance after
setup
!ww.raibledesigns.co"

Tools
. Struts has a lot of IDE support and even has
frameworks built on top of it (i.e. Beehive’s
PageFlow)
. Spring has Spring IDE - only does XML validation,
not a UI/web tool
. WebWork has none
. Tapestry has Spindle - great for coders
. JSF has many, all cost money and hook into
proprietary app servers
!ww.raibledesigns.co"

Business/Marketing
. Struts is still in high-demand and widely-used
. Spring is getting more press, but mostly due to the
framework’s other features
. WebWork is gaining ground, but pretty scarce on
job boards
. Tapestry is even more scarce - needs more
marketing
. JSF is quickly becoming popular
!ww.raibledesigns.co"

Dice Job Count
October 15, 2004
0
375
750
1,125
1,500
Struts
Spring Framework
WebWork
Tapestry
JSF
!ww.raibledesigns.co"

My Opinion
. Struts is fast to develop with because most problems have
been solved. HTML tag library the best of the bunch.
. Spring is nice, but lack of form tags drops it down a notch
or two. JSP 2.0 tag files exist in issue tracker.
. I like WebWork a lot, but lack of of good client-side
validation support is a killer.
. Tapestry - I haven’t finished the learning curve.
. JSF - needs to listen to developers to see what they want
instead of tools vendors.
!ww.raibledesigns.co"

Which would I choose?
. Quick and dirty project?
. Struts because I know it best
. Massive enterprise project?
. Tapestry for its reusable components
. If I got a job as an open source developer?
. WebWork because using it requires you
to dig into the frameworks
!ww.raibledesigns.co"

Resources
. Download sample apps for this presentation
. http://equinox.dev.java.net/framework-comparison
. Struts - http://struts.apache.org
. StrutsTestCase: http://strutstestcase.sf.net
. Spring MVC - http://www.springframework.org
. Spring IDE: http://www.springframework.org/spring-ide/eclipse
. WebWork - http://opensymphony.org/webwork
. Eclipse Plugin: http://sf.net/projects/eclipsework
. IDEA Plugin: http://wiki.opensymphony.com/display/WW/IDEA+Plugin
!ww.raibledesigns.co"

Resources, cont.
. Tapestry - http://jakarta.apache.org/tapestry
. Spindle: http://spindle.sourceforge.net
. JSF - http://java.sun.com/j2ee/javaserverfaces and http://
myfaces.org
. Java Studio Creator: http://sun.com/software/products/jscreator
. MyEclipse: http://myeclipseide.com
. IDEA: http://www.jetbrains.com/idea
. SiteMesh: http://opensymphony.com/sitemesh
!ww.raibledesigns.co"

Resources, cont.
. Testing Frameworks
. JUnit: http://junit.org
. EasyMock: http://easymock.org
. jMock: http://jmock.org
. jWebUnit: http://jwebunit.sourceforge.net
. Canoo WebTest: http://webtest.canoo.com
. XDoclet - http://xdoclet.sourceforge.net
. AppFuse - http://appfuse.dev.java.net
!ww.raibledesigns.co"

Books
. Struts in Action, Ted Husted and Team
. Struts Live, Rick Hightower and Jonathan Lehr
. Spring Live, Matt Raible
. Spring in Action, Craig Walls and Ryan Breidenbach
. Professional Java Development with Spring, Rod
Johnson, Juergen Hoeller and Team

Books, cont.
. WebWork in Action, Patrick Lightbody and Team
. Tapestry in Action, Howard Lewis Ship
. Core JSF, David Geary and Cay Horstmann
. JSF in Action, Kito Mann

The End
...or is it just the beginning...
!ww.raibledesigns.co"

 



jinfeng_wang 2005-04-30 11:01 发表评论
]]>
学习的一个过E?zz)http://www.tkk7.com/jinfeng_wang/archive/2005/04/30/3958.htmljinfeng_wangjinfeng_wangSat, 30 Apr 2005 02:59:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2005/04/30/3958.htmlhttp://www.tkk7.com/jinfeng_wang/comments/3958.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2005/04/30/3958.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/3958.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/3958.html学习的一个过E?BR>
头一天听到XX事物Q啊Q真是个好东?...一定要学好?BR>W二天,学习了一下,啊太难了Q太ȝ?...鬼知道h们ؓ什么说他好
W三天,仔细用了一下,原来q么单,直是太简单了Q这么简单的东东Q居然这么多?BR>W三天,看v来,自己对它的了解还不够?BR>W四天,不是不够而是非常不够Q看hq得认真学习
W五天,再也不敢说对它有了解了,直是高深莫测?BR>W六天,感觉q个东东比较有意思,原来q可以这个样子的?BR>W七天,好象q么做,可以完成以前不敢想的事情了
W八天,现在用得很好了,你个呆瓜Q怎么说这个东东不好?o原来你是菜鸟?BR>W九天,q个东东Q如果能q样一些就更好了?/FONT>


对照一下自己,学的好多东西都还是停留在3??啊! 叹~

jinfeng_wang 2005-04-30 10:59 发表评论
]]>
SiteMesh resources(zz)http://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3192.htmljinfeng_wangjinfeng_wangTue, 12 Apr 2005 13:42:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3192.htmlhttp://www.tkk7.com/jinfeng_wang/comments/3192.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3192.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/3192.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/3192.htmlSiteMesh is a web-page layout and decoration framework and web- application integration framework to aid in creating large sites consisting of many pages for which a consistent look/feel, navigation and layout scheme is required.

External Documentation

User Contributed docs

Release Notes

Developer Notes



jinfeng_wang 2005-04-12 21:42 发表评论
]]>
使用sitemesh建立复合视图(ZZ)http://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3191.htmljinfeng_wangjinfeng_wangTue, 12 Apr 2005 13:31:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3191.htmlhttp://www.tkk7.com/jinfeng_wang/comments/3191.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3191.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/3191.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/3191.html huihoo.com
发布)

sitemesh是opensymphony团队开发的j2ee应用框架之一Q旨在提高页面的可维护性和复用性。opensymphony的另一个广Zh知的框架为webwork是用作web层的表示框架。他们都是开源的Q可以在www.sf.net下找到?/B>

应用于以下大目的例子:http://opensource.thoughtworks.com/projects/sitemesh.html

介:
sitemesh应用Decorator模式Q用filter截取request和response,把页面组件head,content,bannerl合Z个完整的视图。通常我们都是用include标签在每个jsp面中来不断的包含各Uheader, stylesheet, scripts and footerQ现在,在sitemesh的帮助下Q我们可以开心的删掉他们了。如下图Q你惌杄辑ֈ复合视图模式Q那末看完本文吧?/FONT>

 

hello sitemeshQ?/FONT>
  1. 在WEB-INF/web.xml中copy以下filter的定?
    <filter>
      <filter-name>sitemesh</filter-name>
      <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
    </filter>
    
    <filter-mapping>
      <filter-name>sitemesh</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <taglib>
      <taglib-uri>sitemesh-decorator</taglib-uri>
      <taglib-location>/WEB-INF/sitemesh-decorator.tld</taglib-location>
    </taglib>
    
    <taglib>
      <taglib-uri>sitemesh-page</taglib-uri>
      <taglib-location>/WEB-INF/sitemesh-page.tld</taglib-location>
    </taglib>
    

  2. copy所需jar和dtd文g至相应目录,讉Kopensymphony.sourceforge.net的cvs以获取sitemesh最新版本?/FONT>
    sitemesh.jar WEB-INF/lib
    sitemesh-decorator.tld WEB-INF
    sitemesh-page.tld WEB-INF

  3. 建立WEB-INF/decorators.xml描述各装饰器面(可仿照sitemesh例子)?/FONT>
    <decorators defaultdir="/_decorators">
        <decorator name="main" page="main.jsp">
            <pattern>*</pattern>
        </decorator>
    </decorators>



  4. 建立装饰器页?/_decorators/main.jsp
    <%@ page contentType="text/html; charset=GBK"%>
    <%@ taglib uri="sitemesh-decorator" prefix="decorator" %>
    
    <html>
      <head>
        <title><decorator:title default="装饰器页?.." /></title>
        <decorator:head />
      </head>
      <body>
        sitemesh的例?lt;hr>
        <decorator:body />
        <hr>chen56@msn.com
      </body>
    </html>
    


  5. 建立一个的被装饰页?/index.jsp(内容面)
    <%@ page contentType="text/html; charset=GBK"%>
    <html>
      <head>
        <title>Agent Test</title>
      </head>
      <body>
        <p>本页只有一句,是本句.</p>
      </body>
    </html>

最后访问index.jspQ将生成如下面Q?/FONT>

而且Q所有的面也会如同index.jsp一P被sitemesh的filter使用装饰模式修改成如上图般模P却不用再使用include标签?BR>

装饰?nbsp; decorator概念
建立可复用的web应用E序,一个通用的方法是建立一个分层系l,如同下面一个普通的web应用Q?/FONT>
  • 前端Qfront-end:JSP和ServletsQ或jakarta的velocity
  • 控制层框?Controller Q?(Struts/Webwork)
  • 业务逻辑 Business Q主要业务逻辑
  • 持久化框?Qhibernate/jdo

可糟p的是前端的面逻辑很难被复用,当你在每一个页面中用数之不的include来复用公qheader, stylesheet, scriptsQfooterӞ一个问题出C-重复的代码,每个面必须用copy来复用页面结构,而当你需要创意性的改变面l构ӞNq上了你?/FONT>

sitemesh通过filter截取request和responseQƈl原始的面加入一定的装饰(可能为header,footer...)Q然后把l果q回l客LQƈ且被装饰的原始页面ƈ不知道sitemesh的装饎ͼq也pCp的目的?/FONT>

据说卛_新出台的Portlet规范会帮助我们标准的实现比这些更多更cool的想法,但可怜的我还不懂它到底是一个什末东东,有兴的人可以研I?BR>jetspeedQ或JSR (Java Specification Request) 168,但我想sitemesh如此单,我们不妨先用着?/FONT>

 

让我们看看怎样配置环境
除了要copy到WEB-INF/lib中的sitemesh.jar, copy到WEB-INF中的sitemesh-decorator.tld,sitemesh-page.tld文g外,q有2个文件要建立到WEB-INF/Q?/FONT>
  • sitemesh.xml (可?  
  • decorators.xml 

sitemesh.xml 可以讄2U信?

Page Parsers Q负责读取stream的数据到一个Page对象中以被SiteMesh解析和操作?不太常用Q默认即?

Decorator Mappers : 不同的装饰器U类Q我发现2U比较有用都列在下面。一U通用的mapper,可以指定装饰器的配置文g名,另一U可打印的装饰器Q可以允怽当用http://localhost/aaa/a.html?printable=true方式讉K时给出原始页面以供打?免得把header,footer{的花哨的图片也搭上)

(但一般不用徏立它Q默认设|够了Qcom/opensymphony/module/sitemesh/factory/sitemesh-default.xmlQ:

范例Q?/B>

<sitemesh>
  <page-parsers>
    <parser default="true" class="com.opensymphony.module.sitemesh.parser.DefaultPageParser" />
    <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
    <parser content-type="text/html;charset=ISO-8859-1" class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
  </page-parsers>

  <decorator-mappers>
    <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
      <param name="config" value="/WEB-INF/decorators.xml" />
    </mapper>
      <mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper">
         <param name="decorator" value="printable" />
         <param name="parameter.name" value="printable" />
                 <param name="parameter.value" value="true" />
      </mapper>
  
</decorator-mappers>
</sitemesh>

decorators.xml Q定义构成复合视囄所有页面构件的描述(主要l构面Qheader,footer...)Q如下例Q?/FONT>

<decorators defaultdir="/_decorators">
  <decorator name="main" page="main.jsp">
    <pattern>*</pattern>
  </decorator>
  <decorator name="printable" page="printable.jsp" role="customer" webapp="aaa" />
</decorators>

 

  • defaultdir: 包含装饰器页面的目录
  • page : 面文g?/FONT>
  • name : 别名
  • role : 角色Q用于安?/FONT>
  • webapp : 可以另外指定此文件存攄?/FONT>
  • Patterns : 匚w的\径,可以?,那些被访问的面需要被装饰?/FONT>

 

最重要的是写出装饰器本w?也就是那些要复用面Q和l构面)?/FONT>
其实Q重要的工作是制作装饰器页面本w?也就是包含结构和规则的页?Q然后把他们描述到decorators.xml中?/FONT>

让我们来先看一看最单的用法Q其实最常用也最单的用法是我们的hello例子Q面对如此众多的技术,我想只要辑ֈ功能点到为止卛_Q没必要ȝI太?除非您有更深的需??/FONT>

<%@ page contentType="text/html; charset=GBK"%>
<%@ taglib uri="sitemesh-decorator" prefix="decorator" %>

<html>
  <head>
    <title><decorator:title default="装饰器页?.." /></title>
    <decorator:head />
  </head>
  <body>
    sitemesh的例?lt;hr>
    <decorator:body />
    <hr>chen56@msn.com
  </body>
</html>

我们在装饰器面只用?个标{:

<decorator:title default="装饰器页?.." />    Q?把请求的原始面的title内容插入?lt;title></title>中间?/FONT>

<decorator:body /> Q?把请求的原始面的body内的全部内容插入到相应位|?/FONT>

然后我们在decorator.xml中加入以下描q即可:

<decorator name="main" page="main.jsp">
    <pattern>*</pattern>
</decorator>

q样Q请求的所有页面都会被重新处理Qƈ按照main.jsp的格式重新展现在你面前?/FONT>

 

让我们看看更多的用法?抄袭sitemesh文档)
以下列着全部标签Q?/FONT>
Decorator Tags Page Tags
被用于徏立装饰器面. 被用于从原始内容面讉K装饰?
<decorator:head />
<decorator:body />
<decorator:title />
<decorator:getProperty />
<decorator:usePage />
<page:applyDecorator />
<page:param
 

<decorator:head />

插入原始面(被包装页?的head标签中的内容(不包括head标签本n)?/FONT>

<decorator:body />

插入原始面(被包装页?的body标签中的内容?/FONT>

<decorator:title [ default="..." ] />

插入原始面(被包装页??A name=decorator:title>title标签中的内容Q还可以d一个缺省倹{?/FONT>

例:

/_decorator/main.jsp?Q装饰器面Q? <title><decorator:title default="却省title-hello"  /> - 附加标题</title>

/aaa.jsp?(原始面)Q?lt;title>aaa面</title>

讉K/aaa.jsp的结果:<title>aaa面 - 附加标题</title>

<decorator:getProperty property="..." [ default="..." ] [ writeEntireProperty="..." ]/>

在标{֤插入原始面(被包装页?的原有的标签的属?/A>中的内容Q还可以d一个缺省倹{?/FONT>

sitemesh文档中的例子很好理解Q?/FONT>
The decorator: <body bgcolor="white"<decorator:getProperty property="body.onload" writeEntireProperty="true" />>
The undecorated page: <body onload="document.someform.somefield.focus();">
The decorated page: <body bgcolor="white" onload="document.someform.somefield.focus();">

注意Q?/STRONG>writeEntireProperty="true"会在插入内容前加入一个空根{?/FONT>

<decorator:usePage id="..." />
象jsp面中的<jsp:useBean>标签一P可以使用被包装ؓ一个Page对象的页面?(懒的?

例:可用<decorator:usePage id="page" /> Q?/STRONG><%=page.getTitle()%>辑ֈ<decorator:title/>的访问结果?/CODE>

 

<page:applyDecorator name="..." [ page="..." title="..." ] >
<page:param name="..."> ... </page:param>
<page:param name="..."> ... </page:param>
</page:applyDecorator>

应用包装器到指定的页面上Q一般用于被包装面中主动应用包装器。这个标{有点不好理解,我们来看一个例子:

包装器页?/_decorators/panel.jspQ?lt;p><decorator:title /></p>  ... <p><decorator:body /></p>
  q且在decorators.xml中有<decorator name="panel" page="panel.jsp"/>

一个公共页面,卛_被panel包装Q?_public/date.jsp:  
  ... <%=new java.util.Date()%>  ...<decorator:getProperty property="myEmail" />

被包装页?/page.jsp Q?nbsp;
  <title>page的应?lt;/title> 
  .....  

  <page:applyDecorator name="panel" page="/_public/date.jsp" >
    <page:param name="myEmail"> chen_p@neusoft.com </page:param>
  </page:applyDecorator>

最后会是什末结果呢Q除?page.jsp会被默认的包装页面包装上header,footer外,page.jsp面中还内嵌了date.jsp面Qƈ且此date.jsp面q会被panel.jsp包装Z个title加body的有2D늚面Q第1D|date.jsp的titleQ第2D|date.jsp的body内容?/FONT>

另外Q?A name=page:applyDecorator>page:applyDecorator中包含的page:param标签所声明的属性D可以在包装页面中?/FONT>decorator:getProperty标签讉K到?BR>

前面的文章已l以应用sitemesh来改善您的应用,但我发现q有一些其他的东东可能也会对大家有所帮助

可打印的界面装饰
前面说过?U可打印的装饰器Q可以允怽当用http://localhost/aaa/a.html?printable=true方式讉KӞ应用其他的装饰器(自己指定)Q给出原始页面以供打?免得把header,footer{的花哨的图片也搭上)?/FONT>

让我们来看一看怎样实现他:

1.首先在WEB-INFO/sitemesh.xml中设|:
  <mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper">
    <param name="decorator" value="printable" />
    <param name="parameter.name" value="printable" />
    <param name="parameter.value" value="true" />
  </mapper>
q样可以通过?printable=true来用名为printable的装饰器Q而不是用原来的装饰器?/FONT>

2.在WEB-INFO/decorators.xml中定义相应的printable装饰?BR>  <decorator name="printable" page="printable.jsp"/>

3.最后编写printable装饰?decorators/printable.jsp

<%@ taglib uri="sitemesh-decorator" prefix="decorator" %>
<html>
<head>
  <title><decorator:title /></title>
  <decorator:head />
</head>
<body>

  <h1><decorator:title /></h1>
  <p align="right"><i>(printable version)</i></p>

  <decorator:body />

</body>
</html>

q样可以让一个原始页面通过?printable=true开x切换不同的装饰器面?/FONT>

 

中文问题
׃sitemesh内部所使用的缺省字W集为iso-8859-1Q直接用会产生qQ我们可以通过以下ҎU正之:
  • Ҏ1Q可以在您所用的application server的配|文件中找一找,有没有设|encoding?CODE>charset的项目,然后设成gbk或gb2312卛_
  • Ҏ2Q这也是我们一直用的Ҏ?BR>1.在每一个jsp里讄: <%@ page contentType="text/html; charset=gbk"%> 来告诉server你所要求的字W集?BR>2.在每个jsp늚head中定义:<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=gbk"> 来告诉浏览器你所用的字符集?/FONT>
ȝQ用sitemesh最通常的途径Q?/FONT>

1.配置好环境,

2.在WEB-INFO/decroators.xml中描qC徏立的包装器?/FONT>

3.开发在decroators.xml中描q的包装器,最好存攑֜/_decorators目录?/FONT>

4.ok Q可以看看辛勤的成果?:)


资源Q?/B>

关于作者:

陈鹏Q西安东软公司。作Z名狂热的E序员希望每一天都能成长进步,q希望与大家分n快乐和知识?BR>L以下方式和他联系Qemail chen56@msn.com  



jinfeng_wang 2005-04-12 21:31 发表评论
]]>Introduction to SiteMesh(zz)http://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3190.htmljinfeng_wangjinfeng_wangTue, 12 Apr 2005 13:27:00 GMThttp://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3190.htmlhttp://www.tkk7.com/jinfeng_wang/comments/3190.htmlhttp://www.tkk7.com/jinfeng_wang/archive/2005/04/12/3190.html#Feedback0http://www.tkk7.com/jinfeng_wang/comments/commentRss/3190.htmlhttp://www.tkk7.com/jinfeng_wang/services/trackbacks/3190.html

Introduction to SiteMesh Introduction to SiteMesh

by Will Iverson
03/11/2004


Contents
How Does It Work?
Installing SiteMesh
   web.xml
   decorators.xml
   decorators/*.jsp
   sitemesh-2.0.1.jar
   *.tld
Advanced SiteMesh
Summary

In the past, I used to build my web applications the old-fashioned way: handcrafting assembly, carefully building my raw byte handlers to work with Unicode, counting instructions, and using make files to target different CPUs.

OK, maybe not.

Although I've never actually felt the need to build my web application with assembly (CISC or RISC), I sometimes think my fellow developers are on a quest to make their development processes as painful as possible. In particular, I've seen many developers agonize over the best way to handle basic web application building blocks: things like headers, footers, navigation bars, support for printable pages, light-weight pages for handheld devices, and more. In the end, things like includes and brute-force copy-and-paste win out surprisingly often.

In my experience, I've been able to easily solve these problems cleanly, easily, and elegantly using the open source servlet filter SiteMesh, which is hosted on java.net. Instead of requiring a new templating language, XSLT, or "porting" your pages to a new system, using SiteMesh often allows you to dramatically simplify your pages while still using ordinary HTML, JSP, servlets (including Struts), and other familiar technologies.

How Does It Work?

SiteMesh implements a page filter, taking advantage of one of the lesser-known features of the servlet specification. Let's imagine you have a simple JSP that returns the current date and time. Ordinarily, the request for the page comes in to the application server, the page is rendered, and then the results are returned to the web browser. SiteMesh, as a page filter, takes the page after it is rendered and performs additional processing before returning the document to the web browser. This change is most simply described as the additional step shown between Figure 1 and Figure 2.

Figure 1
Figure 1. Normal Page Rendering

Figure 2
Figure 2. SiteMesh Page Rendering

Let's look at a simple example of this. Consider the following simple JSP:

<html>
    <head>
        <title>Simple Document</title>
    </head>
    <body>
        Hello World! <br />
        <%= 1+1 %>
        </body>
</html>

You'll notice that the page has a title and a body (like any ordinary HTML page). You'll notice a tiny bit of JSP code -- this will be rendered just as you would expect. Indeed, you can use any and all features that you would expect, and you link between the various JSP and other resources just as you might expect.

Now, let's look at a simple SiteMesh "decorator" page. Listing 2 shows a JSP page, called by SiteMesh.

<%@ taglib uri="sitemesh-decorator"
prefix="decorator" %>
<html>
 <head>
 <title>
 My Site - <decorator:title default="Welcome!" />
 </title>
 <decorator:head />
 </head>
 <body>
 <h1><decorator:title default="Welcome!" /></h1>
 <p><decorator:body /></p> 
 <p><small>
 (<a 
    href="?printable=true">printable version</a>)
    </small></p>
 </body>
</html>

Looking at the decorator, we can see a few interesting things. First, a SiteMesh taglib is introduced in the first line. This taglib includes everything required to work with the original page. You can see that we use two of the SiteMesh declared tags, <decorator:title> and <decorator:body>. Not surprisingly, the <decorator:title> returns the contents of the <title> tag in the original page, and <decorator:body> the content. We're making a few fairly radical changes to the page, including repeating the title both in the HEAD element as well as the BODY. We're also adding a link to a printable version of the page.

For comparison, Figure 3 shows the rendered original page and Figure 4 the rendered decorated page. Notice the appearance of the title text both in the browser window title bar and in the HTML of the page in the decorated page. You'll also notice that we added a printable page link, as well -- we'll come back to this later.

Figure 3
Figure 3. Original Undecorated Page

Figure 4
Figure 4. Decorated Page

Obviously, this is a much cleaner system for applying traditional header and footer content than using include directives (such as <jsp:include page="foo.jsp" flush="true" />). It's much more flexible and natural, and encourages JSP pages with no navigation or other presentation data. I have found that a combination of decorators and CSS overrides of standard HTML tags allows me to virtually eliminate formatting information from my JSP pages.

Installing SiteMesh

Note that the screenshots, etc. are based on Windows XP Professional, Tomcat 5.0.19, and Java 2 SDK 1.4.2_03. I'm going to assume that you have installed and are able to get Tomcat working. You might have to tweak things slightly, but I've gotten all of this to work fine on Tomcat 4.1 and WebLogic as well, and SiteMesh lists many other supported web application servers.

SiteMesh 2.0.1, the version described in this article, can be downloaded here. There are four files available for download from SiteMesh's java.net project repository. The sitemesh-2.0.1.jar file is just the core JAR file, sitemesh-2.0.1-sources.zip is self-describing, and sitemesh-example.war provides a complex example showing some of SiteMesh's more advanced features.

To keep things simple, we'll start with the sitemesh-blank.war file, building and modifying as we go along. Instead of just dropping the WAR file into our Tomcat webapps directory, we'll crack open the WAR open and drop it in uncompressed, as shown in Figure 5.

Figure 5
Figure 5. SiteMesh Blank WAR Contents

There are a number of files here, so let's take a moment to describe what they do.

web.xml

First, the WEB-INF/web.xml file, shown in Listing 3, contains directives to install the SiteMesh filter and the taglib libraries. If you're adding SiteMesh to an existing web application, you'll need to add these directives to your WEB-INF/web.xml file.

<?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
    "http://java.sun.com/dtd/web-app_2_3.dtd">    
<web-app>    
 <!-- Start of SiteMesh stuff -->    
 <filter>
 <filter-name>sitemesh</filter-name>
     <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
 </filter>    
 <filter-mapping>
    <filter-name>sitemesh</filter-name>
 <url-pattern>*.jsp</url-pattern>
 </filter-mapping>    
 <taglib>
    <taglib-uri>sitemesh-page</taglib-uri>
    <taglib-location>/WEB-INF/sitemesh-page.tld</taglib-location>
 </taglib>    
 <taglib>
    <taglib-uri>sitemesh-decorator</taglib-uri>
     <taglib-location>/WEB-INF/sitemesh-decorator.tld</taglib-location>
 </taglib>    
 <!-- End of SiteMesh stuff -->    
</web-app>

Note: you'll notice that I've flagged the url-pattern line -- if you are using Tomcat 5 (instead of Tomcat 4) you'll need to change the pattern from the default * to something like *.jsp. The * pattern is not allowed under the latest servlet specification.

decorators.xml

The WEB-INF/decorators.xml file is used to bind a decorator name to a specific JSP decorator file. So, for example, we might bind a decorator named handheld to the JSP page decorator minimal.jsp.

<decorators defaultdir="/decorators">
 <decorator name="main" page="main.jsp">
 <pattern>*</pattern>
 </decorator>
 
 <decorator name="panel" page="panel.jsp"/>
 <decorator name="printable" page="printable.jsp"/>
</decorators>

As we can see in this code listing, we define three decorators, and then bind them to three similarly named JSP pages. We also see that the default decorator, main.jsp, will be applied for files by default.

By default, SiteMesh will use the following logic to determine what decorator to apply:

This logic is expressed in described in the sitemesh-2.0.1.jar file at \com\opensymphony\module\sitemesh\factor\sitemesh-default.xml. You can override this behavior with a wide variety of built-in mappers for things like language, client operating system, web browser/user agent, etc. by creating a WEB-INF\sitemesh.xml file. You'll find an example of this included in the sitemesh-example.war file.

  1. Does the page specifically request a decorator using a meta decorator tag?
  2. Is the page a frame set (if so, don't apply a decorator)?
  3. Does the page have a printable=true parameter> (If so, use the printable decorator.)
  4. Does the page specifically request a decorator by the decorator file name?
  5. Does the page match a pattern in the decorators.xml file?

Conceptually, the first rule that evaluates to true determines the decorator that is used. In the example above, when the printable=true parameter is present, the printable.jsp decorator (rule #3) is used instead of the main.jsp (matched in rule #5). In SiteMesh, these rules are described as mappers.

decorators/*.jsp

The three files in the decorators directory are the various decorator JSP files, as described by decorators.xml. We saw an example of a simple decorator above, and we'll look at a more sophisticated example later in this article.

sitemesh-2.0.1.jar

This is the main SiteMesh binary, typically installed in the WEB-INF/lib directory. You can find the Javadoc for this library at www.opensymphony.com/sitemesh/api.

*.tld

SiteMesh uses two tag libraries, but most users will only need the decorator tags (sitemesh-decorator.tld). You can find documentation on these at www.opensymphony.com/sitemesh/tags.html. We've already touched on the main tags, used to retrieve the head, title, and body. We'll look at the remaining tag, getProperty, in the next section.

Advanced SiteMesh

One of the more powerful abilities of SiteMesh is to use the ordinary HTML meta tag (for example, <meta name="foo" content="bar">) to pass information from the base page to the decorator. For example, let's say that we would like to define the author of an HTML page using a meta tag, as shown below.

<html>
    <meta name="author" content="test@example.com">
    <head>
        <title>Simple Document</title>
    </head>
    <body>
        Hello World! <br />
        <%= 1+1 %>
        </body>
</html>

We can make a decorator "smart" enough to know to look for this meta tag, and if present, generate the appropriate HTML:

<%@ taglib uri="sitemesh-decorator" prefix="decorator" %>
 <decorator:usePage id="myPage" />
 <html>
 <head>
 <title>My Site -
    <decorator:title default="Welcome!" />
 </title>
 <decorator:head />
 </head>

 <body>
 <h1><decorator:title default="Welcome!" /></h1>
 <h3>
 <a href="mailto:<decorator:getProperty property="meta.author" 
            default="staff@example.com" />">
 <decorator:getProperty property="meta.author"
              default="staff@example.com" />
 </a></h3><hr />
 <decorator:body />
 <p><small>
    (<a href="?printable=true">printable version</a>)
    </small>
 </p>
 </body>
 </html>

You'll notice that we use a default attribute in the getProperty tag -- if no author is specified, we'll just assume that it was written by the staff. If you decide to use this model for storing page metadata, you'll want to work with your content developers and other team members to determine what tags you want to use and how you'll be using them. At the simple end, you may want to use meta tags to describe things like the author and page timestamp. At the complex end, you may do things like standardize on an XML file to manage your site navigation and use a meta tag to pass the page's node to the decorator.

The page that results from applying this decorator to the JSP page above is shown in Figure 6.

Figure 6
Figure 6. meta Tag Displayed

These page attributes are powerful, and you can retrieve many different properties, not just the meta tags (here's a list of generated page properties). After using SiteMesh for a while, you'll start thinking about HTML and JSP as a mechanism for generating simple markup -- closer to the original intent of HTML -- without having to make a full switch to an XML/XSL or other template engine.

Summary

As we've seen, SiteMesh provides for a powerful, easy-to-use, non-intrusive mechanism for applying page templates. It's easy to envision a wide range of possible uses. For example, you might define a decorator that emits extra debugging information about the page, as determined by the browser (this is especially powerful when combined with a web browser that lets you set an arbitrary user-agent). You might define a decorator with a stripped-down XML output, allowing for easier automated testing. You can even use the decorator to grab content from other pages, for example, to simple portal-like capability.

Once you've gotten comfortable with sitemesh-blank.war, I'd suggest looking at sitemesh-example.war for more features and ideas.

Regardless of how you use SiteMesh, I've found that it lets me centralize a tremendous amount of code, moving it out of my presentation layer and into my decorators, without having to learn a new programming language or templating system.

Oh, and as a final note for those of you still interested in building web pages in assembly, check out home.worldonline.dk/viksoe/asmil.htm.

Good luck and happy coding!

Will Iverson served as Developer Relations Manager for the VisualCafé group at Symantec, as the Java & Runtimes Product Manager at Apple Computer and has led Cascade Technology Group, a private consulting firm, since 1999.



jinfeng_wang 2005-04-12 21:27 发表评论
]]>
վ֩ģ壺 ˳վѲ| Ļһ| AV֮պƷ| AVƬ| 99re8оƷƵ| av߹ۿַ| ޹ŮƵ| vavava888www| ޹Ʒһþ| ҹƵվ| ߿վ| ȫ߹ۿ| һѹ| 㽶97Ƶ| ݾþþƷۺר| Ƶ| þþþseɫ͵͵޾Ʒav | ɫۺ| һþþþþþþ| 77777ҹþö| Ů˳Ժ˾޸| Ƶ߹ۿַ| þþŷղAV | 99reȾƷƵ| þþþƷѹĻ| jŮjڲվ| ѲһëƬ | һӰԺ| վ߹ۿ| ޾ƷƵ߹ۿƵ| þþþ޾ƷŮ| þþþ޾ƷӰ| þþƷƷëƬ| þþƷAV鶹վ| þþƷĻ鶹| þƷ| ۾ƷҹӰ| av뾫Ʒ4 | ˬָ߳ëƬ| Բٸ| ֳִӲƵ|