﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-風向逆轉 - 就要爪哇-文章分类-Others</title><link>http://www.blogjava.net/iKingQu/category/8129.html</link><description>Java菜鸟升级中...</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 11:26:03 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 11:26:03 GMT</pubDate><ttl>60</ttl><item><title>[收藏]Web 2.0 编程思想：16条法则</title><link>http://www.blogjava.net/iKingQu/articles/47123.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Fri, 19 May 2006 14:42:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/47123.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/47123.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/47123.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/47123.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/47123.html</trackback:ping><description><![CDATA[来自：blogbeta.com　  indigo<br /><br /><p>原文：<a href="http://web2.wsj2.com/thinking_in_web_20_sixteen_ways.htm">Thinking in Web 2.0: Sixteen Ways</a><br />作者：<a href="http://web2.wsj2.com/">Dion Hinchcliffe</a></p><p>1、在你开始之前，先定一个简单的目标。无论你是一个Web 2.0应用的创建者还是用户，请清晰的构思你的目标。就像“我需要保存一个书签”或者“我准备帮助人们创建可编辑的、共享的页面”这样的目标，让你保持最基础的需求。很多Web 2.0应用的最初吸引之处就是它的简单，避免并隐藏了那些多余的复杂性。站在创建者的立场，可以想象Google的几乎没有内容的主页，还有del.icio.us的简单的线条。从最终用户的角度来看，与之齐名的就是Diggdot.us所提供的初始化页面。你能够并且希望加入更多功能，但是先做好最开始的。在一个时候只做一个特性，完成一个目标。这听起来很太过于单纯化了，但它将使你更加专注，而且你也会明白我的意思。</p><p>2、链接是最基础的思想。这就是我们称之为Web的一个理由。链接是把Web中各种实体连接起来的最基本的元素。你的信息、你的关系、你的导航，甚至是能够被写成URL的任何内容。这里有一个链接应该遵循的规则（其实你也不必严格的遵守）：</p><p>    1. Web上的任何东西都是可以被URI或者是URL所连接的。<br />    2. 把所有的链接都保存为他的原始出处，这样可以让你与任何人、在任何地方、任何时候都能分享它。<br />    3. 第二条中任何时候的前提是链接必须是持久的，它不会在没有任何缘由的情况下被改变或者是消失。<br />    4. 链接应该是人类可读的、稳定的、并且能够自我诠释的。 </p><p>3、数据应该属于创建它的人。是的，你听我的。任何用户创建的、贡献的或分享的都是他们自己的，除非他们很明显的放弃这个权力来让你自由处置。他们贡献到Web上的任何信息都应该是可编辑的、能被删除的、并且能够取消共享，无论在任何时候，只要用户愿意。这也包含了那些间接的数据，像他们所关心的记录、日志、浏览历史、网站访问信息，或者是任何可以被跟踪的信息。所有的网站必须清晰简单的陈诉那些信息是用户创建的，并且提供他们停止创建的方法，甚至是清除的方法。</p><p>4、数据优先，体验与功能其次。无论它是文本、图片、音频还是视频，Web最终还是把这些解析为数据。换句话说，你无法脱离数据去呈现内容。所有这些数据都通过那些易于发现的URL来定位（参见第2条）。通过另一种形式来看待这些，Web最终是名词优先，动词其次，虽然最近正在向动词偏移。来看看名词的例子：日历的条目、家庭照片、股票价格。还有一些动词的例子：定一个约会、共享一张图片、买一份股票。</p><p>5、做好积极分享一切的准备。尽可能的分享一切，你所拥有的所有数据，你所提供的所有服务。鼓励不遵循原有意图的使用，提倡贡献，不要那些需要分享的内容坚持设置为私有的。在分享与发现之后，提供易于使用的浏览方式是显而易见的需求。为什么呢：话说回来，你会从别人的共享之中受益匪浅。注意：这里没有许可让你去侵犯版权保护的法律，你不能够去分享你刻录的DVD或者是拥有商业版权音乐，因为你已经同意不会去分享这些东西。但是你可以发现并分享那些完全开放的媒体内容。一个小小的建议，你可以学习一下Creative Commons license（共创协议）.</p><p>6、Web是一个平台；要让它成长。当然，我们还有很多其他的平台（Windows、Linux、Mac），但是那些已经不是重点了。换句话说，Web是无法脱离的平台，不会中断的平台，你可以通过各种方式去扩展的平台。你在Web上提供的数据与服务将会成为Web一部分，最终你会在Web平台的某一处扮演你的角色。扮演好你的角色并照顾好后来者。</p><p>7、理解与信奉“阶梯性”。现在的Web越来越大，几乎蔓延到了全世界的所有国家，并且已经拥有了10亿用户。我的观点是Web的各个组成部分存在着细微的区别和不同，就像不同地方的用户那样。例如Web的设计部分：易用性永远优先于速度、可靠性、重用性与可集成性。你也应该提供同样的体验给你的用户。它已经被一次又一次的被人们在文档中强调，忠诚的用户很快会成为专业的用户，他们期待更快的速度还有更多。退一步支持他们。同样，也有很多很多的用户会进入这个阶梯的底端，如你所期待的那样。他们可能不会说你的语言，不熟悉你的文化，甚至不知道是如何到这里的。所以你需要向他们表达清楚。</p><p>8、任何东西都是可编辑的。或者是它应该被编织的更好。要确定的是，只有很少的东西是不能被编辑的，剩下的都可以，这是一个可写的Web。这并不意味着原始内容的丢失，而通常被理解为用户能够很容易的对内容加以评论，或者评注内容是在那里发现的。如果你对此应用的好，他们能够比你所想象的做的更多（把内容串起来并且给予原始内容来创建自己的，等等）。</p><p>9、Web上的身份是神圣的。不幸的是，这并不意味着你能够得到更多的隐私（这完全是上个世纪的想法）。但对身份的验证是必要的，你应该感谢那些只需一个邮件地址就能确定你身份的服务。这意味只要你对你的用户承诺了，你就必须保证他们的隐私安全。必要的时候，在这个世界的某处你还得为你的用户挺身而出，向当地的权威挑战。如果你没有打算那样做，你就得把实际情况告诉你的用户。另一方面，如果身份是必须的，不要试图伪装它，不然在某一天我们将会在Web上放弃我们的最后一点点隐私的权利。</p><p>10、了解流行的标准并且使用他们。从一个消费者或者是创作者的立场来看，数据将会以不同的格式与任何一个人交换。同时这样的数据也会反过来促进标准的完善与采纳。这通常意味像RSS、 OPML、XHTML、Simple XML、JSON等简单标准的流行，而避免SOAP、XSD，还有RDF、ATOM也一样，使用它们会给我的内心带来痛苦。请你也为你所钟爱的标准投上一票来支持它们。</p><p>11、遵循无意使用的规律。如果你把非常有趣的数据和服务用广泛使用的格式开放和共享出去，你将会得到你所应得的，其他人也将会基于你的那一块Web平台来构建。或许还会从别人那里得到更多，所以为这个做一下准备比较好。我已记不清有多少次我看到一个播客（podcasting）服务因为流行过渡而导致服务垮掉，就是因为他们被 Slashdot和del.icio.us给收录了。这一点要知道：网络上的大量化意味着如果一个内容非常有趣，即使是一个很小的角落也会得到惊人的访问量。鼓励使用这种方式，它还是非常有价值的，前提是你要有所准备。</p><p>12、粒化你的数据与服务。我们应该在很早以前就明白这些，大规模集成的数据仅仅适用于无需管理的下载与批量操作。分解你的数据，让他们独立成可描述的URL地址，对你的服务也一样。反过来说，你不要创建一些巨大的、复杂的、像圣诞树那样的数据结构和服务。保持简单，要非常的简单。让这些分离的片断能够容易的被重组和发现。</p><p>13、提供用户能够单独受益的数据和服务。渐渐依赖于这种社会化参与是存在风险的，你需要让你的用户有一点点动机来贡献时间、热情和信息，除非他们能够直接受益。社会化分享比个体行为的利益大很多，除非你能够激发用户的个人动机，否这你将无法享受这份厚礼。</p><p>14、让用户组织并过滤信息。不一定是必须的，但却是非常重要的。让用户以他们自己的方式来标注和组织数据，因为你自己是永远无法及时的处理他们的。用户会按照他们自己理解的最佳方式来处理并构建。要保证你的Web服务能够按照用户所需所想的方式来工作。这也是标签（tagging）和通俗分类（folksonomies ）的方式如此成功的主要因素。</p><p>15、提供丰富的用户体验。Web一直都在和本地的应用程序进行着激烈的竞争。为什么？因为本地程序还是感觉上好一些，速度也快一些。但是这不会长久的（确信在5年或者15年后，这种竞争就不存在了）。是的，我在谈论Rich Internet Applications, Ajax, 还有那些不可思议的交互应用。他们让Web成为了一个真正的“无平台”的平台，如果你知道我是怎么想的。</p><p>16、信奉并支持快速改进和反馈。这个通常意味着加快步伐，但也意味着使用轻量级的工具、技术和不要做出那些适得其反的痛苦决定（例如使用一个被层层环绕的Ajax框架来代替可以通过混合来实现的，或者用C++来构建所有的东西，其实使用Ruby会更好一些）。这同时也意味着需要一个非常快速的方式来处理错误报告，修复Bug，释放新版本。从一个用户的角度来看，报告你所发现的任何问题，还有那些你经常抱怨的地方，甚至那些都不是一个Bug。</p><p>当然，Web 2.0是一个极其广泛和深奥的话题，没有一个人能够列举出它的所有重点和特征。如果你对此充满了兴趣，请花一点时间来补充我没有提到的地方。我想这就是Web 2.0的参与性吧！</p><p>原作者的这个标题借鉴了Bruce Eckel的两本畅销书的名字：《Thinking in C++》和《Thinking in Java》，《C++编程思想》与《Java编程思想》，在此说明一下为什么要这样翻译这个题目:)</p><p>indigo 翻译整理</p><p>原文出处：<a href="http://chn.blogbeta.com/119.html">http://chn.blogbeta.com/119.html</a></p><img src ="http://www.blogjava.net/iKingQu/aggbug/47123.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-05-19 22:42 <a href="http://www.blogjava.net/iKingQu/articles/47123.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Hibernate学习---通过XDoclet(ant)生成Hibernate映射文件</title><link>http://www.blogjava.net/iKingQu/articles/40312.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 10 Apr 2006 11:42:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/40312.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/40312.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/40312.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/40312.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/40312.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<p>通过XDoclet可以我们的精力放在编写java源文件上。<br /><br />具体来说就是：<br />只有Java： java---&gt;XDoclet(hibernatedoclet)---&gt;Hbm----&gt;SchemaExport(schemaexport,hbm2ddl)----&gt;数据表</p>
				<p>
						<strong>1:java源文件编写</strong>
				</p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<img id="Codehighlighter1_0_28_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_28_Open_Text.style.display='none'; Codehighlighter1_0_28_Closed_Image.style.display='inline'; Codehighlighter1_0_28_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
						<img id="Codehighlighter1_0_28_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_28_Closed_Text.style.display='none'; Codehighlighter1_0_28_Open_Image.style.display='inline'; Codehighlighter1_0_28_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
						<span id="Codehighlighter1_0_28_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span>
						<span id="Codehighlighter1_0_28_Open_Text">
								<span style="COLOR: #008000">/*</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * Created on 2006-4-7<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /> </span>
								<span style="COLOR: #008000">*/</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">package</span>
						<span style="COLOR: #000000"> com.entity;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_52_165_Open_Image" onclick="this.style.display='none'; Codehighlighter1_52_165_Open_Text.style.display='none'; Codehighlighter1_52_165_Closed_Image.style.display='inline'; Codehighlighter1_52_165_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_52_165_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_52_165_Closed_Text.style.display='none'; Codehighlighter1_52_165_Open_Image.style.display='inline'; Codehighlighter1_52_165_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span>
						<span id="Codehighlighter1_52_165_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span>
						<span id="Codehighlighter1_52_165_Open_Text">
								<span style="COLOR: #008000">/**</span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * </span>
								<span style="COLOR: #808080">@author</span>
								<span style="COLOR: #008000"> jkallen<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * @hibernate.class lazy="true" table="syn_dept"<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * @hibernate.cache usage="read-write"<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /> </span>
								<span style="COLOR: #008000">*/</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img id="Codehighlighter1_194_684_Open_Image" onclick="this.style.display='none'; Codehighlighter1_194_684_Open_Text.style.display='none'; Codehighlighter1_194_684_Closed_Image.style.display='inline'; Codehighlighter1_194_684_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_194_684_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_194_684_Closed_Text.style.display='none'; Codehighlighter1_194_684_Open_Image.style.display='inline'; Codehighlighter1_194_684_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">public</span>
						<span style="COLOR: #000000"> </span>
						<span style="COLOR: #0000ff">class</span>
						<span style="COLOR: #000000"> SynDepartment </span>
						<span id="Codehighlighter1_194_684_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
								<img src="http://www.blogjava.net/images/dot.gif" />
						</span>
						<span id="Codehighlighter1_194_684_Open_Text">
								<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> <br /><img id="Codehighlighter1_199_209_Open_Image" onclick="this.style.display='none'; Codehighlighter1_199_209_Open_Text.style.display='none'; Codehighlighter1_199_209_Closed_Image.style.display='inline'; Codehighlighter1_199_209_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_199_209_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_199_209_Closed_Text.style.display='none'; Codehighlighter1_199_209_Open_Image.style.display='inline'; Codehighlighter1_199_209_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span>
								<span id="Codehighlighter1_199_209_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span>
								<span id="Codehighlighter1_199_209_Open_Text">
										<span style="COLOR: #008000">/**</span>
										<span style="COLOR: #008000"> 主键 id</span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> </span>
								<span style="COLOR: #0000ff">private</span>
								<span style="COLOR: #000000"> Long id;<br /><img id="Codehighlighter1_230_239_Open_Image" onclick="this.style.display='none'; Codehighlighter1_230_239_Open_Text.style.display='none'; Codehighlighter1_230_239_Closed_Image.style.display='inline'; Codehighlighter1_230_239_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_230_239_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_230_239_Closed_Text.style.display='none'; Codehighlighter1_230_239_Open_Image.style.display='inline'; Codehighlighter1_230_239_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span>
								<span id="Codehighlighter1_230_239_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span>
								<span id="Codehighlighter1_230_239_Open_Text">
										<span style="COLOR: #008000">/**</span>
										<span style="COLOR: #008000"> 部门名称</span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> </span>
								<span style="COLOR: #0000ff">private</span>
								<span style="COLOR: #000000"> String code_name;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> <br /><img id="Codehighlighter1_271_361_Open_Image" onclick="this.style.display='none'; Codehighlighter1_271_361_Open_Text.style.display='none'; Codehighlighter1_271_361_Closed_Image.style.display='inline'; Codehighlighter1_271_361_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_271_361_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_271_361_Closed_Text.style.display='none'; Codehighlighter1_271_361_Open_Image.style.display='inline'; Codehighlighter1_271_361_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span>
								<span id="Codehighlighter1_271_361_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span>
								<span id="Codehighlighter1_271_361_Open_Text">
										<span style="COLOR: #008000">/**</span>
										<span style="COLOR: #008000">
												<br />
												<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  * </span>
										<span style="COLOR: #808080">@return</span>
										<span style="COLOR: #008000"> Returns the id.<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  * @hibernate.id generator-class="native" column="id"<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />  </span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img id="Codehighlighter1_387_403_Open_Image" onclick="this.style.display='none'; Codehighlighter1_387_403_Open_Text.style.display='none'; Codehighlighter1_387_403_Closed_Image.style.display='inline'; Codehighlighter1_387_403_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="Codehighlighter1_387_403_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_387_403_Closed_Text.style.display='none'; Codehighlighter1_387_403_Open_Image.style.display='inline'; Codehighlighter1_387_403_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">public</span>
								<span style="COLOR: #000000"> Long getId() </span>
								<span id="Codehighlighter1_387_403_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.blogjava.net/images/dot.gif" />
								</span>
								<span id="Codehighlighter1_387_403_Open_Text">
										<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span>
										<span style="COLOR: #0000ff">return</span>
										<span style="COLOR: #000000"> id;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /> }</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img id="Codehighlighter1_433_452_Open_Image" onclick="this.style.display='none'; Codehighlighter1_433_452_Open_Text.style.display='none'; Codehighlighter1_433_452_Closed_Image.style.display='inline'; Codehighlighter1_433_452_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="Codehighlighter1_433_452_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_433_452_Closed_Text.style.display='none'; Codehighlighter1_433_452_Open_Image.style.display='inline'; Codehighlighter1_433_452_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span>
								<span style="COLOR: #0000ff">public</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000"> setId(Long id) </span>
								<span id="Codehighlighter1_433_452_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.blogjava.net/images/dot.gif" />
								</span>
								<span id="Codehighlighter1_433_452_Open_Text">
										<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span>
										<span style="COLOR: #0000ff">this</span>
										<span style="COLOR: #000000">.id </span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000"> id;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /> }</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img id="Codehighlighter1_455_548_Open_Image" onclick="this.style.display='none'; Codehighlighter1_455_548_Open_Text.style.display='none'; Codehighlighter1_455_548_Closed_Image.style.display='inline'; Codehighlighter1_455_548_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="Codehighlighter1_455_548_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_455_548_Closed_Text.style.display='none'; Codehighlighter1_455_548_Open_Image.style.display='inline'; Codehighlighter1_455_548_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span>
								<span id="Codehighlighter1_455_548_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span>
								<span id="Codehighlighter1_455_548_Open_Text">
										<span style="COLOR: #008000">/**</span>
										<span style="COLOR: #008000">
												<br />
												<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    * </span>
										<span style="COLOR: #808080">@return</span>
										<span style="COLOR: #008000"> Returns the code_name.<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    * @hibernate.property column = "code_name"<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    </span>
										<span style="COLOR: #008000">*/</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img id="Codehighlighter1_580_603_Open_Image" onclick="this.style.display='none'; Codehighlighter1_580_603_Open_Text.style.display='none'; Codehighlighter1_580_603_Closed_Image.style.display='inline'; Codehighlighter1_580_603_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="Codehighlighter1_580_603_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_580_603_Closed_Text.style.display='none'; Codehighlighter1_580_603_Open_Image.style.display='inline'; Codehighlighter1_580_603_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span>
								<span style="COLOR: #0000ff">public</span>
								<span style="COLOR: #000000"> String getCode_name() </span>
								<span id="Codehighlighter1_580_603_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.blogjava.net/images/dot.gif" />
								</span>
								<span id="Codehighlighter1_580_603_Open_Text">
										<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span>
										<span style="COLOR: #0000ff">return</span>
										<span style="COLOR: #000000"> code_name;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /> }</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img id="Codehighlighter1_649_682_Open_Image" onclick="this.style.display='none'; Codehighlighter1_649_682_Open_Text.style.display='none'; Codehighlighter1_649_682_Closed_Image.style.display='inline'; Codehighlighter1_649_682_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" />
										<img id="Codehighlighter1_649_682_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_649_682_Closed_Text.style.display='none'; Codehighlighter1_649_682_Open_Image.style.display='inline'; Codehighlighter1_649_682_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span>
								<span style="COLOR: #0000ff">public</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #0000ff">void</span>
								<span style="COLOR: #000000"> setCode_name(String code_name) </span>
								<span id="Codehighlighter1_649_682_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.blogjava.net/images/dot.gif" />
								</span>
								<span id="Codehighlighter1_649_682_Open_Text">
										<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span>
										<span style="COLOR: #0000ff">this</span>
										<span style="COLOR: #000000">.code_name </span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000"> code_name;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /> }</span>
								</span>
								<span style="COLOR: #000000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
				</div>
				<p>
						<br />
						<br />这里用到了几种@hibernate标记的用法<br />@hibernate.class标记指定类的映射代码，lazy="true" table="syn_dept"则如<br />hibernate的映射文件class元素的属性值具有相同的意义<br />@hibernate.id标记指定类的OID映射代码<br />@hibernate.property标记指定类的属性映射代码<br />另外还可能用到@hibernate.set(如一对多的情况下)</p>
				<p>
						<strong>2:XDoclet---&gt;Hbm(写在build.xml文件中，ANT运行)<br /></strong>
				</p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">target </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="toHbm"</span>
						<span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  depends</span>
						<span style="COLOR: #0000ff">="compileEntity"</span>
						<span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  description</span>
						<span style="COLOR: #0000ff">="Generate hibernate mapping documents"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">hibernatedoclet </span>
						<span style="COLOR: #ff0000">destdir</span>
						<span style="COLOR: #0000ff">="${generated.dir}"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">fileset </span>
						<span style="COLOR: #ff0000">dir</span>
						<span style="COLOR: #0000ff">="${src.dir}"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">include </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="**/entity/*.java"</span>
						<span style="COLOR: #ff0000"> </span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">fileset</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">hibernate </span>
						<span style="COLOR: #ff0000">version</span>
						<span style="COLOR: #0000ff">="2.0"</span>
						<span style="COLOR: #ff0000"> </span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">hibernatedoclet</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">copy </span>
						<span style="COLOR: #ff0000">todir</span>
						<span style="COLOR: #0000ff">="${classes.dir}"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">fileset </span>
						<span style="COLOR: #ff0000">dir</span>
						<span style="COLOR: #0000ff">="${generated.dir}"</span>
						<span style="COLOR: #ff0000"> </span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">copy</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">target</span>
						<span style="COLOR: #0000ff">&gt;</span>
				</div>
				<p>
						<br />通过hibernatedoclet就可以生成SynDepartment.hbm.xml映射文件<br />fileset顾名思义就是过滤文件了。<br />注：compileEntity--编译java源文件(自定义)</p>
				<p>
						<strong>3:SchemaExport----&gt;数据表</strong>
						<br />
				</p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">target </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="toddl"</span>
						<span style="COLOR: #ff0000"> depends</span>
						<span style="COLOR: #0000ff">="init"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">schemaexport </span>
						<span style="COLOR: #ff0000">properties</span>
						<span style="COLOR: #0000ff">="${classes.dir}/hibernate.properties"</span>
						<span style="COLOR: #ff0000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   quiet</span>
						<span style="COLOR: #0000ff">="no"</span>
						<span style="COLOR: #ff0000"> text</span>
						<span style="COLOR: #0000ff">="no"</span>
						<span style="COLOR: #ff0000"> drop</span>
						<span style="COLOR: #0000ff">="no"</span>
						<span style="COLOR: #ff0000">    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   delimiter</span>
						<span style="COLOR: #0000ff">="&amp;#xd;&amp;#xa;go&amp;#xd;&amp;#xa;"</span>
						<span style="COLOR: #ff0000"> output</span>
						<span style="COLOR: #0000ff">="${sql.dir}/${synup.sql.file}"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">fileset </span>
						<span style="COLOR: #ff0000">refid</span>
						<span style="COLOR: #0000ff">="hibernate.synup.mapping.files"</span>
						<span style="COLOR: #ff0000"> </span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">schemaexport</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">echo </span>
						<span style="COLOR: #ff0000">message</span>
						<span style="COLOR: #0000ff">="Output sql to file: ${sql.dir}/${sql.file}"</span>
						<span style="COLOR: #ff0000"> </span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">target</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">fileset </span>
						<span style="COLOR: #ff0000">id</span>
						<span style="COLOR: #0000ff">="hibernate.synup.mapping.files"</span>
						<span style="COLOR: #ff0000"> dir</span>
						<span style="COLOR: #0000ff">="${classes.dir}"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">include </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="**/entity/*.hbm.xml"</span>
						<span style="COLOR: #ff0000"> </span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">fileset</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
				</div>
				<p>
						<br /> 通过schemaexport就向DB中生成table了。其中可能用到如下的一些属性：<br /> quiet：如果为yes,表示不把子DDL脚本输出到控制台<br /> drop：如果为yes，只执行删除数据库中的操作，但不创建新的表<br /> text：如果为yes，只会生成DDL脚本文件，但不会在数据库中执行DDL脚本<br /> output：指定存放DDL脚本文件的目录<br /> config：设定基于XML格式的配置文件， hbm2ddl(schemaexport)工具从这个文件中读取数据库的配置信息<br /> properties：设定基于java属性文件格式的配置文件，hbm2ddl(schemaexport)工具从这个文件中读取DB的配置信息<br /> format：设定DDL脚本中SQL语句的格式<br /> delimiter：为DDL脚本设置行结束符<br /> <br /> 在ANT中执行：<br /> &lt;target name="initOnlySynup" depends="toHbm,toddl"&gt;<br /> &lt;/target&gt;<br /> <br /> OK,最后生成的映射文件如下：<br /></p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">&lt;?</span>
						<span style="COLOR: #ff00ff">xml version="1.0"</span>
						<span style="COLOR: #0000ff">?&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">&lt;!</span>
						<span style="COLOR: #ff00ff">DOCTYPE hibernate-mapping PUBLIC<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    "-//Hibernate/Hibernate Mapping DTD 2.0//EN" <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">hibernate-mapping</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">class<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="com.SynDepartment"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        table</span>
						<span style="COLOR: #0000ff">="syn_dept"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        dynamic-update</span>
						<span style="COLOR: #0000ff">="false"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        dynamic-insert</span>
						<span style="COLOR: #0000ff">="false"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">cache </span>
						<span style="COLOR: #ff0000">usage</span>
						<span style="COLOR: #0000ff">="read-write"</span>
						<span style="COLOR: #ff0000"> </span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">id<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="id"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            column</span>
						<span style="COLOR: #0000ff">="id"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            type</span>
						<span style="COLOR: #0000ff">="java.lang.Long"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">generator </span>
						<span style="COLOR: #ff0000">class</span>
						<span style="COLOR: #0000ff">="native"</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">generator</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">id</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">&lt;</span>
						<span style="COLOR: #800000">property<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span>
						<span style="COLOR: #ff0000">name</span>
						<span style="COLOR: #0000ff">="code_name"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            type</span>
						<span style="COLOR: #0000ff">="java.lang.String"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            update</span>
						<span style="COLOR: #0000ff">="true"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            insert</span>
						<span style="COLOR: #0000ff">="true"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            access</span>
						<span style="COLOR: #0000ff">="property"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            column</span>
						<span style="COLOR: #0000ff">="code_name"</span>
						<span style="COLOR: #ff0000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #0000ff">/&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #008000">&lt;!--</span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            To add non XDoclet property mappings, create a file named<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                hibernate-properties-SynDepartment.xml<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            containing the additional properties and place it in your merge dir.<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span>
						<span style="COLOR: #008000">--&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">class</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #0000ff">&lt;/</span>
						<span style="COLOR: #800000">hibernate-mapping</span>
						<span style="COLOR: #0000ff">&gt;</span>
						<span style="COLOR: #000000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
				</div>
				<p>
						<br /> 控制台中部分信息如下：</p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #000000">[schemaexport] drop table syn_dept cascade constraints<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />[schemaexport] go<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />[schemaexport] drop sequence hibernate_sequence<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />[schemaexport] go<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />[schemaexport] create table syn_dept (<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />[schemaexport] id number(19,0) not null,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />[schemaexport] code_name varchar2(255),<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />[schemaexport] primary key (id)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />[schemaexport] )</span>
				</div>
				<p>DB中已经生成syn_dept表了,快去看下吧!<br /><br />参考资料：Hibernate持久化技术详解</p>
		</div>
<img src ="http://www.blogjava.net/iKingQu/aggbug/40312.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-04-10 19:42 <a href="http://www.blogjava.net/iKingQu/articles/40312.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Struts自定义标签库-----列表显示</title><link>http://www.blogjava.net/iKingQu/articles/39683.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Thu, 06 Apr 2006 14:10:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/39683.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/39683.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/39683.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/39683.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/39683.html</trackback:ping><description><![CDATA[在Struts应用中，到<a href="/Jkallen/archive/2006/03/07/34151.html" target="_blank">JSP页面上显示下拉列表框</a>应该是常有的事。<br />　　在基于是Struts的MVC框架中显示下拉框，有好些方法，用自定义标签库就是其中之一。<br /><br />　　若我们的此下拉框是放在基于HtmlForm中的。Struts可以通过ActionForm来保存其历史记录（不排除我们人为地给此ActionForm清理一下）。然而此自定义标签库却没有此功能！因为它没有通过过ActionForm中的字段来保存其记录。所以选择的时候可以根据自己的需要来定（我觉得在ActionForm中处理List列表框真的是一件非常庞大的工程:) ）。<br /><br />　　JSP中对标签的应用：
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_2_53_Open_Image" style="DISPLAY: inline" onclick="this.style.display='none'; Codehighlighter1_2_53_Open_Text.style.display='none'; Codehighlighter1_2_53_Closed_Image.style.display='inline'; Codehighlighter1_2_53_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_2_53_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2_53_Closed_Text.style.display='none'; Codehighlighter1_2_53_Open_Image.style.display='inline'; Codehighlighter1_2_53_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">&lt;%</span><span id="Codehighlighter1_2_53_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_2_53_Open_Text" style="DISPLAY: inline"><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">@ taglib uri</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">/WEB-INF/self-html.tld</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> prefix</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">=</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">test</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5">"</span><span style="COLOR: #000000; BACKGROUND-COLOR: #f5f5f5"> </span></span><span style="COLOR: #000000; BACKGROUND-COLOR: #ffff00">%&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">div </span><span style="COLOR: #ff0000">class</span><span style="COLOR: #0000ff">="formitem"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">span </span><span style="COLOR: #ff0000">class</span><span style="COLOR: #0000ff">="parameter_name"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">所属栏目：</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">span</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">span </span><span style="COLOR: #ff0000">class</span><span style="COLOR: #0000ff">="parameter_value"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">test:category </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="dto.id"</span><span style="COLOR: #ff0000"> type</span><span style="COLOR: #0000ff">="17"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">span</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />     </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">div</span><span style="COLOR: #0000ff">&gt;</span></div><p>　　<br />　　web.xml配置文件中：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #008000">&lt;!--</span><span style="COLOR: #008000"> self Tag Library Descriptors </span><span style="COLOR: #008000">--&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">taglib</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">taglib-uri</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">/WEB-INF/self-html.tld</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">taglib-uri</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">taglib-location</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">/WEB-INF/self-html.tld</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">taglib-location</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">taglib</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />self-html.tld定义：<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">taglib</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">tlibversion</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">1.0</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">tlibversion</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">jspversion</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">1.1</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">jspversion</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">shortname</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">netedu</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">shortname</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> <img src="http://www.blogjava.net/images/dot.gif" /> <img src="http://www.blogjava.net/images/dot.gif" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">tag</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">category</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">tagclass</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">com.CategoryTag</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">tagclass</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">bodycontent</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">empty</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">bodycontent</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">info</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">tag here</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">info</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">attribute</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">name</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">required</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">false</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">required</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">rtexprvalue</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">false</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">rtexprvalue</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">attribute</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">attribute</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">id</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">name</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  <img src="http://www.blogjava.net/images/dot.gif" />  <img src="http://www.blogjava.net/images/dot.gif" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /> </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">tag</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">taglib</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><p>　　以后自己就有什么扩展的需要就是在这儿加参数了！<br /><br /><br />　　总算是到了标签库的定义的地方了：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_0_23_Open_Image" style="DISPLAY: inline" onclick="this.style.display='none'; Codehighlighter1_0_23_Open_Text.style.display='none'; Codehighlighter1_0_23_Closed_Image.style.display='inline'; Codehighlighter1_0_23_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_23_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_23_Closed_Text.style.display='none'; Codehighlighter1_0_23_Open_Image.style.display='inline'; Codehighlighter1_0_23_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_23_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_0_23_Open_Text" style="DISPLAY: inline"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /> * </span><span style="COLOR: #808080">@author</span><span style="COLOR: #008000"> test <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /> </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_69_2245_Open_Image" style="DISPLAY: inline" onclick="this.style.display='none'; Codehighlighter1_69_2245_Open_Text.style.display='none'; Codehighlighter1_69_2245_Closed_Image.style.display='inline'; Codehighlighter1_69_2245_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_69_2245_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_69_2245_Closed_Text.style.display='none'; Codehighlighter1_69_2245_Open_Image.style.display='inline'; Codehighlighter1_69_2245_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> CategoryTag </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> TagSupport </span><span id="Codehighlighter1_69_2245_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_69_2245_Open_Text" style="DISPLAY: inline"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_72_149_Open_Image" onclick="this.style.display='none'; Codehighlighter1_72_149_Open_Text.style.display='none'; Codehighlighter1_72_149_Closed_Image.style.display='inline'; Codehighlighter1_72_149_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_72_149_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_72_149_Closed_Text.style.display='none'; Codehighlighter1_72_149_Open_Image.style.display='inline'; Codehighlighter1_72_149_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span><span id="Codehighlighter1_72_149_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id="Codehighlighter1_72_149_Open_Text"><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> (non-Javadoc)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * @see javax.servlet.jsp.tagext.Tag#doStartTag()<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_199_2242_Open_Image" onclick="this.style.display='none'; Codehighlighter1_199_2242_Open_Text.style.display='none'; Codehighlighter1_199_2242_Closed_Image.style.display='inline'; Codehighlighter1_199_2242_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_199_2242_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_199_2242_Closed_Text.style.display='none'; Codehighlighter1_199_2242_Open_Image.style.display='inline'; Codehighlighter1_199_2242_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> doStartTag() </span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> JspException </span><span id="Codehighlighter1_199_2242_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_199_2242_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> TODO Auto-generated method stub</span><span style="COLOR: #008000"><br /><img id="Codehighlighter1_256_2058_Open_Image" onclick="this.style.display='none'; Codehighlighter1_256_2058_Open_Text.style.display='none'; Codehighlighter1_256_2058_Closed_Image.style.display='inline'; Codehighlighter1_256_2058_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_256_2058_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_256_2058_Closed_Text.style.display='none'; Codehighlighter1_256_2058_Open_Image.style.display='inline'; Codehighlighter1_256_2058_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_256_2058_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_256_2058_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            JspWriter out </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> pageContext.getOut();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">jspwriter是一个隐含对象，用于向jsp网页输出内容。输出的目标由</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">            CategoryManager manager </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> getManager();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            List options</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(type</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">Constants.SORT_VALUE_ARCHIVE_YEAR)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                options</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">getArchiveYear();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(options</span><span style="COLOR: #000000">==</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">||</span><span style="COLOR: #000000">options.size()</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                options</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">UMParameterUtil.getParameters(type);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(options</span><span style="COLOR: #000000">==</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">||</span><span style="COLOR: #000000">options.size()</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />               options</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> manager.getCategorys(type);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            BaseCategoryDTO dto;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            ParametersDTO param;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            Object o </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (bean </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                    o </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> RequestUtils.lookup(pageContext, bean, property, scope);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />           <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (o </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> (( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(o </span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000"> Integer))</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">( </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(o </span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000"> Long))</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(o </span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000"> List))</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(o <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000"> Long[])) ))<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                    </span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> JspException(<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                            </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">bean or property must be instanceof Long or List</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;select </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">name</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, name));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">id</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, id));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">multiple</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, multiple));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">class</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, styleClass));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">size</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, String.valueOf(size)));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">onchange</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, onchange));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">style</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, style));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">disable</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, disable));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (showAll) out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;option value=-1&gt;不限&lt;/option&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (showNull) out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;option value=''&gt;&lt;/option&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                printOption(out, options, o);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;/select&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img id="Codehighlighter1_2092_2164_Open_Image" onclick="this.style.display='none'; Codehighlighter1_2092_2164_Open_Text.style.display='none'; Codehighlighter1_2092_2164_Closed_Image.style.display='inline'; Codehighlighter1_2092_2164_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_2092_2164_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2092_2164_Closed_Text.style.display='none'; Codehighlighter1_2092_2164_Open_Image.style.display='inline'; Codehighlighter1_2092_2164_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> }</span></span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000"> (IOException ioException) </span><span id="Codehighlighter1_2092_2164_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_2092_2164_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">throw</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> JspException(ioException.getMessage());<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">catch</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> (SKIP_BODY);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">return super.doStartTag();</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span></span></div><p><br />　　注：<br />　　有options= manager.getCategorys(type);其中manager是CategoryManager类。此方法返回的一个List就是下拉框的值。具体实现可由我们自己来定义好了！记得在JSP中也有&lt;test:category name="dto..id" type="17"/&gt;，其中的type="17"（比如说可以是传一个DB中的一个表的一个外键）就是此方法中的初始化参数值了（关于此标签库的定义的一些setter and getter方法中也舍了）.既然是库当然要通用。这个type就是通用的一个关键入口，不过显然这样一样可读性打了几分折扣。<br /><br />　　TaglibUtil.attrFormat("name", name)的方法如下：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_24_223_Open_Image" onclick="this.style.display='none'; Codehighlighter1_24_223_Open_Text.style.display='none'; Codehighlighter1_24_223_Closed_Image.style.display='inline'; Codehighlighter1_24_223_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_24_223_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_24_223_Closed_Text.style.display='none'; Codehighlighter1_24_223_Open_Image.style.display='inline'; Codehighlighter1_24_223_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> TaglibUtil </span><span id="Codehighlighter1_24_223_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_24_223_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img id="Codehighlighter1_95_221_Open_Image" onclick="this.style.display='none'; Codehighlighter1_95_221_Open_Text.style.display='none'; Codehighlighter1_95_221_Closed_Image.style.display='inline'; Codehighlighter1_95_221_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_95_221_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_95_221_Closed_Text.style.display='none'; Codehighlighter1_95_221_Open_Image.style.display='inline'; Codehighlighter1_95_221_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /> </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> String attrFormat(String attrName, Object attrValue) </span><span id="Codehighlighter1_95_221_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_95_221_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (attrValue</span><span style="COLOR: #000000">!=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />         </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> attrName </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000"> + attrValue + </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />         </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /> }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><p><br />　　还有一个就是printOption，这个方法应该比较重要了。它负责生成了列表框的选择的值与名称。如：</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_19_934_Open_Image" onclick="this.style.display='none'; Codehighlighter1_19_934_Open_Text.style.display='none'; Codehighlighter1_19_934_Closed_Image.style.display='inline'; Codehighlighter1_19_934_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_19_934_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_19_934_Closed_Text.style.display='none'; Codehighlighter1_19_934_Open_Image.style.display='inline'; Codehighlighter1_19_934_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">excludeFlag) </span><span id="Codehighlighter1_19_934_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_19_934_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;option </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                    </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">value</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, id<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                            .toString()));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.println(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">sysValue</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, sysValue));<br /><img id="Codehighlighter1_246_766_Open_Image" onclick="this.style.display='none'; Codehighlighter1_246_766_Open_Text.style.display='none'; Codehighlighter1_246_766_Closed_Image.style.display='inline'; Codehighlighter1_246_766_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_246_766_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_246_766_Closed_Text.style.display='none'; Codehighlighter1_246_766_Open_Image.style.display='inline'; Codehighlighter1_246_766_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(o</span><span style="COLOR: #000000">!=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">)</span><span id="Codehighlighter1_246_766_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_246_766_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_285_365_Open_Image" onclick="this.style.display='none'; Codehighlighter1_285_365_Open_Text.style.display='none'; Codehighlighter1_285_365_Closed_Image.style.display='inline'; Codehighlighter1_285_365_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_285_365_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_285_365_Closed_Text.style.display='none'; Codehighlighter1_285_365_Open_Image.style.display='inline'; Codehighlighter1_285_365_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />                </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(o </span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000"> Long)</span><span id="Codehighlighter1_285_365_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_285_365_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (id.equals(o)) out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">selected </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />                }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br /><img id="Codehighlighter1_429_558_Open_Image" onclick="this.style.display='none'; Codehighlighter1_429_558_Open_Text.style.display='none'; Codehighlighter1_429_558_Closed_Image.style.display='inline'; Codehighlighter1_429_558_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_429_558_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_429_558_Closed_Text.style.display='none'; Codehighlighter1_429_558_Open_Image.style.display='inline'; Codehighlighter1_429_558_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />                    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(o </span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000"> List)</span><span id="Codehighlighter1_429_558_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_429_558_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (((List)o).contains(id)) <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                            out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">selected </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);  <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />                    }</span></span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> <br /><img id="Codehighlighter1_612_752_Open_Image" onclick="this.style.display='none'; Codehighlighter1_612_752_Open_Text.style.display='none'; Codehighlighter1_612_752_Closed_Image.style.display='inline'; Codehighlighter1_612_752_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_612_752_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_612_752_Closed_Text.style.display='none'; Codehighlighter1_612_752_Open_Image.style.display='inline'; Codehighlighter1_612_752_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />                        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(o </span><span style="COLOR: #0000ff">instanceof</span><span style="COLOR: #000000"> Long[])</span><span id="Codehighlighter1_612_752_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_612_752_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(isSelected(id,(Long[])o))<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                                out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">selected </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">); <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />                        }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />            }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />           </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> if (dto.getId().equals(o)) out.print("selected ");</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">            out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(name);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            out.print(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;/option&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><p><br />　　不要郁闷id是如何来的。当然是从options= manager.getCategorys(type)中来的了。</p><p>　　也许说得不是太详细，代码也有些残缺。不过实现过程基本全在这里了。我觉得它非常棒，直到我用到它的onchange,style时！简直在直接跟使用html中的list一样！</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">　　　<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">size</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, String.valueOf(size)));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">onchange</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, onchange));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">style</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, style));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            out.print(TaglibUtil.attrFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">disable</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, disable));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><p><br />　　至少给我们指明了一些自定义标签库的经验！</p><img src ="http://www.blogjava.net/iKingQu/aggbug/39683.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-04-06 22:10 <a href="http://www.blogjava.net/iKingQu/articles/39683.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]瞎掰开源派系</title><link>http://www.blogjava.net/iKingQu/articles/39561.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Thu, 06 Apr 2006 04:54:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/39561.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/39561.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/39561.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/39561.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/39561.html</trackback:ping><description><![CDATA[原文转自：javaeye<br /><br /><h3><a name="Java%E5%BC%80%E6%BA%90%E8%BD%AF%E4%BB%B6%E5%85%AD%E5%A4%A7%E5%B8%AE%E6%B4%BE-%E4%B8%90%E5%B8%AEApacheSoftwareFoundation"></a>丐帮 - Apache Software Foundation</h3><p>在我开始学习Java的时候，Apache的Jakarta子项目还很弱小，Apache的头牌是Apache HTTPD Server(至今也还是头牌)，如今已经成了江湖第一大帮。Apache势力庞大，背后有众多大厂商的支持，例如IBM资助了apache的好几个 project，Sun则和tomcat合作密切，而BEA砸下重资在Beehive上面。有了官府的支持，Apache理所当然了成了第一大帮。不过 Apache的问题就是组织成员太复杂了，旗下各个project来自三山五岳，良莠不齐，甚至各个门下子弟还经常发生冲突，漫无纪律。例如ant是构建工具头牌，Maven又要抢山头；OJB是持久层头牌，但是Torque还不肯让位，他两位还没有把座次安排好，iBATIS也要加入丐帮......</p><p>对于这样一个没有组织纪律，自己内部互相冲突的丐帮来说，我已经不存什么好感了，除了丐帮还时不时有几个优秀的弟子，例如log4j，ant，common，他注定永远不能成为武林盟主。</p><h3><a name="Java%E5%BC%80%E6%BA%90%E8%BD%AF%E4%BB%B6%E5%85%AD%E5%A4%A7%E5%B8%AE%E6%B4%BE-%E5%B0%91%E6%9E%97EclipseFoundation"></a>少林 - Eclipse Foundation</h3><p>Eclipse来头不小，直接来自IBM，并且已经得到业界众多厂商的支持，由于有官府的大力支持，Eclipse成为武林盟主的可能性很大。 Eclipse下属的各个子项目也都身怀绝技，SWT，EMF，GEF，RCP，SDO，每个都是独当一面的好手。最关键的是Eclipse是WSAD的基础，IBM很多开发人员直接为Eclipse开发，这意味着帮派和官府的直接勾结，待到IBM把Rose XDE的功能放入Eclipse，号令天下也是指日可待。</p><h3><a name="Java%E5%BC%80%E6%BA%90%E8%BD%AF%E4%BB%B6%E5%85%AD%E5%A4%A7%E5%B8%AE%E6%B4%BE-%E6%AD%A6%E5%BD%93JBossInc"></a>武当 - JBoss Inc</h3><p>JBoss来自草莽，没有丐帮的人多势众，没有少林的官府支持，然而经过自身的努力，已经跻身江湖顶级帮派行列，并且具备了很大的发言权。 JBoss的特点是武功自成一派，旗下每个子项目都具备非常强悍的实力，但是各个子项目又可以组成一个有机的整体，组成一个阵势，发挥意想不到的威力。其中JBoss的独门武功－Hibernate则是威力最大的杀手锏，凭借这一功夫，JBoss虽然不算很大，但是已经成为了Java企业界的巨头之一，能够以自己的声音影响整个武林。</p><h3><a name="Java%E5%BC%80%E6%BA%90%E8%BD%AF%E4%BB%B6%E5%85%AD%E5%A4%A7%E5%B8%AE%E6%B4%BE-%E5%B3%A8%E5%B5%8BOpensymphony"></a>峨嵋 - Opensymphony</h3><p>opensymphony不能跟上述三大帮派相比，但是她独具特色，门下弟子不多，但是各个都有绝活，因此在武林当中也站稳了脚跟。例如Webwork成为了下一代MVC框架Struts Ti的核心，OSCache是颇受欢迎的Cache产品，Quartz则是很有名的Java Job软件，Sitemesh也是一款灵巧易用的软件。所有这些虽然都不算重量级武功，但是都独当一面，在整个武林都独树一帜，令人侧目。</p><h3><a name="Java%E5%BC%80%E6%BA%90%E8%BD%AF%E4%BB%B6%E5%85%AD%E5%A4%A7%E5%B8%AE%E6%B4%BE-%E9%80%8D%E9%81%A5%E6%B4%BEcodehaus"></a>逍遥派 - codehaus</h3><p>codehaus下面的Groovy, DamageControl, XStream, Nano, Pico, AspectWerkz武功都是犹如凌波微步般, 既实用又优雅，并且该组织背后有有ThoughWorks这样一个技术至上的咨询公司撑腰，所以它的武功都是讲究敏捷，优雅，易用，于繁重的开发工作中体味出一丝丝悠闲的乐趣，真正符合了逍遥的意境。</p><h3><a name="Java%E5%BC%80%E6%BA%90%E8%BD%AF%E4%BB%B6%E5%85%AD%E5%A4%A7%E5%B8%AE%E6%B4%BE-%E6%98%86%E4%BB%91objectweb"></a>昆仑 - objectweb</h3><p>objectweb僻处法国，远离IT全球中心，就好像昆仑远处西域一样。因而objectweb也和中原武学有很大的不同，剑走偏锋。例如objectweb的项目偏重于cluster和分布式方面的支持，例如c-jdbc，rmi-jdbc，Perseus，XAPool等等。正是因为他的剑走偏锋，才使得他不那么知名于中原武林，也正是因为剑走偏锋，才使得他独树一帜，保持了自己独有的特色。<br /></p><img src ="http://www.blogjava.net/iKingQu/aggbug/39561.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-04-06 12:54 <a href="http://www.blogjava.net/iKingQu/articles/39561.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Hibernate获取数据方式与缓存使用</title><link>http://www.blogjava.net/iKingQu/articles/39560.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Thu, 06 Apr 2006 04:46:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/39560.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/39560.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/39560.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/39560.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/39560.html</trackback:ping><description><![CDATA[
		<p>Hibernate获取数据的方式有不同的几种，其与缓存结合使用的效果也不尽相同，而Hibernate中具体怎么使用缓存其实是我们很关心的一个问题，直接涉及到性能方面。<br />缓存在Hibernate中主要有三个方面：一级缓存、二级缓存和查询缓存；一级缓存在Hibernate中对应的即为session范围的缓存，也就是当session关闭时缓存即被清除，一级缓存在Hibernate中是不可配置的部分；二级缓存在Hibernate中对应的即为SessionFactory范围的缓存，通常来讲SessionFactory的生命周期和应用的生命周期相同，所以可以看成是进程缓存或集群缓存，二级缓存在Hibernate中是可以配置的，可以通过class-cache配置类粒度级别的缓存(class-cache在class中数据发生任何变化的情况下自动更新)，同时也可通过collection-cache配置集合粒度级别的缓存(collection-cache仅在collection中增加了元素或者删除了元素的情况下才自动更新，也就是当collection中元素发生值的变化的情况下它是不会自动更新的)，缓存自然会带来并发的访问问题，这个时候相应的就要根据应用来设置缓存所采用的事务隔离级别，和数据库的事务隔离级别概念基本一样，没什么多介绍的，^_^；查询缓存在Hibernate同样是可配置的，默认是关闭的，可以通过设置cache.use_ query_cache为true来打开查询缓存。根据缓存的通常实现策略，我们可以来理解Hibernate的这三种缓存，缓存的实现通过是通过key/value的Map方式来实现，在Hibernate的一级、二级和查询缓存也同样如此，一级、二级缓存使用的key均为po的主键ID，value即为po实例对象，查询缓存使用的则为查询的条件、查询的参数、查询的页数，value有两种情况，如果采用的是select po.property这样的方式那么value为整个结果集，如采用的是from这样的方式那么value为获取的结果集中各po对象的主键ID，这样的作用很明显，节省内存，^_^<br />简单介绍完Hibernate的缓存后，再结合Hibernate的获取数据方式来说明缓存的具体使用方式，在Hibernate中获取数据常用的方式主要有四种：Session.load、Session.get、Query.list、Query.iterator。<br />1、Session.load<br />      在执行session.load时，Hibernate首先从当前session的一级缓存中获取id对应的值，在获取不到的情况下，将根据该对象是否配置了二级缓存来做相应的处理，如配置了二级缓存，则从二级缓存中获取id对应的值，如仍然获取不到则还需要根据是否配置了延迟加载来决定如何执行，如未配置延迟加载则从数据库中直接获取，在从数据库获取到数据的情况下，Hibernate会相应的填充一级缓存和二级缓存，如配置了延迟加载则直接返回一个代理类，只有在触发代理类的调用时才进行数据库查询的操作。<br />      在这样的情况下我们就可以看到，在session一直打开的情况下，要注意在适当的时候对一级缓存进行刷新操作，通常是在该对象具有单向关联维护的时候，在Hibernate中可以使用象session.clear、session.evict的方式来强制刷新一级缓存。<br />      二级缓存则在数据发生任何变化(新增、更新、删除)的情况下都会自动的被更新。<br />2、Session.get<br />      在执行Session.get时，和Session.load不同的就是在当从缓存中获取不到时，直接从数据库中获取id对应的值。<br />3、Query.list<br />      在执行Query.list时，Hibernate的做法是首先检查是否配置了查询缓存，如配置了则从查询缓存中查找key为查询语句+查询参数+分页条件的值，如获取不到则从数据库中进行获取，从数据库获取到后Hibernate将会相应的填充一级、二级和查询缓存，如获取到的为直接的结果集，则直接返回，如获取到的为一堆id的值，则再根据id获取相应的值(Session.load)，最后形成结果集返回，可以看到，在这样的情况下，list也是有可能造成N次的查询的。<br />      查询缓存在数据发生任何变化的情况下都会被自动的清空。<br />4、Query.iterator<br />      在执行Query.iterator时，和Query.list的不同的在于从数据库获取的处理上，Query.iterator向数据库发起的是select id from这样的语句，也就是它是先获取符合查询条件的id，之后在进行iterator.next调用时才再次发起session.load的调用获取实际的数据。<br />      可见，在拥有二级缓存并且查询参数多变的情况下，Query.iterator会比Query.list更为高效。<br /><br />这四种获取数据的方式都各有适用的场合，要根据实际情况做相应的决定，^_^，最好的方式无疑就是打开show_sql选项看看执行的情况来做分析，系统结构上只用保证这种调整是容易实现的就好了，在cache这个方面的调整自然是非常的容易，只需要调整配置文件里的设置，而查询的方式则可对外部进行屏蔽，这样要根据实际情况调整也非常容易。<br /><br />推荐两篇关于Hibernate缓存机制介绍的文章：<br /><a href="http://gocom.primeton.com/blog/index.php?op=ViewArticle&amp;articleId=467&amp;blogId=37&amp;src=jdon&amp;srcforum=62"><font color="#000080">http://gocom.primeton.com/blog/index.php?op=ViewArticle&amp;articleId=467&amp;blogId=37&amp;src=jdon&amp;srcforum=62</font></a><br /><a href="http://club.gamvan.com/club/clubPage.jsp?ccStyle=0&amp;tID=10456&amp;ccID=37"><font color="#000080">http://club.gamvan.com/club/clubPage.jsp?ccStyle=0&amp;tID=10456&amp;ccID=37</font></a></p>
<img src ="http://www.blogjava.net/iKingQu/aggbug/39560.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-04-06 12:46 <a href="http://www.blogjava.net/iKingQu/articles/39560.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]dom4j(Version 1.6.1)快速入门</title><link>http://www.blogjava.net/iKingQu/articles/39350.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Wed, 05 Apr 2006 04:35:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/39350.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/39350.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/39350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/39350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/39350.html</trackback:ping><description><![CDATA[
		<div class="postTitle">Parsing XML</div>
		<br />    或许你想要做的第一件事情就是解析一个某种类型的XML文档，用dom4j很容易做到。请看下面的示范代码：<br /><br />import java.net.URL;<br /><br />import org.dom4j.Document;<br />import org.dom4j.DocumentException;<br />import org.dom4j.io.SAXReader;<br /><br />public class Foo {<br /><br />    public Document parse(URL url) throws DocumentException {<br />        SAXReader reader = new SAXReader();<br />        Document document = reader.read(url);<br />        return document;<br />    }<br />}<br /><br /><h4>使用迭代器（Iterators）</h4><br />    我们可以通过多种方法来操作XML文档，这些方法返回java里标准的迭代器（Iterators）。例如：<br /><br />public void bar(Document document) throws DocumentException {<br />        Element root = document.getRootElement();<br />        //迭代根元素下面的所有子元素<br />        for ( Iterator i = root.elementIterator(); i.hasNext(); ) {<br />            Element element = (Element) i.next();<br />            //处理代码<br />        }<br /><br />        //迭代根元素下面名称为"foo"的子元素<br />        for ( Iterator i = root.elementIterator( "foo" ); i.hasNext(); ) {<br />            Element foo = (Element) i.next();<br />            //处理代码<br />        }<br /><br />        // 迭代根元素的属性attributes）元素<br />        for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {<br />            Attribute attribute = (Attribute) i.next();<br />            // do something<br />        }<br />     }<br /><br /><h4>强大的XPath导航</h4><br />    在dom4j中XPath可以表示出在XML树状结构中的Document或者任意的节点（Node）（例如：Attribute，Element 或者ProcessingInstruction等）。它可以使在文档中复杂的操作仅通过一行代码就可以完成。例如：<br /><br />public void bar(Document document) {<br />        List list = document.selectNodes( "//foo/bar" );<br /><br />        Node node = document.selectSingleNode( "//foo/bar/author" );<br /><br />        String name = node.valueOf( "@name" );<br />    }<br /><br />    如果你想得到一个XHTML文档中的所有超文本链接（hypertext links）你可以使用下面的代码：<br /><br />    public void findLinks(Document document) throws DocumentException {<br /><br />        List list = document.selectNodes( "//a/@href" );<br /><br />        for (Iterator iter = list.iterator(); iter.hasNext(); ) {<br />            Attribute attribute = (Attribute) iter.next();<br />            String url = attribute.getValue();<br />        }<br />    }<br /><br />    如果你需要关于XPath语言的任何帮助，我们强烈推荐这个站点<a class="l2" href="http://www.zvon.org/xxl/XPathTutorial/General/examples.html" target="_blank">Zvon tutorial</a>他会通过一个一个的例子引导你学习。<br /><br /><h4>快速遍历（Fast Looping）</h4><br /><br />如果你不得不遍历一个非常大的XML文档，然后才去执行，我们建议你使用快速遍历方法（fast looping method），它可以避免为每一个循环的节点创建一个迭代器对象,如下所示：<br /><br />public void treeWalk(Document document) {<br />        treeWalk( document.getRootElement() );<br />    }<br /><br />    public void treeWalk(Element element) {<br />        for ( int i = 0, size = element.nodeCount(); i &lt; size; i++ ) {<br />            Node node = element.node(i);<br />            if ( node instanceof Element ) {<br />                treeWalk( (Element) node );<br />            }<br />            else {<br />                // do something....<br />            }<br />        }<br />    }<br /><br /><h4>生成一个新的XML文档对象</h4><br />    在dom4j中你可能常常希望用程序生成一个XML文档对象，下面的程序为你进行了示范：<br /><br />import org.dom4j.Document;<br />import org.dom4j.DocumentHelper;<br />import org.dom4j.Element;<br /><br />public class Foo {<br /><br />    public Document createDocument() {<br />        Document document = DocumentHelper.createDocument();<br />        Element root = document.addElement( "root" );<br /><br />        Element author1 = root.addElement( "author" )<br />            .addAttribute( "name", "James" )<br />            .addAttribute( "location", "UK" )<br />            .addText( "James Strachan" );<br />        <br />        Element author2 = root.addElement( "author" )<br />            .addAttribute( "name", "Bob" )<br />            .addAttribute( "location", "US" )<br />            .addText( "Bob McWhirter" );<br /><br />        return document;<br />    }<br />}<br /><br /><h4>将一个文档对象写入文件中</h4><br />    将一个文档对象写入Writer对象的一个简单快速的途径是通过write()方法。<br /><br />        FileWriter out = new FileWriter( "foo.xml" );<br />        document.write( out );<br /><br />如果你想改变输出文件的排版格式，比如你想要一个漂亮的格式或者是一个紧凑的格式，或者你想用Writer 对象或者OutputStream 对象来操作，那么你可以使用XMLWriter 类。<br /><br />import org.dom4j.Document;<br />import org.dom4j.io.OutputFormat;<br />import org.dom4j.io.XMLWriter;<br /><br />public class Foo {<br /><br />    public void write(Document document) throws IOException {<br /><br />        // 写入文件<br />        XMLWriter writer = new XMLWriter(<br />            new FileWriter( "output.xml" )<br />        );<br />        writer.write( document );<br />        writer.close();<br /><br /><br />        // 以一种优雅的格式写入System.out对象<br />        OutputFormat format = OutputFormat.createPrettyPrint();<br />        writer = new XMLWriter( System.out, format );<br />        writer.write( document );<br /><br />        // 以一种紧凑的格式写入System.out对象<br />        format = OutputFormat.createCompactFormat();<br />        writer = new XMLWriter( System.out, format );<br />        writer.write( document );<br />    }<br />}<br /><br /><h4>转化为字符串，或者从字符串转化</h4><br />    如果你有一个文档（Document）对象或者任何一个节点（Node）对象的引用（reference），象属性（Attribute）或者元素（Element），你可以通过asXML()方法把它转化为一个默认的XML字符串：<br /><br />        Document document = ...;<br />        String text = document.asXML();<br /><br />如果你有一些XML内容的字符串表示，你可以通过DocumentHelper.parseText()方法将它重新转化为文档（Document）对象：<br /><br />        String text = "&lt;person&gt; &lt;name&gt;James&lt;/name&gt; &lt;/person&gt;";<br />        Document document = DocumentHelper.parseText(text);<br /><br /><h4>通过XSLT样式化文档（Document）</h4><br /><br />    使用Sun公司提供的<a class="l2" href="http://java.sun.com/xml/" target="_blank">JAXP</a> API将XSLT 应用到文档（Document）上是很简单的。它允许你使用任何的XSLT引擎（例如：Xalan或SAXON等）来开发。下面是一个使用JAXP创建一个转化器（transformer），然后将它应用到文档（Document）上的例子：<br /><br />import javax.xml.transform.Transformer;<br />import javax.xml.transform.TransformerFactory;<br /><br />import org.dom4j.Document;<br />import org.dom4j.io.DocumentResult;<br />import org.dom4j.io.DocumentSource;<br /><br />public class Foo {<br /><br />    public Document styleDocument(<br />        Document document, <br />        String stylesheet<br />    ) throws Exception {<br /><br />        // 使用 JAXP 加载转化器<br />        TransformerFactory factory = TransformerFactory.newInstance();<br />        Transformer transformer = factory.newTransformer( <br />            new StreamSource( stylesheet ) <br />        );<br /><br />        // 现在来样式化一个文档（Document）<br />        DocumentSource source = new DocumentSource( document );<br />        DocumentResult result = new DocumentResult();<br />        transformer.transform( source, result );<br /><br />        // 返回经过样式化的文档（Document）<br />        Document transformedDoc = result.getDocument();<br />        return transformedDoc;<br />    }<br />}<br /><br /><a class="l2" href="http://dom4j.org/guide.html" target="_blank">原文地址</a><br /><a class="l2" href="http://prdownloads.sourceforge.net/dom4j/dom4j-1.6.1.zip?download" target="_blank">dom4j下载地址</a><br /><img src ="http://www.blogjava.net/iKingQu/aggbug/39350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-04-05 12:35 <a href="http://www.blogjava.net/iKingQu/articles/39350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]有效编写软件的75条建议</title><link>http://www.blogjava.net/iKingQu/articles/38927.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 03 Apr 2006 06:35:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/38927.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/38927.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/38927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/38927.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/38927.html</trackback:ping><description><![CDATA[
		<p>1. 你们的项目组使用源代码管理工具了么？<br />　　应该用。VSS、CVS、PVCS、ClearCase、CCC/Harvest、FireFly都可以。我的选择是VSS。<br /><br />　　2. 你们的项目组使用缺陷管理系统了么？<br />　　应该用。ClearQuest太复杂，我的推荐是BugZilla。 <br /><br />　　3. 你们的测试组还在用Word写测试用例么？<br />　　不要用Word写测试用例（Test Case）。应该用一个专门的系统，可以是Test Manager，也可以是自己开发一个ASP.NET的小网站。主要目的是Track和Browse。 <br /><br />　　4. 你们的项目组有没有建立一个门户网站？<br />　　要有一个门户网站，用来放Contact Info、Baselined Schedule、News等等。推荐Sharepoint Portal Server 2003来实现，15分钟就搞定。买不起SPS 2003可以用WSS (Windows Sharepoint Service)。 <br /><br />　　5. 你们的项目组用了你能买到最好的工具么？<br />　　应该用尽量好的工具来工作。比如，应该用VS.NET而不是Notepad来写C#。用Notepad写程序多半只是一种炫耀。但也要考虑到经费，所以说是“你能买到最好的”。 <br /><br />　　6. 你们的程序员工作在安静的环境里么？<br />　　需要安静环境。这点极端重要，而且要保证每个人的空间大于一定面积。 <br /><br />　　7. 你们的员工每个人都有一部电话么？需要每人一部电话。而且电话最好是带留言功能的。当然，上这么一套带留言电话系统开销不小。不过至少每人一部电话要有，千万别搞得经常有人站起来喊：“某某某电话”。《人件》里面就强烈谴责这种做法。 <br /><br />　　8. 你们每个人都知道出了问题应该找谁么？<br />　　应该知道。任何一个Feature至少都应该有一个Owner，当然，Owner可以继续Dispatch给其他人。<br /><br />　　9. 你遇到过有人说“我以为…”么？<br />　　要消灭“我以为”。Never assume anything。 <br /><br />　　10. 你们的项目组中所有的人都坐在一起么？<br />　　需要。我反对Virtual Team，也反对Dev在美国、Test在中国这种开发方式。能坐在一起就最好坐在一起，好处多得不得了。 <br /><br />　　11. 你们的进度表是否反映最新开发进展情况？ <br />　　应该反映。但是，应该用Baseline的方法来管理进度表：维护一份稳定的Schedule，再维护一份最新更改。Baseline的方法也应该用于其它的Spec。Baseline是变更管理里面的一个重要手段。<br /><br />　　12. 你们的工作量是先由每个人自己估算的么？<br />　　应该让每个人自己估算。要从下而上估算工作量，而不是从上往下分派。除非有其他原因，比如政治任务工期固定等。 <br /><br />　　13. 你们的开发人员从项目一开始就加班么？<br />　　不要这样。不要一开始就搞疲劳战。从项目一开始就加班，只能说明项目进度不合理。当然，一些对日软件外包必须天天加班，那属于剥削的范畴。 <br /><br />　　14. 你们的项目计划中Buffer Time是加在每个小任务后面的么？<br />　　不要。Buffer Time加在每个小任务后面，很容易轻易的就被消耗掉。Buffer Time要整段的加在一个Milestone或者checkpoint前面。 <br /><br />　　15. 值得再多花一些时间，从95%做到100%好值得，非常值得。<br />　　尤其当项目后期人困马乏的时候，要坚持。这会给产品带来质的区别。<br /> <br />　　16. 登记新缺陷时，是否写清了重现步骤？<br />　　要。这属于Dev和Test之间的沟通手段。面对面沟通需要，详细填写Repro Steps也需要。<br /> <br />　　17. 写新代码前会把已知缺陷解决么？要。每个人的缺陷不能超过10个或15个，否则必须先解决老的bug才能继续写新代码。 <br /><br />　　18. 你们对缺陷的轻重缓急有事先的约定么？<br />　　必须有定义。Severity要分1、2、3，约定好：蓝屏和Data Lost算Sev 1，Function Error算Sev 2，界面上的算Sev 3。但这种约定可以根据产品质量现状适当进行调整。<br /><br />　　19. 你们对意见不一的缺陷有三国会议么？必须要有。要有一个明确的决策过程。这类似于CCB (Change Control Board)的概念。 <br /><br />　　20. 所有的缺陷都是由登记的人最后关闭的么？ <br />　　Bug应该由Opener关闭。Dev不能私自关闭Bug。 <br /><br />　　21. 你们的程序员厌恶修改老的代码么？<br />　　厌恶是正常的。解决方法是组织Code Review，单独留出时间来。XP也是一个方法。 <br /><br />　　22. 你们项目组有Team Morale Activity么？<br />　　每个月都要搞一次，吃饭、唱歌、Outing、打球、开卡丁车等等，一定要有。不要剩这些钱。<br /> <br />　　23. 你们项目组有自己的Logo么？<br />　　要有自己的Logo。至少应该有自己的Codename。 <br /><br />　　24. 你们的员工有印有公司Logo的T-Shirt么？<br />　　要有。能增强归属感。当然，T-Shirt要做的好看一些，最好用80支的棉来做。别没穿几次就破破烂烂的。<br /><br />　　25. 总经理至少每月参加次项目组会议要的。<br />　　要让team member觉得高层关注这个项目。 <br /><br />　　26. 你们是给每个Dev开一个分支么？<br />　　反对。Branch的管理以及Merge的工作量太大，而且容易出错。 <br /><br />　　27. 有人长期不Check-In代码么？<br />　　不可以。对大部分项目来说，最多两三天就应该Check-In。 <br /><br />　　28. 在Check-In代码时都填写注释了么？<br />　　要写的，至少一两句话，比如“解决了Bug No.225”。如果往高处拔，这也算做“配置审计”的一部分。<br /><br />　　29. 有没有设定每天Check-In的最后期限？<br />　　要的，要明确Check-In Deadline。否则会Build Break。<br /> <br />　　30. 你们能把所有源码一下子编译成安装文件吗？ <br />　　要的。这是每日编译（Daily Build）的基础。而且必须要能够做成自动的。 <br /><br />        31. 你们的项目组做每日编译么？<br />　　当然要做。有三样东西是软件项目/产品开发必备的：1. bug management; 2. source control; 3. daily build。 <br />　　32. 你们公司有没有积累一个项目风险列表？<br />　　要。Risk Inventory。否则，下个项目开始的时候，又只能拍脑袋分析Risk了。<br /><br />　　33. 设计越简单越好越简单越好。<br />　　设计时候多一句话，将来可能就带来无穷无尽的烦恼。应该从一开始就勇敢的砍。这叫scope management。 <br /><br />　　34. 尽量利用现有的产品、技术、代码千万别什么东西都自己Coding。BizTalk和Sharepoint就是最好的例子，有这两个作为基础，可以把起点提高很多。或者可以尽量多用现成的Control之类的。或者尽量用XML，而不是自己去Parse一个文本文件；尽量用RegExp，而不是自己从头操作字符串，等等等等。这就是“软件复用”的体现。 <br /><br />　　35. 你们会隔一段时间就停下来夯实代码么？<br />　　要。最好一个月左右一次。传言去年年初Windows组在Stevb的命令下停过一个月增强安全。Btw，“夯”这个字念“hang”，第一声。 <br /><br />　　36. 你们的项目组每个人都写Daily Report么？<br />　　要写。五分钟就够了，写10句话左右，告诉自己小组的人今天我干了什么。一则为了沟通，二则鞭策自己（要是游手好闲一天，自己都会不好意思写的）。<br /><br />　　37. 你们的项目经理会发出Weekly Report么？<br />　　要。也是为了沟通。内容包括目前进度，可能的风险，质量状况，各种工作的进展等。<br /><br />　　38. 你们项目组是否至少每周全体开会一次？<br />　　要。一定要开会。程序员讨厌开会，但每个礼拜开会时间加起来至少应该有4小时。包括team meeting, spec review meeting, bug triage meeting。千万别大家闷头写code。 <br /><br />　　39. 你们项目组的会议、讨论都有记录么？<br />　　会前发meeting request和agenda，会中有人负责主持和记录，会后有人负责发meeting minutes，这都是effective meeting的要点。而且，每个会议都要形成agreements和action items。<br /><br />　　40. 其他部门知道你们项目组在干什么么？<br />　　要发一些Newsflash给整个大组织。Show your team’s value。否则，当你坐在电梯里面，其他部门的人问：“你们在干嘛”，你回答“ABC项目”的时候，别人全然不知，那种感觉不太好。<br /> <br />　　41. 通过Email进行所有正式沟通 <br />　　Email的好处是免得抵赖。但也要避免矫枉过正，最好的方法是先用电话和当面说，然后Email来确认。 <br />　　42. 为项目组建立多个Mailing Group <br />　　如果在AD+Exchange里面，就建Distribution List。比如，我会建ABC Project Core Team，ABC Project Dev Team，ABC Project All Testers，ABC Project Extended Team等等。这样发起Email来方便，而且能让该收到email的人都收到、不该收到不被骚扰。 <br /><br />　　43. 每个人都知道哪里可以找到全部的文档么？<br />　　应该每个人都知道。这叫做知识管理（Knowledge Management）。最方便的就是把文档放在一个集中的File Share，更好的方法是用Sharepoint。 <br /><br />　　44. 你做决定、做变化时，告诉大家原因了么？<br />　　要告诉大家原因。Empower team member的手段之一是提供足够的information，这是MSF一开篇的几个原则之一。的确如此，tell me why是人之常情，tell me why了才能有understanding。中国人做事喜欢搞限制，限制信息，似乎能够看到某一份文件的人就是有身份的人。大错特错。权威、权力，不在于是不是能access information/data，而在于是不是掌握资源。<br /> <br />　　45. Stay agile and expect change 要这样。<br />　　需求一定会变的，已经写好的代码一定会被要求修改的。做好心理准备，对change不要抗拒，而是expect change。 <br /><br />　　46. 你们有没有专职的软件测试人员？<br />　　要有专职测试。如果人手不够，可以peer test，交换了测试。千万别自己测试自己的。 <br /><br />　　47. 你们的测试有一份总的计划来规定做什么和怎么做么？这就是Test Plan。要不要做性能测试？要不要做Usability测试？什么时候开始测试性能？测试通过的标准是什么？用什么手段，自动的还是手动的？这些问题需要用Test Plan来回答。<br /><br />　　48. 你是先写Test Case然后再测试的么？<br />　　应该如此。应该先设计再编程、先test case再测试。当然，事情是灵活的。我有时候在做第一遍测试的同时补上test case。至于先test case再开发，我不喜欢，因为不习惯，太麻烦，至于别人推荐，那试试看也无妨。 <br /><br />　　49. 你是否会为各种输入组合创建测试用例？<br />　　不要，不要搞边界条件组合。当心组合爆炸。有很多test case工具能够自动生成各种边界条件的组合——但要想清楚，你是否有时间去运行那么多test case。 <br /><br />       50. 你们的程序员能看到测试用例么？<br />　　要。让Dev看到Test Case吧。我们都是为了同一个目的走到一起来的：提高质量。<br /><br />　　51. 你们是否随便抓一些人来做易用性测试？ <br />　　要这么做。自己看自己写的程序界面，怎么看都是顺眼的。这叫做审美疲劳——臭的看久了也就不臭了，不方便的永久了也就习惯了。 <br /><br />　　52. 你对自动测试的期望正确么？<br />　　别期望太高。依我看，除了性能测试以外，还是暂时先忘掉“自动测试”吧，忘掉WinRunner和LoadRunner吧。对于国内的软件测试的现状来说，只能“矫枉必须过正”了。 <br /><br />　　53. 你们的性能测试是等所有功能都开发完才做的么？<br />　　不能这样。性能测试不能被归到所谓的“系统测试”阶段。早测早改正，早死早升天。<br /> <br />　　54. 你注意到测试中的杀虫剂效应了么？<br />　　虫子有抗药性，Bug也有。发现的新Bug越来越少是正常的。这时候，最好大家交换一下测试的area，或者用用看其他工具和手法，就又会发现一些新bug了。<br /><br />　　55. 你们项目组中有人能说出产品的当前整体质量情况么？<br />　　要有。当老板问起这个产品目前质量如何，Test Lead/Manager应该负责回答。 <br /><br />　　56. 你们有单元测试么？<br />　　单元测试要有的。不过没有单元测试也不是不可以，我做过没有单元测试的项目，也做成功了——可能是侥幸，可能是大家都是熟手的关系。还是那句话，软件工程是非常实践、非常工程、非常灵活的一套方法，某些方法在某些情况下会比另一些方法好，反之亦然。 <br /><br />　　57. 你们的程序员是写完代码就扔过墙的么？<br />　　大忌。写好一块程序以后，即便不做单元测试，也应该自己先跑一跑。虽然有了专门的测试人员，做开发的人也不可以一点测试都不做。微软还有Test Release Document的说法，程序太烂的话，测试有权踢回去。<br /><br />　　58. 你们的程序中所有的函数都有输入检查么？<br />　　不要。虽然说做输入检查是write secure code的要点，但不要做太多的输入检查，有些内部函数之间的参数传递就不必检查输入了，省点功夫。同样的道理，未必要给所有的函数都写注释。写一部分主要的就够了。<br /><br />　　59. 产品有统一的错误处理机制和报错界面么？<br />　　要有。最好能有统一的error message，然后每个error message都带一个error number。这样，用户可以自己根据error number到user manual里面去看看错误的具体描述和可能原因，就像SQL Server的错误那样。同样，ASP.NET也要有统一的Exception处理。可以参考有关的Application Block。 <br /><br />　　60. 你们有统一的代码书写规范么？<br />　　要有。Code Convention很多，搞一份来发给大家就可以了。当然，要是有FxCop这种工具来检查代码就更好了。 <br /><br />　　61. 你们的每个人都了解项目的商业意义么？<br />　　要。这是Vision的意思。别把项目只当成工作。有时候要想着自己是在为中国某某行业的信息化作先驱者，或者时不时的告诉team member，这个项目能够为某某某国家部门每年节省多少多少百万的纳税人的钱，这样就有动力了。平凡的事情也是可以有个崇高的目标的。<br /><br />　　62. 产品各部分的界面和操作习惯一致么？<br />　　要这样。要让用户觉得整个程序好像是一个人写出来的那样。<br /><br />　　63. 有可以作为宣传亮点的Cool Feature么？<br />　　要。这是增强团队凝聚力、信心的。而且，“一俊遮百丑”，有亮点就可以掩盖一些问题。这样，对于客户来说，会感觉产品从质量角度来说还是acceptable的。或者说，cool feature或者说亮点可以作为质量问题的一个事后弥补措施。 <br /><br />　　64. 尽可能缩短产品的启动时间要这样。<br />　　软件启动时间（Start-Up time）是客户对性能好坏的第一印象。<br /><br />　　65. 不要过于注重内在品质而忽视了第一眼的外在印象程序员容易犯这个错误：太看重性能、稳定性、存储效率，但忽视了外在感受。而高层经理、客户正相反。这两方面要兼顾，协调这些是PM的工作。<br /><br />　　66. 你们根据详细产品功能说明书做开发么？<br />　　要这样。要有设计才能开发，这是必须的。设计文档，应该说清楚这个产品会怎么运行，应该采取一些讲故事的方法。设计的时候千万别钻细节，别钻到数据库、代码等具体实现里面去，那些是后面的事情，一步步来不能着急。<br /> <br />　　67. 开始开发和测试之前每个人都仔细审阅功能设计么？<br />　　要做。Function Spec review是用来统一思想的。而且，review过以后形成了一致意见，将来再也没有人可以说“你看，当初我就是反对这么设计的，现在吃苦头了吧” <br /><br />　　68. 所有人都始终想着The Whole Image么？要这样。项目里面每个人虽然都只是在制造一片叶子，但每个人都应该知道自己在制造的那片叶子所在的树是怎么样子的。我反对软件蓝领，反对过分的把软件制造看成流水线、车间。参见第61条。<br /><br />　　69. Dev工作的划分是单纯纵向或横向的么？<br />　　不能单纯的根据功能模块分，或者单纯根据表现层、中间层、数据库层分。我推荐这么做：首先根据功能模块分，然后每个“层”都有一个Owner来Review所有人的设计和代码，保证consistency。 <br /><br />　　70. 你们的程序员写程序设计说明文档么？<br />　　要。不过我听说微软的程序员1999年以前也不写。所以说，写不写也不是绝对的，偷懒有时候也是可以的。参见第56条。<br /><br />　　71. 你在招人面试时让他写一段程序么？<br />　　要的。我最喜欢让人做字符串和链表一类的题目。这种题目有很多循环、判断、指针、递归等，既不偏向过于考算法，也不偏向过于考特定的API。 <br /><br />　　72. 你们有没有技术交流讲座？<br />　　要的。每一两个礼拜搞一次内部的Tech Talk或者Chalk Talk吧。让组员之间分享技术心得，这笔花钱送到外面去培训划算。 <br /><br />　　73. 你们的程序员都能专注于一件事情么？<br />　　要让程序员专注一件事。例如说，一个部门有两个项目和10个人，一种方法是让10个人同时参加两个项目，每个项目上每个人都花50%时间；另一种方法是5个人去项目A，5个人去项目B，每个人都100%在某一个项目上。我一定选后面一种。这个道理很多人都懂，但很多领导实践起来就把属下当成可以任意拆分的资源了。 <br /><br />　　74. 你们的程序员会夸大完成某项工作所需要的时间么？<br />　　会的，这是常见的，尤其会在项目后期夸大做某个change所需要的时间，以次来抵制change。解决的方法是坐下来慢慢磨，磨掉程序员的逆反心理，一起分析，并把估算时间的颗粒度变小。 <br /><br />　　75. 尽量不要用Virtual Heads 最好不要用Virtual Heads。<br />　　Virtual heads意味着resource is not secure，shared resource会降低resource的工作效率，容易增加出错的机会，会让一心二用的人没有太多时间去review spec、review design。一个dedicated的人，要强过两个只能投入50%时间和精力的人。我是吃过亏的：7个part time的tester，发现的Bug和干的活，加起来还不如两个full-time的。参见第73条。73条是针对程序员的，75条是针对Resource Manager的。</p>
		<p> </p>
<img src ="http://www.blogjava.net/iKingQu/aggbug/38927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-04-03 14:35 <a href="http://www.blogjava.net/iKingQu/articles/38927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]如何让View显示为最大化</title><link>http://www.blogjava.net/iKingQu/articles/37857.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 28 Mar 2006 10:59:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/37857.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/37857.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/37857.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/37857.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/37857.html</trackback:ping><description><![CDATA[第一种：利用Action<br /><font size="2">IWorkbenchWindow window = getViewSite().getWorkbenchWindow();<br />IWorkbenchAction max = ActionFactory.MAXIMIZE.create(window);<br />max.run();</font><br /><br />这段代码要放在何适的位置上才会起到合适的作用。<br /><br />第二种：利用Zoom<br />在ApplicationWorkbenchWindowAdvisor#postWindowOpen中做到<br />public void postWindowOpen() {<br />     IWorkbenchWindow window = Plugin.getDefault().getWorkbench().getActiveWorkbenchWindow();<br />     IViewPart part=null;<br />     try {<br />         part = window.getActivePage().showView(View.ID);<br />     } catch (PartInitException e) {<br />         e.printStackTrace();<br />     }<br />  <br />     if(part!=null){<br />        window.getActivePage().activate(part); <br />        window.getActivePage().bringToTop(part);<br />  <br />        WorkbenchPage realPage = (WorkbenchPage) window.getActivePage(); 
<p>        IWorkbenchPartReference partRef = window.getActivePage().getActivePartReference();</p><p>        if (partRef != null) {<br />            ((WorkbenchPage) window.getActivePage()).toggleZoom(partRef);<br />        }else{<br />         System.out.println("partRef is null!");<br />        }<br />    }<br />}<br /><br />原文地址 ：<a href="/hopeshared/archive/2006/03/27/37641.html">http://www.blogjava.net/hopeshared/archive/2006/03/27/37641.html</a></p><img src ="http://www.blogjava.net/iKingQu/aggbug/37857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-28 18:59 <a href="http://www.blogjava.net/iKingQu/articles/37857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]软件开发文档模板</title><link>http://www.blogjava.net/iKingQu/articles/37649.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 27 Mar 2006 09:37:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/37649.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/37649.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/37649.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/37649.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/37649.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 原文地址：http://www.blogjava.net/myblogs/archive/2006/03/27/37633.html												1　可行性研究报告																		　　可行性研究报告的编写目的是：说明该软件开发项目的实现在技术、经济和社会条件方面的可行性；评述为了合理地达到开发目标而可能先择的各种方案；说明论证所选定的方案。...&nbsp;&nbsp;<a href='http://www.blogjava.net/iKingQu/articles/37649.html'>阅读全文</a><img src ="http://www.blogjava.net/iKingQu/aggbug/37649.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-27 17:37 <a href="http://www.blogjava.net/iKingQu/articles/37649.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]正则表达式大全(regular expression) </title><link>http://www.blogjava.net/iKingQu/articles/36752.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Tue, 21 Mar 2006 19:12:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36752.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36752.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36752.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36752.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36752.html</trackback:ping><description><![CDATA[
		<p>
				<font size="2">关键字： 正则表达式，Regular Expression</font>
		</p>
		<p>
				<font size="2">原著：笑容</font>
		</p>
		<p>
				<font size="2">创作于：2004年05月03日<br />最后更新：<!--webbot bot="Timestamp" S-Type="REGENERATED" S-Format="%Y年%m月%d日 %H:%M" startspan -->2004年05月04日 21:12<!--webbot bot="Timestamp" endspan i-checksum="7688" --><br />版权声明：使用</font>
				<font size="2">
						<a href="http://www.creativecommons.cn/licenses/by-nc/1.0/">创作公用版权协议</a>
				</font>
		</p>
		<p>
				<font size="2">引用地址：&lt;a href="http://oo8h.51.net/docs/regular_expression.htm"&gt;正则表达式(regular expression)&lt;/a&gt;</font>
		</p>
		<hr />
		<p>
				<strong>前言</strong>
		</p>
		<p>正则表达式是烦琐的，但是强大的，学会之后的应用会让你除了提高效率外，会给你带来绝对的成就感。只要认真去阅读这些资料，加上应用的时候进行一定的参考，掌握正则表达式不是问题。<br /><br /></p>
		<h2>
				<a name="1._引子">1. 引子</a>
		</h2>
		<p>　　目前，正则表达式已经在很多软件中得到广泛的应用，包括*nix（Linux, Unix等），HP等操作系统，PHP，C#，Java等开发环境，以及很多的应用软件中，都可以看到正则表达式的影子。</p>
		<p>　　正则表达式的使用，可以通过简单的办法来实现强大的功能。为了简单有效而又不失强大，造成了正则表达式代码的难度较大，学习起来也不是很容易，所以需要付出一些努力才行，入门之后参照一定的参考，使用起来还是比较简单有效的。</p>
		<blockquote>
				<p>例子：<span style="BACKGROUND-COLOR: #00ffff"> ^.+@.+\\..+$ </span></p>
		</blockquote>
		<p>　　这样的代码曾经多次把我自己给吓退过。可能很多人也是被这样的代码给吓跑的吧。继续阅读本文将让你也可以自由应用这样的代码。</p>
		<p>　　注意：这里的第7部分跟前面的内容看起来似乎有些重复，目的是把前面表格里的部分重新描述了一次，目的是让这些内容更容易理解。</p>
		<h2>
				<strong>
						<a name="2._正则表达式的历史">2. 正则表达式的历史</a>
				</strong>
		</h2>
		<div id="nstext" valign="bottom">　　正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。 
<p>　　1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上，发表了一篇标题为“神经网事件的表示法”的论文，引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式，因此采用“正则表达式”这个术语。</p><p>　　随后，发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究，Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 <em>qed </em>编辑器。</p><p>　　如他们所说，剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。　</p></div>
		<h2>
				<strong>
						<a name="3._正则表达式定义">3. 正则表达式定义</a>
				</strong>
		</h2>
		<p>　　正则表达式(regular expression)描述了一种字符串匹配的模式，可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。</p>
		<blockquote>
				<ul>
						<li>
								<span style="BACKGROUND-COLOR: #ffff00">列目录时，　dir *.txt或ls *.txt中的*.txt就</span>
								<font color="#ff0000">
										<span style="BACKGROUND-COLOR: #ffff00">不</span>
								</font>
								<span style="BACKGROUND-COLOR: #ffff00">是一个正则表达式,因为这里*与正则式的*的含义是不同的。</span>
						</li>
				</ul>
		</blockquote>
		<p>　　正则表达式是由普通字符（例如字符 a 到 z）以及特殊字符（称为元字符）组成的文字模式。正则表达式作为一个模板，将某个字符模式与所搜索的字符串进行匹配。</p>
		<h3>
				<strong>
						<a name="3.1_普通字符">3.1 普通字符</a>
				</strong>
		</h3>
		<p>　　由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符，所有数字，所有标点符号以及一些符号。 </p>
		<h3>
				<a name="3.2_非打印字符">3.2 非打印字符</a>
		</h3>
		<p>
		</p>
		<table cellspacing="1" cellpadding="3" border="0">
				<tbody>
						<tr>
								<th style="FONT-SIZE: 12px" align="left">字符 </th>
								<th style="FONT-SIZE: 12px" align="left">含义</th>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\cx </td>
								<td style="FONT-SIZE: 12px">匹配由x指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\f </td>
								<td style="FONT-SIZE: 12px">匹配一个换页符。等价于 \x0c 和 \cL。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\n </td>
								<td style="FONT-SIZE: 12px">匹配一个换行符。等价于 \x0a 和 \cJ。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\r </td>
								<td style="FONT-SIZE: 12px">匹配一个回车符。等价于 \x0d 和 \cM。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\s </td>
								<td style="FONT-SIZE: 12px">匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\S </td>
								<td style="FONT-SIZE: 12px">匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\t </td>
								<td style="FONT-SIZE: 12px">匹配一个制表符。等价于 \x09 和 \cI。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\v </td>
								<td style="FONT-SIZE: 12px">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
						</tr>
				</tbody>
		</table>
		<br />　 <a name="3.3_特殊字符">3.3 特殊字符</a>　　所谓特殊字符，就是一些有特殊含义的字符，如上面说的"*.txt"中的*，简单的说就是表示任何字符串的意思。如果要查找文件名中有＊的文件，则需要对＊进行转义，即在其前加一个\。ls \*.txt。正则表达式有以下特殊字符。 
<p>　</p><p></p><table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">特别字符</th><th style="FONT-SIZE: 12px" align="left">说明</th></tr><tr><td style="FONT-SIZE: 12px">$</td><td style="FONT-SIZE: 12px">匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性，则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身，请使用 \$。</td></tr><tr><td style="FONT-SIZE: 12px">( )</td><td style="FONT-SIZE: 12px">标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符，请使用 \( 和 \)。</td></tr><tr><td style="FONT-SIZE: 12px">*</td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。要匹配 * 字符，请使用 \*。</td></tr><tr><td style="FONT-SIZE: 12px">+</td><td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。要匹配 + 字符，请使用 \+。</td></tr><tr><td style="FONT-SIZE: 12px">.</td><td style="FONT-SIZE: 12px">匹配除换行符 \n之外的任何单字符。要匹配 .，请使用 \。</td></tr><tr><td style="FONT-SIZE: 12px">[ </td><td style="FONT-SIZE: 12px">标记一个中括号表达式的开始。要匹配 [，请使用 \[。</td></tr><tr><td style="FONT-SIZE: 12px">?</td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次，或指明一个非贪婪限定符。要匹配 ? 字符，请使用 \?。</td></tr><tr><td style="FONT-SIZE: 12px">\</td><td style="FONT-SIZE: 12px">将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如， 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\"，而 '\(' 则匹配 "("。</td></tr><tr><td style="FONT-SIZE: 12px">^</td><td style="FONT-SIZE: 12px">匹配输入字符串的开始位置，除非在方括号表达式中使用，此时它表示不接受该字符集合。要匹配 ^ 字符本身，请使用 \^。</td></tr><tr><td style="FONT-SIZE: 12px">{</td><td style="FONT-SIZE: 12px">标记限定符表达式的开始。要匹配 {，请使用 \{。</td></tr><tr><td style="FONT-SIZE: 12px">|</td><td style="FONT-SIZE: 12px">指明两项之间的一个选择。要匹配 |，请使用 \|。</td></tr></tbody></table><blockquote><ul><li><strong style="FONT-WEIGHT: 400; BACKGROUND-COLOR: #ffff00">　　构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。</strong></li></ul></blockquote><p>　</p><h3><a name="3.4_限定符">3.4 限定符</a></h3><p>　　限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。<br />*、+和?限定符都是贪婪的，因为它们会尽可能多的匹配文字，只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。<br />　　正则表达式的限定符有：<br />　 </p><table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">字符 </th><th style="FONT-SIZE: 12px" align="left">描述</th></tr><tr><td style="FONT-SIZE: 12px">* </td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。</td></tr><tr><td style="FONT-SIZE: 12px">+ </td><td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。</td></tr><tr><td style="FONT-SIZE: 12px">? </td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。</td></tr><tr><td style="FONT-SIZE: 12px">{n} </td><td style="FONT-SIZE: 12px">n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。</td></tr><tr><td style="FONT-SIZE: 12px">{n,} </td><td style="FONT-SIZE: 12px">n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</td></tr><tr><td style="FONT-SIZE: 12px">{n,m} </td><td style="FONT-SIZE: 12px">m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。</td></tr></tbody></table><h3><a name="3.5_定位符">3.5 定位符</a></h3><p>　　用来描述字符串或单词的边界，^和$分别指字符串的开始与结束，\b描述单词的前或后边界，\B表示非单词边界。<font color="#ff0000">不能对定位符使用限定符。</font></p><h3><a name="3.6_选择">3.6 选择</a></h3><p>　　用圆括号将所有选择项括起来，相邻的选择项之间用|分隔。但用圆括号会有一个副作用，是相关的匹配会被缓存，此时可用?:放在第一个选项前来消除这种副作用。<br />　　其中?:是非捕获元之一，还有两个非捕获元是?=和?!，这两个还有更多的含义，前者为正向预查，在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串，后者为负向预查，在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。 </p><h3><a name="3.7_后向引用">3.7 后向引用</a></h3><p>　　对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中，所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从 1 开始，连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 '\n' 访问，其中 n 为一个标识特定缓冲区的一位或两位十进制数。<br />　　可以使用非捕获元字符 '?:', '?=', or '?!' 来忽略对相关匹配的保存。 </p><h2><a name="4._各种操作符的运算优先级">4. 各种操作符的运算优先级</a></h2><p>　　相同优先级的从左到右进行运算，不同优先级的运算先高后低。各种操作符的优先级从高到低如下：<br />　 </p><table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">操作符 </th><th style="FONT-SIZE: 12px" align="left">描述</th></tr><tr><td style="FONT-SIZE: 12px">\ </td><td style="FONT-SIZE: 12px">转义符</td></tr><tr><td style="FONT-SIZE: 12px">(), (?:), (?=), [] </td><td style="FONT-SIZE: 12px">圆括号和方括号</td></tr><tr><td style="FONT-SIZE: 12px">*, +, ?, {n}, {n,}, {n,m} </td><td style="FONT-SIZE: 12px">限定符</td></tr><tr><td style="FONT-SIZE: 12px">^, $, \anymetacharacter </td><td style="FONT-SIZE: 12px">位置和顺序</td></tr><tr><td style="FONT-SIZE: 12px">| </td><td style="FONT-SIZE: 12px">“或”操作</td></tr></tbody></table><h2><a name="5._全部符号解释">5. 全部符号解释</a></h2><p></p><table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">字符 </th><th style="FONT-SIZE: 12px" align="left">描述</th></tr><tr><td style="FONT-SIZE: 12px">\ </td><td style="FONT-SIZE: 12px">将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如，'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。</td></tr><tr><td style="FONT-SIZE: 12px">^ </td><td style="FONT-SIZE: 12px">匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性，^ 也匹配 '\n' 或 '\r' 之后的位置。</td></tr><tr><td style="FONT-SIZE: 12px">$ </td><td style="FONT-SIZE: 12px">匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性，$ 也匹配 '\n' 或 '\r' 之前的位置。</td></tr><tr><td style="FONT-SIZE: 12px">* </td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。</td></tr><tr><td style="FONT-SIZE: 12px">+ </td><td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。</td></tr><tr><td style="FONT-SIZE: 12px">? </td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。</td></tr><tr><td style="FONT-SIZE: 12px">{n} </td><td style="FONT-SIZE: 12px">n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。</td></tr><tr><td style="FONT-SIZE: 12px">{n,} </td><td style="FONT-SIZE: 12px">n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</td></tr><tr><td style="FONT-SIZE: 12px">{n,m} </td><td style="FONT-SIZE: 12px">m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。</td></tr><tr><td style="FONT-SIZE: 12px">? </td><td style="FONT-SIZE: 12px">当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 "oooo"，'o+?' 将匹配单个 "o"，而 'o+' 将匹配所有 'o'。</td></tr><tr><td style="FONT-SIZE: 12px">. </td><td style="FONT-SIZE: 12px">匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符，请使用象 '[.\n]' 的模式。</td></tr><tr><td style="FONT-SIZE: 12px">(pattern) </td><td style="FONT-SIZE: 12px">匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 SubMatches 集合，在JScript 中则使用 $0…$9 属性。要匹配圆括号字符，请使用 '\(' 或 '\)'。</td></tr><tr><td style="FONT-SIZE: 12px">(?:pattern) </td><td style="FONT-SIZE: 12px">匹配 pattern 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如， 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。</td></tr><tr><td style="FONT-SIZE: 12px">(?=pattern) </td><td style="FONT-SIZE: 12px">正向预查，在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如，'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ，但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。</td></tr><tr><td style="FONT-SIZE: 12px">(?!pattern) </td><td style="FONT-SIZE: 12px">负向预查，在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows"，但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始</td></tr><tr><td style="FONT-SIZE: 12px">x|y </td><td style="FONT-SIZE: 12px">匹配 x 或 y。例如，'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。</td></tr><tr><td style="FONT-SIZE: 12px">[xyz] </td><td style="FONT-SIZE: 12px">字符集合。匹配所包含的任意一个字符。例如， '[abc]' 可以匹配 "plain" 中的 'a'。</td></tr><tr><td style="FONT-SIZE: 12px">[^xyz] </td><td style="FONT-SIZE: 12px">负值字符集合。匹配未包含的任意字符。例如， '[^abc]' 可以匹配 "plain" 中的'p'。</td></tr><tr><td style="FONT-SIZE: 12px">[a-z] </td><td style="FONT-SIZE: 12px">字符范围。匹配指定范围内的任意字符。例如，'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。</td></tr><tr><td style="FONT-SIZE: 12px">[^a-z] </td><td style="FONT-SIZE: 12px">负值字符范围。匹配任何不在指定范围内的任意字符。例如，'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。</td></tr><tr><td style="FONT-SIZE: 12px">\b </td><td style="FONT-SIZE: 12px">匹配一个单词边界，也就是指单词和空格间的位置。例如， 'er\b' 可以匹配"never" 中的 'er'，但不能匹配 "verb" 中的 'er'。</td></tr><tr><td style="FONT-SIZE: 12px">\B </td><td style="FONT-SIZE: 12px">匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er'，但不能匹配 "never" 中的 'er'。</td></tr><tr><td style="FONT-SIZE: 12px">\cx </td><td style="FONT-SIZE: 12px">匹配由 x 指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。</td></tr><tr><td style="FONT-SIZE: 12px">\d </td><td style="FONT-SIZE: 12px">匹配一个数字字符。等价于 [0-9]。</td></tr><tr><td style="FONT-SIZE: 12px">\D </td><td style="FONT-SIZE: 12px">匹配一个非数字字符。等价于 [^0-9]。</td></tr><tr><td style="FONT-SIZE: 12px">\f </td><td style="FONT-SIZE: 12px">匹配一个换页符。等价于 \x0c 和 \cL。</td></tr><tr><td style="FONT-SIZE: 12px">\n </td><td style="FONT-SIZE: 12px">匹配一个换行符。等价于 \x0a 和 \cJ。</td></tr><tr><td style="FONT-SIZE: 12px">\r </td><td style="FONT-SIZE: 12px">匹配一个回车符。等价于 \x0d 和 \cM。</td></tr><tr><td style="FONT-SIZE: 12px">\s </td><td style="FONT-SIZE: 12px">匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td></tr><tr><td style="FONT-SIZE: 12px">\S </td><td style="FONT-SIZE: 12px">匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td></tr><tr><td style="FONT-SIZE: 12px">\t </td><td style="FONT-SIZE: 12px">匹配一个制表符。等价于 \x09 和 \cI。</td></tr><tr><td style="FONT-SIZE: 12px">\v </td><td style="FONT-SIZE: 12px">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td></tr><tr><td style="FONT-SIZE: 12px">\w </td><td style="FONT-SIZE: 12px">匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。</td></tr><tr><td style="FONT-SIZE: 12px">\W </td><td style="FONT-SIZE: 12px">匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。</td></tr><tr><td style="FONT-SIZE: 12px">\xn </td><td style="FONT-SIZE: 12px">匹配 n，其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如，'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' &amp; "1"。正则表达式中可以使用 ASCII 编码。.</td></tr><tr><td style="FONT-SIZE: 12px">\num </td><td style="FONT-SIZE: 12px">匹配 num，其中 num 是一个正整数。对所获取的匹配的引用。例如，'(.)\1' 匹配两个连续的相同字符。</td></tr><tr><td style="FONT-SIZE: 12px">\n </td><td style="FONT-SIZE: 12px">标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式，则 n 为向后引用。否则，如果 n 为八进制数字 (0-7)，则 n 为一个八进制转义值。</td></tr><tr><td style="FONT-SIZE: 12px">\nm </td><td style="FONT-SIZE: 12px">标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式，则 nm 为向后引用。如果 \nm 之前至少有 n 个获取，则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足，若 n 和 m 均为八进制数字 (0-7)，则 \nm 将匹配八进制转义值 nm。</td></tr><tr><td style="FONT-SIZE: 12px">\nml </td><td style="FONT-SIZE: 12px">如果 n 为八进制数字 (0-3)，且 m 和 l 均为八进制数字 (0-7)，则匹配八进制转义值 nml。</td></tr><tr><td style="FONT-SIZE: 12px">\un </td><td style="FONT-SIZE: 12px">匹配 n，其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (?)。</td></tr></tbody></table><p>　</p><h2><a name="6._部分例子">6. 部分例子</a></h2><p></p><table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">正则表达式</th><th style="FONT-SIZE: 12px" align="left">说明</th></tr><tr><td style="FONT-SIZE: 12px">/\b([a-z]+) \1\b/gi</td><td style="FONT-SIZE: 12px">一个单词连续出现的位置</td></tr><tr><td style="FONT-SIZE: 12px">/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ </td><td style="FONT-SIZE: 12px">将一个URL解析为协议、域、端口及相对路径</td></tr><tr><td style="FONT-SIZE: 12px">/^(?:Chapter|Section) [1-9][0-9]{0,1}$/</td><td style="FONT-SIZE: 12px">定位章节的位置</td></tr><tr><td style="FONT-SIZE: 12px">/[-a-z]/</td><td style="FONT-SIZE: 12px">A至z共26个字母再加一个-号。</td></tr><tr><td style="FONT-SIZE: 12px">/ter\b/</td><td style="FONT-SIZE: 12px">可匹配chapter，而不能terminal</td></tr><tr><td style="FONT-SIZE: 12px">/\Bapt/</td><td style="FONT-SIZE: 12px">可匹配chapter，而不能aptitude</td></tr><tr><td style="FONT-SIZE: 12px">/Windows(?=95 |98 |NT )/</td><td style="FONT-SIZE: 12px">可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后，从Windows后面开始进行下一次的检索匹配。</td></tr></tbody></table><p>　</p><h2><a name="7._正则表达式匹配规则">7. 正则表达式匹配规则</a></h2><p><strong><a name="7.1_基本模式匹配">7.1 基本模式匹配</a></strong><br /><br />　　一切从最基本的开始。模式，是正规表达式最基本的元素，它们是一组描述字符串特征的字符。模式可以很简单，由普通的字符串组成，也可以非常复杂，往往用特殊的字符表示一个范围内的字符、重复出现，或表示上下文。例如：</p><blockquote><p>^once </p></blockquote><p>　　这个模式包含一个特殊的字符^，表示该模式只匹配那些以once开头的字符串。例如该模式与字符串"once upon a time"匹配，与"There once was a man from NewYork"不匹配。正如如^符号表示开头一样，$符号用来匹配那些以给定模式结尾的字符串。</p><blockquote><p>bucket$ </p></blockquote><p>　　这个模式与"Who kept all of this cash in a bucket"匹配，与"buckets"不匹配。字符^和$同时使用时，表示精确匹配（字符串与模式一样）。例如：</p><blockquote><p>^bucket$ </p></blockquote><p>　　只匹配字符串"bucket"。如果一个模式不包括^和$，那么它与任何包含该模式的字符串匹配。例如：模式</p><blockquote><p>once </p></blockquote><p>与字符串</p><blockquote><p>There once was a man from NewYork<br />Who kept all of his cash in a bucket.</p></blockquote><p>是匹配的。<br /><br />　　在该模式中的字母(o-n-c-e)是字面的字符，也就是说，他们表示该字母本身，数字也是一样的。其他一些稍微复杂的字符，如标点符号和白字符（空格、制表符等），要用到转义序列。所有的转义序列都用反斜杠(\)打头。制表符的转义序列是：\t。所以如果我们要检测一个字符串是否以制表符开头，可以用这个模式：</p><blockquote><p>^\t </p></blockquote><p>类似的，用\n表示“新行”，\r表示回车。其他的特殊符号，可以用在前面加上反斜杠，如反斜杠本身用\\表示，句号.用\.表示，以此类推。<br /><br /><strong><a name="7.2_字符簇">7.2 字符簇</a></strong><br /><br />在INTERNET的程序中，正规表达式通常用来验证用户的输入。当用户提交一个FORM以后，要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效，用普通的基于字面的字符是不够的。<br /><br />所以要用一种更自由的描述我们要的模式的办法，它就是字符簇。要建立一个表示所有元音字符的字符簇，就把所有的元音字符放在一个方括号里：</p><blockquote><p>[AaEeIiOoUu] </p></blockquote><p>这个模式与任何元音字符匹配，但只能表示一个字符。用连字号可以表示一个字符的范围，如：</p><blockquote><p>[a-z] //匹配所有的小写字母 <br />[A-Z] //匹配所有的大写字母 <br />[a-zA-Z] //匹配所有的字母 <br />[0-9] //匹配所有的数字 <br />[0-9\.\-] //匹配所有的数字，句号和减号 <br />[ \f\r\t\n] //匹配所有的白字符 </p></blockquote><p>同样的，这些也只表示一个字符，这是一个非常重要的。如果要匹配一个由一个小写字母和一位数字组成的字符串，比如"z2"、"t6"或"g7"，但不是"ab2"、"r2d3" 或"b52"的话，用这个模式：</p><blockquote><p>^[a-z][0-9]$ </p></blockquote><p>尽管[a-z]代表26个字母的范围，但在这里它只能与第一个字符是小写字母的字符串匹配。<br /><br />前面曾经提到^表示字符串的开头，但它还有另外一个含义。当在一组方括号里使用^是，它表示“非”或“排除”的意思，常常用来剔除某个字符。还用前面的例子，我们要求第一个字符不能是数字：</p><blockquote><p>^[^0-9][0-9]$ </p></blockquote><p>这个模式与"&amp;5"、"g7"及"-2"是匹配的，但与"12"、"66"是不匹配的。下面是几个排除特定字符的例子：</p><blockquote><p>[^a-z] //除了小写字母以外的所有字符 <br />[^\\\/\^] //除了(\)(/)(^)之外的所有字符 <br />[^\"\'] //除了双引号(")和单引号(')之外的所有字符 </p></blockquote><p>特殊字符"." (点，句号)在正规表达式中用来表示除了“新行”之外的所有字符。所以模式"^.5$"与任何两个字符的、以数字5结尾和以其他非“新行”字符开头的字符串匹配。模式"."可以匹配任何字符串，除了空串和只包括一个“新行”的字符串。<br /><br />PHP的正规表达式有一些内置的通用字符簇，列表如下：</p><blockquote><p>字符簇 含义 <br />[[:alpha:]] 任何字母 <br />[[:digit:]] 任何数字 <br />[[:alnum:]] 任何字母和数字 <br />[[:space:]] 任何白字符 <br />[[:upper:]] 任何大写字母 <br />[[:lower:]] 任何小写字母 <br />[[:punct:]] 任何标点符号 <br />[[:xdigit:]] 任何16进制的数字，相当于[0-9a-fA-F] </p></blockquote><p><strong><a name="7.3_确定重复出现">7.3 确定重复出现</a></strong><br /><br />到现在为止，你已经知道如何去匹配一个字母或数字，但更多的情况下，可能要匹配一个单词或一组数字。一个单词有若干个字母组成，一组数字有若干个单数组成。跟在字符或字符簇后面的花括号({})用来确定前面的内容的重复出现的次数。 </p><blockquote><p>字符簇 含义 <br />^[a-zA-Z_]$ 所有的字母和下划线 <br />^[[:alpha:]]{3}$ 所有的3个字母的单词 <br />^a$ 字母a <br />^a{4}$ aaaa <br />^a{2,4}$ aa,aaa或aaaa <br />^a{1,3}$ a,aa或aaa <br />^a{2,}$ 包含多于两个a的字符串 <br />^a{2,} 如：aardvark和aaab，但apple不行 <br />a{2,} 如：baad和aaa，但Nantucket不行 <br />\t{2} 两个制表符 <br />.{2} 所有的两个字符 </p></blockquote><p>这些例子描述了花括号的三种不同的用法。一个数字，{x}的意思是“前面的字符或字符簇只出现x次”；一个数字加逗号，{x,}的意思是“前面的内容出现x或更多的次数”；两个用逗号分隔的数字，{x,y}表示“前面的内容至少出现x次，但不超过y次”。我们可以把模式扩展到更多的单词或数字：</p><blockquote><p>^[a-zA-Z0-9_]{1,}$ //所有包含一个以上的字母、数字或下划线的字符串 <br />^[0-9]{1,}$ //所有的正数 <br />^\-{0,1}[0-9]{1,}$ //所有的整数 <br />^\-{0,1}[0-9]{0,}\.{0,1}[0-9]{0,}$ //所有的小数 </p></blockquote><p>最后一个例子不太好理解，是吗？这么看吧：与所有以一个可选的负号(\-{0,1})开头(^)、跟着0个或更多的数字([0-9]{0,})、和一个可选的小数点(\.{0,1})再跟上0个或多个数字([0-9]{0,})，并且没有其他任何东西($)。下面你将知道能够使用的更为简单的方法。<br /><br />特殊字符"?"与{0,1}是相等的，它们都代表着：“0个或1个前面的内容”或“前面的内容是可选的”。所以刚才的例子可以简化为：</p><blockquote><p>^\-?[0-9]{0,}\.?[0-9]{0,}$ </p></blockquote><p>特殊字符"*"与{0,}是相等的，它们都代表着“0个或多个前面的内容”。最后，字符"+"与 {1,}是相等的，表示“1个或多个前面的内容”，所以上面的4个例子可以写成：</p><blockquote><p>^[a-zA-Z0-9_]+$ //所有包含一个以上的字母、数字或下划线的字符串 <br />^[0-9]+$ //所有的正数 <br />^\-?[0-9]+$ //所有的整数 <br />^\-?[0-9]*\.?[0-9]*$ //所有的小数 </p></blockquote><p>当然这并不能从技术上降低正规表达式的复杂性，但可以使它们更容易阅读。</p><p>参考文献：<br /><a href="http://www.soulogic.com/code/doc/RegularExpressions/"><font color="#009933">JScript 和 VBScript 正则表达式</font></a></p><p>微软MSDN上的例子(英文)：</p><p></p><table class="clsContainer" style="TABLE-LAYOUT: fixed" cellspacing="0" cellpadding="15" width="100%" border="0" float="left"><tbody><tr><td valign="top"><div id="nstext0" valign="bottom"><dl><dt><a href="http://msdn.microsoft.com/library/en-us/cpguide/html/cpconexamplescanningforhrefs.asp"><font color="#009933" size="1">Scanning for HREFS</font></a><font size="1"></font></dt><dd><font size="1">Provides an example that searches an input string and prints out all the href="..." values and their locations in the string. </font></dd><dt><a href="http://msdn.microsoft.com/library/en-us/cpguide/html/cpconexamplechangingdateformats.asp"><font color="#009933" size="1">Changing Date Formats</font></a><font size="1"></font></dt><dd><font size="1">Provides an example that replaces dates of the form mm/dd/yy with dates of the form dd-mm-yy. </font></dd><dt><a href="http://msdn.microsoft.com/library/en-us/cpguide/html/cpconexampleextractingurlinformation.asp"><font color="#009933" size="1">Extracting URL Information</font></a><font size="1"></font></dt><dd><font size="1">Provides an example that extracts a protocol and port number from a string containing a URL. For example, "http://www.contoso.com:8080/letters/readme.html" returns "http:8080". </font></dd><dt><a href="http://msdn.microsoft.com/library/en-us/cpguide/html/cpconexamplecleaninginputstring.asp"><font color="#009933" size="1">Cleaning an Input String</font></a><font size="1"></font></dt><dd><font size="1">provides an example that strips invalid non-alphanumeric characters from a string. </font></dd><dt><a href="http://msdn.microsoft.com/library/en-us/cpguide/html/cpconexampleconfirmingvalidemailformat.asp"><font color="#009933" size="1">Confirming Valid E-Mail Format</font></a><font size="1"></font></dt><dd><font size="1">Provides an example that you can use to verify that a string is in valid e-mail format. </font></dd></dl></div></td></tr></tbody></table><p><font size="2">最后更新：<!--webbot bot="Timestamp" S-Type="REGENERATED" S-Format="%Y年%m月%d日 %H:%M" startspan -->2005年01月17日 19:54<!--webbot bot="Timestamp" endspan i-checksum="8120" --><br />版权声明：使用<a href="http://www.creativecommons.cn/licenses/by-nc/1.0/"><font color="#009933">创作公用版权协议</font></a></font></p><p><font size="2">引用地址：&lt;a href="http://oo8h.com/docs/regular_expression.htm"&gt;正则表达式(regular expression)&lt;/a&gt;</font></p><p><br /><br /></p><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=630917</p><img src ="http://www.blogjava.net/iKingQu/aggbug/36752.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-22 03:12 <a href="http://www.blogjava.net/iKingQu/articles/36752.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]HTTP代理如何正确处理Cookie </title><link>http://www.blogjava.net/iKingQu/articles/36531.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 20 Mar 2006 16:59:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36531.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36531.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36531.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36531.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36531.html</trackback:ping><description><![CDATA[
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/j-cookie/#author">
						<font color="#996699">黄湘平 </font>
				</a>, 高级软件工程师，IBM CSDL<br /></p>
		<p>2005 年 11 月 10 日</p>
		<p>读者定位为具有Java和Web开发经验的开发和设计人员。</p>
		<p>读者可以学习到关于Cookie的工作原理和Cookie协议的细节，以及在一个HTTP应用代理的场景下Cookie的管理和处理思想，并可以直接使用文中的代码和思路，提高工作效率。</p>
		<p>随着越来越多的系统移植到了Web上，HTTP协议具有了比以前更广泛的应用。不同的系统对WEB实现提出了不同的要求，基于HTTP协议的网络应用正趋于复杂化和多元化。很多应用需要把用户请求的页面进行处理后再返回给用户，比如页面关键字过滤，页面内容缓存、内容搜索、页面翻译等等。这些应用在实际效果上类似于一个HTTP应用代理：它们首先接受用户的请求，根据用户请求的URL去真正的目标服务器取回目标页面，再根据不同应用的要求做出相应处理后返回给用户。这样用户直接面对的就是这个HTTP应用代理，而通过它与其他页面进行交互。Cookie或Session技术的应用，解决了HTTP协议的一个问题 -- 无法保持客户状态，因此它现在被广泛应用于各种Web站点中。上面提到的那些应用如果不能处理好Cookie和Session的传递、更新和废除等问题，就会极大的限制它们所能处理站点的范围，因此如何在HTTP应用代理中正确处理Cookie，成为一个必须解决的问题。本文结合在页面翻译（Machine Translation System）项目中对于Cookie的处理方法，探讨一下这方面的解决方案。</p>
		<p>
				<a name="IDADCYZB">
						<span class="atitle">
								<font size="4">MTS项目简介及讨论前提</font>
						</span>
				</a>
		</p>
		<p>Machine Translation System（以下简称MTS）是一个在线实时页面翻译系统，为用户在线提供把英文页面翻译成其他9种语言的服务。用户通过向MTS系统提交一个类似下面的URL使用此服务，其中参数url指明了用户所需要翻译的目标地址，参数language指明了所需翻译成的目标语言，www.mts.com是假想中提供MTS服务的站点。</p>
		<p>
				<a href="http://www.mts.com/translate?url=http://www.ibm.com/&amp;language=French">
						<font color="#5c81a7">HTTP://www.mts.com/translate?url=http://www.ibm.com/&amp;language=French</font>
				</a>
		</p>
		<p>一个完整的MTS系统处理过程可以分解成以下几个步骤：</p>
		<ul>
				<li>用户向MTS提交合适的URL。 
</li>
				<li>MTS在接到用户的请求后，解析出用户需要翻译的目标地址和目标语言，根据用户请求的目标地址，把请求转发到目标服务器。 
</li>
				<li>MTS接受来自目标服务器的应答，包括页面信息和HTTP头信息。 
</li>
				<li>MTS在确定得到正确的目标页面后，把页面内容送入WebSphere Translation Server进行翻译。 
</li>
				<li>把翻译后的页面连同修改后的HTTP头信息提交给用户。 </li>
		</ul>
		<p>当然，这其中涉及到很多的应用处理。比如与各种HTTP/HTTPS站点建立联结、根据HTTP头信息进行页面跳转和错误处理、为始终保持用户在翻译模式下而对目标的HTML页面进行分析和修改，根据系统设置对某些DNT（Do Not Translate）的页面进行过滤和跳转，当然还有对Cookie的处理等等。其他问题跟这篇文章关联不大，我们重点讨论在这种情况下的Cookie处理。Cookie跟随目标服务器的HTTP头信息被MTS接收到，经过MTS整理之后发给客户端浏览器。MTS在接到下一次用户对同一个站点的翻译请求时，再把从客户端得到的Cookie发送给目标服务器。</p>
		<p>在以上的场景中，MTS充当的作用类似于一种HTTP应用代理服务器，它代替用户取得目标页面，并在作出相应处理后再提交给用户。当然，这种代理服务器不需要用户修改浏览器的代理服务器参数或者网络配置，而只是简单的在浏览器的地址栏中输入一个MTS能够识别的URL即可。此篇文章也是在这样一个应用场景的基础上，展开对HTTP应用代理服务器如何处理Cookie的讨论。</p>
		<p>
				<a name="IDAEDYZB">
						<span class="atitle">
								<font size="4">问题的产生</font>
						</span>
				</a>
		</p>
		<p>在MTS系统中，目标服务器的Cookie在两个地方会产生问题。当MTS接收目标服务器应答的时候，Cookie随着HTTP头信息被MTS接收到的。这时候目标服务器认为MTS就是最终客户，因此它赋予了Cookie与目标服务器相符的属性。而如果MTS把这些Cookie原封不动的保存在HTTP头信息中，传给真正的最终用户的话，用户的浏览器会因为这些Cookie不合法而忽略它们。同理，当Cookie从浏览器端传回目标服务器的时候，也会遇到相同的问题。因此有必要对Cookie进行一些处理，以保证用户的浏览器能真正识别和利用这些Cookie。</p>
		<p>但是为何用户浏览器无法识别从目标服务器传过来的原始Cookie呢？这是因为出于安全性的考虑，Cookie规范制定的时候对Cookie的产生和接受设置了一些严格的规范，不符合这些规范的Cookie，浏览器和服务器都将予以忽略。下面我们从Cookie规范入手进行介绍。</p>
		<p>
				<a name="IDALDYZB">
						<span class="atitle">
								<font size="4">Cookie的规范介绍</font>
						</span>
				</a>
		</p>
		<p>目前有以下几种Cookie规范：</p>
		<ul>
				<li>Netscape cookie草案：是最早的cookie规范，基于rfc2109。尽管这个规范与rc2109有较大的差别，但是很多服务器都与之兼容。 
</li>
				<li>rfc2109， 是w3c发布的第一个官方cookie规范。理论上讲，所有的服务器在处理cookie(版本1)时，都要遵循此规范。遗憾的是，这个规范太严格了，以致很多服务器不正确的实施了该规范或仍在使用Netscape规范。 
</li>
				<li>rfc2965规范定义了cookie版本2，并说明了cookie版本1的不足。 </li>
		</ul>
		<p>rfc2965规范的使用，目前并不多。rfc2109规范相应要严格得多，在实际应用上，并不是所有的浏览器和Web服务器都严格遵守。因此相比较而言，Netscape cookie草案倒是一个比较简洁和被广泛支持的Cookie规范，因此我们在这里以Netscape cookie草案为基础进行讨论，对于其他两种规范，我们的讨论和代码具有相同的意义。关于Netscape cookie草案的细节，大家可以参照Netscape官方站点，这里我们列举一些和我们讨论有关的内容。</p>
		<p>根据Netscape cookie草案的描述，Cookie 是Web 服务器向用户的浏览器发送的一段ASCII码文本。一旦收到Cookie，浏览器会把Cookie的信息片断以"名/值"对(name-value pairs)的形式储存保存在本地。这以后，每当向同一个Web 服务器请求一个新的文档时，Web 浏览器都会发送之站点以前存储在本地的Cookie。创建Cookie的最初目的是想让Web服务器能够通过多个HTTP请求追踪客户。有些复杂的网络应用需要在不同的网页之间保持一致，它们需要这种会话状态的保持能力。</p>
		<p>浏览器与Web服务器通过HTTP协议进行通讯，而Cookie就是保存在HTTP协议的请求或者应答头部（在HTTP协议中，数据包括两部分，一部分是头部，由一些名值对构成，用来描述要被传输数据的一些信息。一部分是主体(body)，是真正的数据（如HTML页面等））进行传送的。</p>
		<p>在HTML文档被发送之前，Web服务器通过传送HTTP 包头中的Set-Cookie 消息把一个cookie 发送到用户的浏览器中。下面是一个遵循Netscape cookie草案的完整的Set-Cookie 头：</p>
		<p>
				<br />
				<a name="IDAZDYZB">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">Set-Cookie：customer=huangxp; path=/foo; domain=.ibm.com; 
expires= Wednesday, 19-OCT-05 23:12:40 GMT; [secure]
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>Set-Cookie的每个属性解释如下：</p>
		<ul>
				<li>Customer=huangxp 一个"名称＝值"对，把名称customer设置为值"huangxp"，这个属性在Cookie中必须有。 
</li>
				<li>path=/foo 控制哪些访问能够触发cookie 的发送。如果没有指定path，cookie 会在所有对此站点的HTTP 传送时发送。如果path=/directory，只有访问/directory 下面的网页时，cookie才被发送。在这个例子中，用户在访问目录/foo下的内容时，浏览器将发送此cookie。如果指定了path，但是path与当前访问的url不符，则此cookie将被忽略。 
</li>
				<li>domain=.ibm.com 指定cookie被发送到哪台计算机上。正常情况下，cookie只被送回最初向用户发送cookie 的计算机。在这个例子中，cookie 会被发送到任何在.ibm.com域中的主机。如果domain 被设为空，domain 就被设置为和提供cookie 的Web 服务器相同。如果domain不为空，并且它的值又和提供cookie的Web服务器域名不符，这个Cookie将被忽略。 
</li>
				<li>expires= Wednesday, 19-OCT-05 23:12:40 GMT 指定cookie 失效的时间。如果没有指定失效时间，这个cookie 就不会被写入计算机的硬盘上，并且只持续到这次会话结束。 
</li>
				<li>secure 如果secure 这个词被作为Set-Cookie 头的一部分，那么cookie 只能通过安全通道传输（目前即SSL通道）。否则，浏览器将忽略此Cookie。 </li>
		</ul>
		<p>一旦浏览器接收了cookie，这个cookie和对远端Web服务器的连续请求将一起被浏览器发送。例如 前一个cookie 被存入浏览器并且浏览器试图请求URL <a href="http://www.ibm.com/foo/index.html"><font color="#5c81a7">http://www.ibm.com/foo/index.html</font></a> 时，下面的HTTP 包头就被发送到远端的Web服务器。</p>
		<p>GET /foo/index.html HTTP/1.0<br />Cookie：customer=huangxp </p>
		<p>
				<a name="IDAREYZB">
						<span class="atitle">
								<font size="4">一次典型的网络浏览过程</font>
						</span>
				</a>
		</p>
		<p>在了解了Cookie协议的一些基本内容之后，让我们看看一次典型的网络浏览过程中浏览器如何识别和处理Cookie：</p>
		<ul>
				<li>浏览器对于Web服务器应答包头中Cookie的操作步骤：<br />1. 从Web服务器的应答包头中提取所有的cookie。<br />2. 解析这些cookie的组成部分（名称，值，路径等等）。<br />3. 判定主机是否允许设置这些cookie。允许的话，则把这些Cookie存储在本地。 
</li>
				<li>浏览器对Web服务器请求包头中所有的Cookie进行筛选的步骤：<br />1. 根据请求的URL和本地存储cookie的属性，判断那些Cookie能被发送给Web服务器。<br />2. 对于多个cookie，判定发送的顺序。<br />3. 把需要发送的Cookie加入到请求HTTP包头中一起发送。 </li>
		</ul>
		<p>
				<a name="IDAIFYZB">
						<span class="atitle">
								<font size="4">由MTS代理的网络浏览过程</font>
						</span>
				</a>
		</p>
		<p>以上我们了解了在一个典型的浏览器与Web服务器交互的时候，Cookie的传递过程。下面我们将看到，如果在MTS代理网络浏览的过程中，不对Cookie进行修改，上面的Cookie传递过程将无法实现。</p>
		<p>1. 假设用户希望把http://www.ibm.com/foo/index.html页面翻译成法文，应该使用如下的url对MTS发出请求</p>
		<p>： </p>
		<p>
				<a href="http://www.mts.com/translate?url=http://www.ibm.com/foo/index.html&amp;language=French">
						<font color="#5c81a7">HTTP://www.mts.com/translate?url=http://www.ibm.com/foo/index.html&amp;language=French</font>
				</a>
		</p>
		<p>2. MTS接收用户的请求，连接远程目标服务器<a href="http://www.ibm.com/foo/index.html"><font color="#5c81a7">http://www.ibm.com/foo/index.html</font></a>。目标服务器做出应答，返回HTTP头和HTML页面内容。其中，典型的HTTP头内容如下：</p>
		<p>
				<br />
				<a name="IDA0FYZB">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">HTTP/1.1 200 OK
Date: Mon, 24 Oct 2005 06:54:41 GMT
Server: IBM_HTTP_Server
Cache-Control: no-cache
Content-Length: 19885
Connection: close
Set-Cookie：customer=huangxp; path=/foo; domain=.ibm.com; 
expires= Wednesday, 19-OCT-05 23:12:40 GMT
Content-Type: text/html
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>3. MTS不对Set-Cookie后的内容作任何处理，直接把它加到用户浏览器的应答头上发送给浏览器。</p>
		<p>4. 浏览器将从Set-Cookie中解析出domain和path的值，分别是.ibm.com和/foo，并与请求的url：<a href="http://www.mts.com/translate?url=http://www.ibm.com/foo/index.html&amp;language=French"><font color="#5c81a7">HTTP://www.mts.com/translate?url=http://www.ibm.com/foo/index.html&amp;language=French</font></a>进行比较。请求url的domain是www.mts.com，path是/，与Set-Cookie中的属性不符，所以浏览器将忽略此Cookie。</p>
		<p>另外，在浏览器发送Cookie的时候也会遇到同样的问题，同样如上例，如果浏览器里本来已经存储了http://www.ibm.com/foo/的Cookie，但由于用户要通过MTS访问此站点，浏览器经不会把已经存储的Cookie上转到MTS中，MTS也就无法把之传递到http://ibm.com/foo/上。</p>
		<p>基于上面Cookie规范的介绍和例证，我们能看出，浏览器在接受某一个站点的Cookie的时候，需要检查Cookie的参数domain、path、secure，看是否与当前的站点和URL相符，如果不符的话，就会忽略。另一方面。浏览器在上传Cookie的时候，也会根据当前所访问站点的属性，上传相关的Cookie，而其他的Cookie则不予上传。</p>
		<p>至此，我们讨论了需要修改Cookie的根本原因在于Cookie规范的限制。下面我们讨论两种解决问题的思路。</p>
		<p>
				<a name="IDALGYZB">
						<span class="atitle">
								<font size="4">解决问题的两种思路</font>
						</span>
				</a>
		</p>
		<p>Cookie的存在是要解决HTTP协议本身先天的缺陷-无状态性，它为用户保存了一些需要的状态信息。因此我们解决此问题的最本质的出发点，也就是找到一种途径能为用户保存Cookie所提供用户状态信息，实际上就是Name/Value对。</p>
		<p>
				<a name="IDARGYZB">
						<span class="smalltitle">
								<strong>
										<font size="3">思路一</font>
								</strong>
						</span>
				</a>
		</p>
		<p>第一种思路就是修改目标服务器取得的Cookie，使之符合MTS站点的属性，然后作为MTS站点的Cookie存储到用户的浏览器中去。当然，这种修改必须保留原始Cookie的所有属性值，当以后访问同一个目标服务器的时候，MTS能根据保存的属性值还原出原始Cookie，然后进行提交。</p>
		<p>具体到属性值的保存位置，没有太多选择的余地，实际上，domain，path，secure，expires这几个属性都无法利用，只有利用name=value这一属性对。我们的做法是创造一个新的Cookie，把原始Cookie的domain，path的值与name值进行编码，用分隔符附加在Name值的后面，符值给新的Cookie。这样做也同时避免了不同目标服务器如果出现同名的Cookie，将会互相覆盖的情况（Cookie规范里面也规定了，客户端以domain，path，name作为Cookie的唯一标示）。而原始Cookie的secure和expires值，直接符给新的Cookie，新Cookie的domain和path设成缺省值，这样，新Cookie就可以被浏览器正常接受。由于浏览器接受的所有Cookie的domain和path值都一样，因此每次用户对MTS提出请求时，浏览器都会把所有与MTS站点相关的Cookie上传，因此，MTS还需要还原原始的Cookie，过滤掉与目标服务器不相干的Cookie，然后上传有用的Cookie。</p>
		<p>这种思路的优点在于Cookie存储在客户端，可以做到长期存储，浏览器自己根据Cookie的expires值做出判断，省掉很多开发的麻烦。缺点是转换的过程相对较复杂。另外还有一个缺点，也是由于Cookie规范的限制所造成的。Cookie规范对于一个浏览器同时能够存储的Cookie数量作出了规定。</p>
		<ul>
				<li>总共300 个cookie 
</li>
				<li>每个Cookie 4 K 的存储容量 
</li>
				<li>每一个domain 或者 server 20 个cookie。 </li>
		</ul>
		<p>以上是浏览器所应达到的最小存储数量，超出这个限制，浏览器应该自动按照最少最近被使用的原则删除超出得Cookie。由于用户有可能通过MTS这一个网站翻译大量的目标服务器，因此浏览器存储在MTS的domain下的cookie数量就很有可能超过20个，这时候就会导致某些Cookie被删除。一般这也不会造成太大问题，因为规范是要求浏览器删除最少最近被使用的Cookie，但我们在实际测试当中发现有些浏览器并不遵守这样的规范，而是删除最新的Cookie，这就将导致用户很大的不便。</p>
		<p>
				<a name="IDA4GYZB">
						<span class="smalltitle">
								<strong>
										<font size="3">思路二</font>
								</strong>
						</span>
				</a>
		</p>
		<p>第二种思路在于把原始的Cookie组织成dataBean，存储到用户的Session当中去。这样，在用户端只需要存储一个SessionID的Cookie，而不需要存储所有目标服务器的每一个Cookie。另外，当接收到用户的又一次翻译请求时，再从Session当中取出所有的dataBean，逐一进行分析，找出与用户所请求的目标服务器相符的原始Cookie，进行提交。</p>
		<p>这种思路可以克服上一种思路中Cookie超过标准数量时的缺陷，而且不需编码保存原始的Cookie属性值，减少了程序的复杂度。缺点是需要程序员自己处理expires。而且由于是把Cookie存储在Session中，一旦Session失效，所有Cookie都将被删除，所以，无法保存那些长期的Cookie。</p>
		<p>总之，两种思路各有利弊，在实际应用当中要权衡考虑。下面我们针对两种思路进行技术实现，分别对应方案一和方案二。</p>
		<p>由于MTS需要与目标服务器连接，遵循HTTP协议读取和返回Cookie，但是如果用JDK中的java.net.URLConnection处理Cookie将非常不方便，因此我们使用HTTPClient来处理与目标服务器的连接。</p>
		<p>
				<a name="IDAHHYZB">
						<span class="atitle">
								<font size="4">方案一：Cookie存储在浏览器端</font>
						</span>
				</a>
		</p>
		<p>用户每发起一次新的请求，浏览器在检查完本地存储Cookie的有效性后，会把所有由MTS产生的有效Cookie附加在请求头里送到MTS。MTS接受到客户端的翻译请求后，从Request中提取出所有的Cookie，还原后根据目标服务器的domain和path进行过滤。产生所有与目标服务器相关的Cookie。</p>
		<p>
				<br />
				<a name="IDANHYZB">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">//从request中获取所有的Cookie
javax.servlet.http.Cookie[] theCookies = request.getCookies();
ArrayList cookiesList = new ArrayList();
String url = request.getParameter("url");
String domain = URLUtil.getURLHost(url);
String path = URLUtil.getPath(url);

if (theCookies != null)
{
	for (int i = 0; i &lt; theCookies.length; i++)
	{
		RE r = new RE();
         //用正则表达式把name项还原成domain，path，name
		REDebugCompiler compiler = new REDebugCompiler();
		r.setProgram(compiler.compile("\\|\\|"));
		String[] values = r.split(theCookies[i].getName());
		//"9.181.116.183||/MTModule||testCookie:value1" or " ||              
		||testCookie:value1"
		if (values.length == 3)
		{
			if (values[0].trim().startsWith("."))
			{
				if (!domain.endsWith(values[0].trim()))
					continue;
			} else if (!domain.endsWith("://" + values[0].trim()))
					continue;
			if (!path.startsWith(values[1].trim()))
				continue;

			Cookie tempCookie = new Cookie();
			tempCookie.setDomain(
				("".equals(values[0].trim())) ? null : values[0]);
			tempCookie.setPath(
				("".equals(values[1].trim())) ? null : values[1]);
			tempCookie.setName(
				("".equals(values[2].trim())) ? null : values[2]);
			tempCookie.setSecure(theCookies[i].getSecure());
			tempCookie.setValue(theCookies[i].getValue());
			tempCookie.setVersion(theCookies[i].getVersion());
			tempCookie.setComment(theCookies[i].getComment());
			cookiesList.add(tempCookie);
		}
	}
}
//transferedCookie用来存储将被传到目标服务器的Cookie
Cookie[] transferedCookie = new Cookie[cookiesList.size()];
cookiesList.toArray(transferedCookie);
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>接下来，需要把Cookie送到目标服务器中。我们使用HTTPClient与目标服务器连接。HTTPClient在与目标服务器连接以后，允许服务器设置Cookie并在需要的时候自动将Cookie返回服务器，也支持手工设置 Cookie后发送到服务器端。但是，由于如何处理cookie有几个规范互相冲突：Netscape Cookie 草案、RFC2109、RFC2965，而且还有很大数量的软件商的Cookie实现不遵循任何规范。 为了处理这种状况，需要把HttpClient设置成Cookie兼容模式，这样可以最大限度的处理好各种Cookie。下面的代码把Cookie送到目标服务器。</p>
		<p>
				<br />
				<a name="IDAVHYZB">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">HttpClient client = new HttpClient();
//从request得到所有需要传输的cookie 
Cookie[] questCookie = getCookieFromRequest(request);
//设置HTTPClient为Cookie兼容模式
client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY);
if (questCookie.length &gt; 0)
//把Cookie加到httpclient中
	client.getState().addCookies(questCookie);
HttpMethod method = new GetMethod(TagerURL);
 //向目标服务器发送请求
int statusCode = client.executeMethod(method);
method.releaseConnection();
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>MTS把请求和Cookie送出后，继续接收目标服务器的应答，读取返回的原始Cookie，并转换成可以存储在用户浏览器端的Cookie。下面的代码将对原始Cookie的内容进行变换，保留expires和secure等项，把domain和path项编码到name中去。</p>
		<p>
				<br />
				<a name="IDA3HYZB">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">//从HTTPClient中取得所有的Cookie
Cookie[] temp = client.getState().getCookies();
if (temp != null)
{
	javax.servlet.httpCookie theCookie = new javax.servlet.http.Cookie[temp.length];
     //逐一对Cookie进行处理
	for (int i = 0; i &lt; temp.length; i++)
	{    StringBuffer sb = new StringBuffer();
        //编码成domain||path||name
        sb.append(
        	temp[i].getDomain() == null ? " " : temp[i].getDomain());
        sb.append("||");
        sb.append(temp[i].getPath() == null ? " " : temp[i].getPath());
        sb.append("||");
        sb.append(temp[i].getName() == null ? " " : temp[i].getName());
        theCookie[i] =
        	new Cookie(sb.toString(),temp[i].getValue());
        //复制其他项
        theCookie[i].setMaxAge(theCookie[i].getMaxAge();
        theCookie[i].setSecure(temp[i].getSecure());
        theCookie[i].setVersion(temp[i].getVersion());
        theCookie[i].setComment(temp[i].getComment());
	}
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>最后一步，把这些Cookie保存到response里，随HTTP应答头返回用户浏览器。并保存在浏览器中。</p>
		<p>
				<br />
				<a name="IDAIAA3B">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">//把所有转换后的Cookie加入response
for (int i = 0; i &lt; theCookie.length; i++) {
	response.addCookie(theCookie[i]);
}
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>至此，我们已经完成了接收用户请求，转换Cookie，发送到目标服务器，接收目标服务器的原始Cookie，并保存在客户浏览器的整个处理过程。</p>
		<p>
				<a name="IDAQAA3B">
						<span class="atitle">
								<font size="4">方案二：Cookie存储在服务器端</font>
						</span>
				</a>
		</p>
		<p>在此种方案中，目标服务器返回给MTS的Cookie将被组织成dataBean，存储在用户的Session中。因此，我们首先生成一个用来存储Cookie的类CookiesBean，根据它的特性，它可以继承ArraryList类。此对象将存储用户访问目标服务器时接收到的所有Cookie，并提供与新接收到的Cookie融合的功能，同时能够删除过期的Cookie，更新同名的Cookie。</p>
		<p>
				<br />
				<a name="IDAWAA3B">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">public class CookiesBean extends ArrayList
{
	/**
	 * 处理Cookies.
	 * @参数 Cookies array
	 */
	public CookiesBean(Cookie[] cook)
	{
		if (cook == null)
			return;
//add all cookie which isn't expired.
		for (int i = 0; i &lt; cook.length; i++)
		{
			if (!cook[i].isExpired())
			{
				add(cook[i]);
			}
		}
	}

	/**
	 * 融合参数中的bean
	 * @参数 bean
	 * 参考: rfc2109 4.3.3  Cookie Management
	 */
	public void RefreshBean(CookiesBean bean)
	{
		if (bean == null)
			return;

		Iterator it = bean.iterator();
         //针对bean中的每一个Cookie进行处理
		while (it.hasNext())
		{
			Cookie beanCookie = (Cookie) it.next();
			if (beanCookie == null) continue;

			ArrayList drop = new ArrayList();
			Iterator thisIt = iterator();
              //取出存储的Cookie进行比较和处理
			while (thisIt.hasNext())
			{
				Cookie thisCookie = (Cookie) thisIt.next();
				if (thisCookie == null) continue;
                   //比较name，domain和path,如果一样的话，则把此Cookie移到drop中
				if (CommonMethods
					.CompString(beanCookie.getName(), thisCookie.getName())
					&amp;&amp; CommonMethods.CompString(
						beanCookie.getDomain(),
						thisCookie.getDomain())
					&amp;&amp; CommonMethods.CompString(
						beanCookie.getPath(),
						thisCookie.getPath()))
				{
					drop.add(thisCookie);
					continue;
				}
                  //删除过期的Cookie
				if (thisCookie.isExpired())
					drop.add(thisCookie);
			}
             //删除所有drop中的Cookie
			this.removeAll(drop);
             //如果beanCookie有效，则加入到存储区中。
			if (!beanCookie.isExpired())
				add(beanCookie);
		}

		return;
	}
}	
</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>当MTS接受到客户端的翻译请求后，会从Session中提取出所有的dataBean，并得到存储的所有Cookie。如以下代码：</p>
		<p>
				<br />
				<a name="IDA4AA3B">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">				CookiesBean dataBean = null;
		Cookie[] theCookies = new Cookie[0];
		ArrayList cookiesList = new ArrayList();
         //获得Session，并获得dataBean
		HttpSession session = request.getSession(false);
		if (session != null)
		{
			dataBean = (CookiesBean) session.getAttribute(SESSION_NAME);
		}
		else
		{
			return theCookies;
		}
		</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>MTS在所有的存储的Cookie中，检查Cookie的Domain、path和secure的值，筛选出符合目标服务器的Cookie。</p>
		<p>
				<br />
				<a name="IDAGBA3B">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">				//提取目标服务器的domain和path
		String url = context.getURL();
		String domain = URLUtil.getURLHost(url);
		String path = url.substring(domain.length());
		
		String cookiedomain = null;
		String cookiepath = null;
		//逐个比较Cookie的domain和path
		//把符合要求的Cookie纪录到cookiesList中
		for (int i = 0; i &lt; dataBean.size(); i++)
		{
			Cookie cookie = (Cookie) dataBean.get(i);
			if (cookie == null) continue;
			cookiedomain =
				(cookie.getDomain() == null) ? "" : cookie.getDomain();
			cookiepath = (cookie.getPath() == null) ? "  " : cookie.getPath();

			if (!path.startsWith(cookiepath))
				continue;

			if (cookiedomain.startsWith("."))
			{
				if (!domain.endsWith(cookiedomain))
					continue;
			}
			else if (!domain.endsWith("://" + cookiedomain))
				continue;
			if (cookie.isExpired())
				continue;
			if (cookie.getSecure() &amp;&amp; url.toLowerCase().startsWith("http:"))
				continue;

			cookiesList.add(cookie);
		}
		theCookies = new Cookie[cookiesList.size()];
		cookiesList.toArray(theCookies);
		return theCookies;
		</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>把Cookie送到目标服务器的代码与方案一基本一样，在此忽略。</p>
		<p>最后一步，需要把Cookie存储到Session中。下面的代码将从目标服务器接受Cookie，融入到dataBean中，并保存到客户的Session中。</p>
		<p>
				<br />
				<a name="IDAPBA3B">
						<b>
						</b>
				</a>
				<br />
		</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<font face="Lucida Console">		//从目标服务器得到Cookie集
     Cookie[] cookies = client.getState().getCookies();
	CookiesBean bean = new CookiesBean(cookies);
     CookiesBean dataBean = bean;

     //取得用户Session
	HttpSession session =  request.getSession(false);
	if (session != null)
	{
		if (session.getAttribute(SESSION_NAME) != null)
		{
              //读取Session中存取的dataBean
			dataBean = (CookiesBean) session.getAttribute(SESSION_NAME);
              //目标服务器端的Cookie融合到Session中的dataBean中
			dataBean.RefreshBean(bean);
		}
         //把最终的dataBean存入Session中
		session.setAttribute(SESSION_NAME, dataBean);
	}
	</font>
												</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>至此，我们已经完成了在Session中保存个目标服务器所产生Cookie的整个处理过程。</p>
		<p>
				<a name="IDAXBA3B">
						<span class="atitle">
								<font size="4">关于Session的考虑</font>
						</span>
				</a>
		</p>
		<p>在研究完如何管理和传递Cookie之后，我们也需要研究一下Session的传递。因为目前大部分站点都在采用Session机制保存用户状态数据，如果不能解决Session的传递问题，HTTP应用代理服务器的适用范围同样会大打折扣。</p>
		<p>首先我们了解一下Session的实现机制。Session是一种服务器端的机制，服务器使用一种类似于散列表的结构来保存信息。当程序需要为某个客户端的请求创建一个session的时候，服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id，如果已包含一个session id则说明以前已经为此客户端创建过session，服务器就按照session id把这个session检索出来使用（如果检索不到，可能会新建一个），session id的值应该是一个既不会重复，又不容易被找到规律以仿造的字符串。</p>
		<p>保存这个session id的方式之一就是采用Cookie。一般这个Cookie的名字都类似于 SESSIONID。比如WebSphere对于Web应用程序生成的Cookie：JSESSIONID= 0001HWF4iVD94pY8Cpbx6U4CXkf:10lro0398，它的名字就是 JSESSIONID。</p>
		<p>保存session id的其他方式还包括URL重写和表单隐藏字段。这两种方式都不需要代理服务器作特殊处理。因此实际上，我们解决了Cookie的管理和传递的问题之后，也就解决了Session的管理和传递。</p>
		<p>
				<a name="IDAACA3B">
						<span class="atitle">
								<font size="4">结束语</font>
						</span>
				</a>
		</p>
		<p>从上面的讨论中可以看出，由于Cookie本身的规范限制，HTTP应用代理所必需面对的一个问题就是如何对Cookie进行正确的处理。本文对此提出了两种解决思路并列出了实现代码。对于MTS项目本身，我们使用的是第二种方案。开发人员在认识好Cookie本身的特性之后，参照本文的思路，根据自己系统的特点，也会找出更适宜的解决方案。</p>
		<p>
				<a name="resources">
						<span class="atitle">
								<font size="4">参考资料 </font>
						</span>
				</a>
		</p>
		<ul>
				<li>Netscape Cookie Specification 对Netscape Cookie 使用的特性进行了简要的介绍。<br /><br /></li>
				<li>RFC2965：HTTP State Management Mechanism 介绍了HTTP 状态管理机制<br /><br /></li>
				<li>RFC2109 w3c发布的第一个官方cookie规范<br /><br /></li>
				<li>RFC2616：Hypertext Transfer Protocol 超文本传输协议<br /><br /></li>
				<li>Ronald Tschalr开发了 HTTPClient，将其作为 URLConnection 的替代品。<br /><br /></li>
				<li>Jakarta Regexp Apache 的开源项目，处理正则表达式的java包。 </li>
		</ul>
<img src ="http://www.blogjava.net/iKingQu/aggbug/36531.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-21 00:59 <a href="http://www.blogjava.net/iKingQu/articles/36531.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Java中四种XML解析技术之不完全测试</title><link>http://www.blogjava.net/iKingQu/articles/36489.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 20 Mar 2006 15:31:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36489.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36489.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36489.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36489.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36489.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<p>
						<font size="4">
								<strong>测试环境：</strong>
						</font>
						<br />
						<br />　　AMD毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server SP4、Sun JDK 1.4.1+Eclipse 2.1+Resin 2.1.8，在Debug模式下测试。 <br /><br />　　XML文件格式如下： <br /><br />　　&lt;?xml version="1.0" encoding="GB2312"?&gt;&lt;RESULT&gt;&lt;VALUE&gt; <br /><br />　　&lt;NO&gt;A1234&lt;/NO&gt; <br /><br />　　&lt;ADDR&gt;四川省XX县XX镇XX路X段XX号&lt;/ADDR&gt;&lt;/VALUE&gt;&lt;VALUE&gt; <br /><br />　　&lt;NO&gt;B1234&lt;/NO&gt; <br /><br />　　&lt;ADDR&gt;四川省XX市XX乡XX村XX组&lt;/ADDR&gt;&lt;/VALUE&gt;&lt;/RESULT&gt; <br /><br /><font size="4"><strong>测试方法：</strong></font><br /><br />　　让每一种方案分别解析10K、100K、1000K、10000K的XML文件，计算其消耗时间(单位:毫秒)。 <br /><br />　　JSP文件： <br /><br />　　&lt;%@ page contentType="text/html; charset=gb2312" %&gt;&lt;%@ page import="com.test.*"%&gt; <br /><br />　　&lt;html&gt;&lt;body&gt;&lt;%String args[]={""};MyXMLReader.main(args);%&gt;&lt;/body&gt;&lt;/html&gt; <br /><br />　　测试 <br /><br />　　首先出场的是DOM(JAXP Crimson解析器) <br /><br />　　DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构，然后才能做任何工作。由于它是基于信息层次的，因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先，由于树在内存中是持久的，因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航，而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 <br /><br />　　另一方面，对于特别大的文档，解析和加载整个文档可能很慢且很耗资源，因此使用其他手段来处理这样的数据会更好。这些基于事件的模型，比如SAX。 <br /><br />　　Bean文件： <br /><br />　　package com.test; <br /><br />　　import java.io.*;import java.util.*;import org.w3c.dom.*;import javax.xml.parsers.*; <br /><br />　　public class MyXMLReader{ <br /><br />　　public static void main(String arge[]){ <br /><br />　　long lasting =System.currentTimeMillis(); <br /><br />　　try{ <br /><br />　　　File f=new File("data_10k.xml"); <br /><br />　　　DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); <br /><br />　　　DocumentBuilder builder=factory.newDocumentBuilder(); <br /><br />　　　Document doc = builder.parse(f); <br /><br />　　　NodeList nl = doc.getElementsByTagName("VALUE"); <br /><br />　　　for (int i=0;i&lt;nl.getLength();i++){ <br /><br />　　　　System.out.print("车牌号码:" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue()); <br /><br />　　　　System.out.println("车主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue()); <br /><br />　　} <br /><br />　　}catch(Exception e){ <br /><br />　　　e.printStackTrace(); <br /><br />　　} <br /><br />　　System.out.println("运行时间："+(System.currentTimeMillis() - lasting)+"毫秒");}} <br /><br />　　10k消耗时间：265 203 219 172 <br /><br />　　100k消耗时间：9172 9016 8891 9000 <br /><br />　　1000k消耗时间：691719 675407 708375 739656 <br /><br />　　10000k消耗时间：OutOfMemoryError <br /><br />　　接着是SAX <br /><br />　　这种处理的优点非常类似于流媒体的优点。分析能够立即开始，而不是等待所有的数据被处理。而且，由于应用程序只是在读取数据时检查数据，因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上，应用程序甚至不必解析整个文档；它可以在某个条件得到满足时停止解析。一般来说，SAX还比它的替代者DOM快许多。 <br />　　选择DOM还是选择SAX？ <br /><br />　　对于需要自己编写代码来处理XML文档的开发人员来说， <br /><br />　　选择DOM还是SAX解析模型是一个非常重要的设计决策。 <br /><br />　　DOM采用建立树形结构的方式访问XML文档，而SAX采用的事件模型。 <br /><br />　　DOM解析器把XML文档转化为一个包含其内容的树，并可以对树进行遍历。用DOM解析模型的优点是编程容易，开发人员只需要调用建树的指令，然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档，所以对性能和内存的要求比较高，尤其是遇到很大的XML文件的时候。由于它的遍历能力，DOM解析器常用于XML文档需要频繁的改变的服务中。 <br /><br />　　SAX解析器采用了基于事件的模型，它在解析XML文档的时候可以触发一系列的事件，当发现给定的tag的时候，它可以激活一个回调方法，告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低，因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时，SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难，而且很难同时访问同一个文档中的多处不同数据。 <br /><br />　　Bean文件： <br /><br />　　package com.test;import org.xml.sax.*;import org.xml.sax.helpers.*;import javax.xml.parsers.*; <br /><br />　　public class MyXMLReader extends DefaultHandler { <br /><br />　　java.util.Stack tags = new java.util.Stack(); <br /><br />　　public MyXMLReader() { <br /><br />　　super();} <br /><br />　　public static void main(String args[]) { <br /><br />　　long lasting = System.currentTimeMillis(); <br /><br />　　try { <br /><br />　　　SAXParserFactory sf = SAXParserFactory.newInstance(); <br /><br />　　　SAXParser sp = sf.newSAXParser(); <br /><br />　　　MyXMLReader reader = new MyXMLReader(); <br /><br />　　　sp.parse(new InputSource("data_10k.xml"), reader); <br /><br />　　} catch (Exception e) { <br /><br />　　　e.printStackTrace(); <br /><br />　　} <br /><br />　　System.out.println("运行时间：" + (System.currentTimeMillis() - lasting) + "毫秒");} <br /><br />　　public void characters(char ch[], int start, int length) throws SAXException { <br /><br />　　String tag = (String) tags.peek(); <br /><br />　　if (tag.equals("NO")) { <br /><br />　　　System.out.print("车牌号码：" + new String(ch, start, length));}if (tag.equals("ADDR")) { <br /><br />　　System.out.println("地址:" + new String(ch, start, length));}} <br /><br />　　public void startElement(String uri,String localName,String qName,Attributes attrs) { <br /><br />　　tags.push(qName);}} <br /><br />　　10k消耗时间：110 47 109 78 <br /><br />　　100k消耗时间：344 406 375 422 <br /><br />　　1000k消耗时间：3234 3281 3688 3312 <br /><br />　　10000k消耗时间：32578 34313 31797 31890 30328 <br /><br />　　然后是JDOM http://www.jdom.org/ <br /><br />　　JDOM的目的是成为Java特定文档模型，它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型，JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。 <br /><br />　　JDOM与DOM主要有两方面不同。首先，JDOM仅使用具体类而不使用接口。这在某些方面简化了API，但是也限制了灵活性。第二，API大量使用了Collections类，简化了那些已经熟悉这些类的Java开发者的使用。 <br /><br />　　JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的，并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而，它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口都更有意义的工作。 <br /><br />　　JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入)。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布的开放源码。 <br /><br />　　Bean文件： <br /><br />　　package com.test; <br /><br />　　import java.io.*;import java.util.*;import org.jdom.*;import org.jdom.input.*; <br /><br />　　public class MyXMLReader { <br /><br />　　public static void main(String arge[]) { <br /><br />　　long lasting = System.currentTimeMillis(); <br /><br />　　try { <br /><br />　　　SAXBuilder builder = new SAXBuilder(); <br /><br />　　　Document doc = builder.build(new File("data_10k.xml")); <br /><br />　　　Element foo = doc.getRootElement(); <br /><br />　　　List allChildren = foo.getChildren(); <br /><br />　　　for(int i=0;i&lt;allChildren.size();i++) { <br /><br />　　　　System.out.print("车牌号码:" + ((Element)allChildren.get(i)).getChild("NO").getText()); <br /><br />　　　　System.out.println("车主地址:" + ((Element)allChildren.get(i)).getChild("ADDR").getText()); <br /><br />　　　} <br /><br />　　} catch (Exception e) { <br /><br />　　　e.printStackTrace(); <br /><br />　　} <br /><br />　　System.out.println("运行时间：" + (System.currentTimeMillis() - lasting) + "毫秒");}} <br /><br />　　10k消耗时间：125 62 187 94 <br /><br />　　100k消耗时间：704 625 640 766 <br /><br />　　1000k消耗时间：27984 30750 27859 30656 <br /><br />　　10000k消耗时间：OutOfMemoryError <br /><br />　　最后是DOM4J http://dom4j.sourceforge.net/ <br /><br />　　虽然DOM4J代表了完全独立的开发结果，但最初，它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能，包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项，它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始，它就一直处于开发之中。 <br /><br />　　为支持所有这些功能，DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类，但是在许多情况下，它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是，虽然DOM4J付出了更复杂的API的代价，但是它提供了比JDOM大得多的灵活性。 <br /><br />　　在添加灵活性、XPath集成和对大文档处理的目标时，DOM4J的目标与JDOM是一样的：针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案，实现在本质上处理所有Java/XML问题的目标。在完成该目标时，它比JDOM更少强调防止不正确的应用程序行为。 <br /><br />　　DOM4J是一个非常非常优秀的Java XML API，具有性能优异、功能强大和极端易用使用的特点，同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML，特别值得一提的是连Sun的JAXM也在用DOM4J。 <br /><br />　　Bean文件： <br /><br />　　package com.test; <br /><br />　　import java.io.*;import java.util.*;import org.dom4j.*;import org.dom4j.io.*; <br /><br />　　public class MyXMLReader { <br /><br />　　public static void main(String arge[]) { <br /><br />　　long lasting = System.currentTimeMillis(); <br /><br />　　try { <br /><br />　　　File f = new File("data_10k.xml"); <br /><br />　　　SAXReader reader = new SAXReader(); <br /><br />　　　Document doc = reader.read(f); <br /><br />　　　Element root = doc.getRootElement(); <br /><br />　　　Element foo; <br /><br />　　　for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) { <br /><br />　　　　foo = (Element) i.next(); <br /><br />　　　　System.out.print("车牌号码:" + foo.elementText("NO")); <br /><br />　　　　System.out.println("车主地址:" + foo.elementText("ADDR")); <br /><br />　　　} <br /><br />　　} catch (Exception e) { <br /><br />　　　e.printStackTrace(); <br /><br />　　} <br /><br />　　System.out.println("运行时间：" + (System.currentTimeMillis() - lasting) + "毫秒");}} <br /><br />　　10k消耗时间：109 78 109 31 <br /><br />　　100k消耗时间：297 359 172 312 <br /><br />　　1000k消耗时间：2281 2359 2344 2469 <br /><br />　　10000k消耗时间：20938 19922 20031 21078 <br /><br />　　JDOM和DOM在性能测试时表现不佳，在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM。虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题，但是从性能观点来看，它确实没有值得推荐之处。另外，DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础，因为它正式获得W3C推荐(与基于非标准的Java模型相对)，所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。 <br /><br />　　SAX表现较好，这要依赖于它特定的解析方式。一个SAX检测即将到来的XML流，但并没有载入到内存(当然当XML流被读入时，会有部分文档暂时隐藏在内存中)。 <br /><br />　　无疑，DOM4J是这场测试的获胜者，目前许多开源项目中大量采用DOM4J，例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性，那就采用DOM4J吧</p>
				<br />
				<br />
				<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=589524</p>
		</div>
<img src ="http://www.blogjava.net/iKingQu/aggbug/36489.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-20 23:31 <a href="http://www.blogjava.net/iKingQu/articles/36489.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]XML的四种解析器原理及性能比较 </title><link>http://www.blogjava.net/iKingQu/articles/36487.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 20 Mar 2006 15:29:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36487.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36487.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36487.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36487.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36487.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<p>1： DOM <br /><br />DOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准。DOM 是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构，然后才能做任何工作。由于它是基于信息层次的，因而 DOM 被认为是基于树或基于对象的。DOM 以及广义的基于树的处理具有几个优点。 <br /><br />首先，由于树在内存中是持久的，因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航，而不是像 SAX 那样是一次性的处理。DOM 使用起来也要简单得多。 <br /><br />另一方面，对于特别大的文档，解析和加载整个文档可能很慢且很耗资源，因此使用其他手段来处理这样的数据会更好。这些基于事件的模型，比如 SAX. <br /><br />2：SAX <br /><br />这种处理的优点非常类似于流媒体的优点。分析能够立即开始，而不是等待所有的数据被处理。而且，由于应用程序只是在读取数据时检查数据，因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上，应用程序甚至不必解析整个文档；它可以在某个条件得到满足时停止解析。一般来说，SAX 还比它的替代者 DOM 快许多。 <br /><br />3：选择 DOM 还是选择 SAX ？ <br /><br />对于需要自己编写代码来处理 XML 文档的开发人员来说，选择 DOM 还是 SAX 解析模型是一个非常重要的设计决策。 <br /><br />DOM 采用建立树形结构的方式访问 XML 文档，而 SAX 采用的事件模型。 <br /><br />DOM 解析器把 XML 文档转化为一个包含其内容的树，并可以对树进行遍历。用 DOM 解析模型的优点是编程容易，开发人员只需要调用建树的指令，然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML 文档，所以对性能和内存的要求比较高，尤其是遇到很大的 XML 文件的时候。由于它的遍历能力，DOM 解析器常用于 XML 文档需要频繁的改变的服务中。 <br /><br />SAX 解析器采用了基于事件的模型，它在解析 XML 文档的时候可以触发一系列的事件，当发现给定的tag的时候，它可以激活一个回调方法，告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低，因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时，SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难，而且很难同时访问同一个文档中的多处不同数据。 <br /><script type="text/javascript"><!--
google_ad_client = "pub-9416189179052893";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text_image";
google_ad_channel ="0040068371";
google_color_border = "DDB7BA";
google_color_bg = "FFF5F6";
google_color_link = "0000CC";
google_color_url = "008000";
google_color_text = "6F6F6F";
//--></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script><iframe name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-9416189179052893&amp;dt=1142868416203&amp;lmt=1142868416&amp;prev_fmts=160x600_as&amp;format=468x60_as&amp;output=html&amp;channel=0040068371&amp;pv_ch=0040068371%2B&amp;url=http%3A%2F%2Fblog.csdn.net%2Fbaggio785%2Farchive%2F2006%2F01%2F28%2F589518.aspx&amp;color_bg=FFF5F6&amp;color_text=6F6F6F&amp;color_link=0000CC&amp;color_url=008000&amp;color_border=DDB7BA&amp;ad_type=text_image&amp;cc=22&amp;u_h=768&amp;u_w=1024&amp;u_ah=738&amp;u_aw=1024&amp;u_cd=32&amp;u_tz=480&amp;u_java=true" frameborder="0" width="468" scrolling="no" height="60" allowtransparency=""></iframe><br />4：JDOM <br /><br />JDOM的目的是成为 Java 特定文档模型，它简化与 XML 的交互并且比使用 DOM 实现更快。由于是第一个 Java 特定模型，JDOM 一直得到大力推广和促进。正在考虑通过“Java 规范请求 JSR-102”将它最终用作“Java 标准扩展”。从 2000 年初就已经开始了 JDOM 开发。 <br /><br />JDOM 与 DOM 主要有两方面不同。首先，JDOM 仅使用具体类而不使用接口。这在某些方面简化了 API，但是也限制了灵活性。第二，API 大量使用了 Collections 类，简化了那些已经熟悉这些类的 Java 开发者的使用。 <br /><br />JDOM 文档声明其目的是“使用 20%（或更少）的精力解决 80%（或更多）Java/XML 问题”（根据学习曲线假定为 20%）。JDOM 对于大多数 Java/XML 应用程序来说当然是有用的，并且大多数开发者发现 API 比 DOM 容易理解得多。JDOM 还包括对程序行为的相当广泛检查以防止用户做任何在 XML 中无意义的事。然而，它仍需要您充分理解 XML 以便做一些超出基本的工作（或者甚至理解某些情况下的错误）。这也许是比学习 DOM 或 JDOM 接口都更有意义的工作。 <br /><br />JDOM 自身不包含解析器。它通常使用 SAX2 解析器来解析和验证输入 XML 文档（尽管它还可以将以前构造的 DOM 表示作为输入）。它包含一些转换器以将 JDOM 表示输出成 SAX2 事件流、DOM 模型或 XML 文本文档。JDOM 是在 Apache 许可证变体下发布的开放源码。 <br /><br />5： DOM4J <br /><br />虽然 DOM4J 代表了完全独立的开发结果，但最初，它是 JDOM 的一种智能分支。它合并了许多超出基本 XML 文档表示的功能，包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项，它通过 DOM4J API 和标准 DOM 接口具有并行访问功能。从 2000 下半年开始，它就一直处于开发之中。 <br /><br />为支持所有这些功能，DOM4J 使用接口和抽象基本类方法。DOM4J 大量使用了 API 中的 Collections 类，但是在许多情况下，它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是，虽然 DOM4J 付出了更复杂的 API 的代价，但是它提供了比 JDOM 大得多的灵活性。 <br /><br />在添加灵活性、XPath 集成和对大文档处理的目标时，DOM4J 的目标与 JDOM 是一样的：针对 Java 开发者的易用性和直观操作。它还致力于成为比 JDOM 更完整的解决方案，实现在本质上处理所有 Java/XML 问题的目标。在完成该目标时，它比 JDOM 更少强调防止不正确的应用程序行为。 <br /><br />DOM4J 是一个非常非常优秀的Java XML API，具有性能优异、功能强大和极端易用使用的特点，同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML，特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J. <br /><br />6：总述 <br /><br />JDOM 和 DOM 在性能测试时表现不佳，在测试 10M 文档时内存溢出。在小文档情况下还值得考虑使用 DOM 和 JDOM.虽然 JDOM 的开发者已经说明他们期望在正式发行版前专注性能问题，但是从性能观点来看，它确实没有值得推荐之处。另外，DOM 仍是一个非常好的选择。DOM 实现广泛应用于多种编程语言。它还是许多其它与 XML 相关的标准的基础，因为它正式获得 W3C 推荐（与基于非标准的 Java 模型相对），所以在某些类型的项目中可能也需要它（如在 javascript 中使用 DOM）。 <br /><br />SAX表现较好，这要依赖于它特定的解析方式。一个 SAX 检测即将到来的XML流，但并没有载入到内存（当然当XML流被读入时，会有部分文档暂时隐藏在内存中）。 <br /><br />无疑，DOM4J是最好的，目前许多开源项目中大量采用 DOM4J，例如大名鼎鼎的 Hibernate 也用 DOM4J 来读取 XML 配置文件。如果不考虑可移植性，那就采用DOM4J吧！</p>
				<br />
				<br />
				<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=589518</p>
		</div>
<img src ="http://www.blogjava.net/iKingQu/aggbug/36487.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-20 23:29 <a href="http://www.blogjava.net/iKingQu/articles/36487.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]企业级应用为什么要分层？</title><link>http://www.blogjava.net/iKingQu/articles/36422.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 20 Mar 2006 12:50:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36422.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36422.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36422.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36422.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36422.html</trackback:ping><description><![CDATA[首先，需要知道什么是企业级应用。<br /><br /><span style="FONT-WEIGHT: bold">企业级应用（enterprise applications）</span>，其实是一个软件行业内部通用的一个术语。如果解释成通俗易懂的话来说，那就是一个企业范围内所使用的、基于计算机的稳定的、安全的和高效的分布式信息管理系统。<br />对于企业级应用而言它的分布式有两种形式：B/S结构和C/S结构。由于浏览器的功能日益强大、网页技术的日益流行和应用服务器软件和中间件产品的逐步成熟，B/S结构的企业级应用已经成为一种流行的趋势，所以在下面的讨论中所谓的企业级应用统一为基于B/S结构的分布式企业信息系统。<br /><br />一般说来企业级应用都可以分为三层<a title="持久层（Persistence Layer）" href="http://www.ambysoft.com/essays/persistenceLayer.html">持久层（Persistence Layer）</a> 、<a title="业务逻辑层（Business Logic Layer）" href="http://www.onjava.com/pub/a/onjava/excerpt/bldgjavaent_8/index1.html">业务逻辑层（Business Logic Layer）</a> 和<a title="展现层（Presentation Layer  ）" href="http://en.wikipedia.org/wiki/Presentation_layer">展现层（Presentation Layer ）</a> 。<br />为什么要分这么几个层次呢？ <br />归根结底主要原因只有一个——那就是提高软件开发生产力，降低软件开发成本，提高软件产品质量。<br />因为软件公司也是资本公司，公司的主要目标是盈利而不是科技发展。所以，公司的技术架构的优劣主要应该体现在公司的生产成本和产品的质量上。<br />对于降低软件产品的开发成本是软件产品出现以来所有软件公司所追求的目标。到目前为止，达到这个目标的方式有这么几种：<br /><ol><li>把软件产品根据功能进行分解，分别开发：对于大的复杂系统，如果没有很好的分解开发的话，其结果是不可想象的。现实中企业需要分开各个职能部门，它们的职责和业务是不同的，这样开发中需要根据业务进行任务分解，把大的系统分解成为小的业务系统。这样才能够实现系统开发过程中的并行开发，并且会培养业务专精人员，提高开发的效率。 
</li><li>业务系统根据技术架构进行分层开发：分层的开发方式实现了人类对复杂事物的普遍处理方式——分而治之。通过把复杂的系统分解成为相对简单的独立系统，低耦合的分解既可以实现开发人员的并行工作，又可以实现开发人员的任务分工。而且通过分层，对组件拼装和流水化作业提供了理论和事实的基础。 
</li><li>组件拼装实现社会化分工：不必自己去创造轮子，直接付钱去买想要的轮子即可。这是从传统的制造行业借鉴来的经验。J2EE得到的广泛认同从实质上体现了业界对这种方式的肯定。 
</li><li>过去经验的积累和积累资源的重复利用：重用一直是一个争议比较大的东西，争论的双方各执一词，各有道理也各有大师助阵，但是那更多的是在理论上和技术层面上。理论和技术上的争论对商业软件开发是无用的。因为商业化的软件开发，最重要的是提供优质的产品和服务并且能够最大可能的获取利润。所以，抛开具体实现方式不谈，我个人觉得公司过去经验的积累和积累资源的重复利用是有商业价值的。因为软件公司必须得面对开发人员流动的问题，不管是升迁还是调动还是跳槽，软件公司总会面对业务专精人员的流失问题。业务专精人员的流失造成的成本是要计算在开发成本中的，所以怎样以固化的形式积累业务人员的经验，和过去解决问题的方案的可重复利用以及新员工职业培训成本的降低在降低开发成本的方面是值得考虑的。</li></ol>综上所述，对于一个企业级应用框架（还有人开发企业级应用不用框架吗？）而言，分层是提高开发效率、降低开发和培训成本的最佳实践方案之一。<br />但是，为什么要分为<a title="持久层（Persistence Layer）" href="http://www.ambysoft.com/essays/persistenceLayer.html">持久层（Persistence Layer）</a> 、<a title="业务逻辑层（Business Logic Layer）" href="http://www.onjava.com/pub/a/onjava/excerpt/bldgjavaent_8/index1.html">业务逻辑层（Business Logic Layer）</a> 和<a title="展现层（Presentation Layer  ）" href="http://en.wikipedia.org/wiki/Presentation_layer">展现层（Presentation Layer ）</a> 3层呢？<br />其实这三层不过就是从三个不同的视角去看这个企业信息系统罢了。从数据的角度看，企业信息系统不外乎就是对数据的存取。从功能的角度看，企业信息系统就是对现实中的业务逻辑操作的信息化抽象而从用户的角度上看，它是一个人机接口，它可以接受输入并且会对所做的输入做出相应的反应。这三层从底向上实现了底层计算机数据和顶层人的业务操作的跨越，一般说来，从概念上讲，所有的企业级应用框架都可以分成这三层，因为这三个视角是客观的。但是这并不保证所有的企业级应用都能保证这三个层之间不发生耦合。<img src ="http://www.blogjava.net/iKingQu/aggbug/36422.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-20 20:50 <a href="http://www.blogjava.net/iKingQu/articles/36422.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Struts 学习起歩问答</title><link>http://www.blogjava.net/iKingQu/articles/36161.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sun, 19 Mar 2006 20:11:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36161.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36161.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36161.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36161.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36161.html</trackback:ping><description><![CDATA[
		<p>1 JSP Framework - Struts介绍 <br />Struts是采用Java Servlet/JavaServer Pages技术，开发Web应用程序的开放源码的framework。 </p>
		<p>
		</p>
		<p>采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架。 </p>
		<p>Struts有如下的主要功能： </p>
		<p>1. 包含一个controller servlet，能将用户的请求发送到相应的Action对象。 </p>
		<p>2. JSP自由tag库，并且在controller servlet中提供关联支持，帮助开发员创建交互式表单应用。 </p>
		<p>3. 提供了一系列实用对象：XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息。 </p>
		<p>Struts是Jakarta项目的一部分，主页在http://jakarta.apache.org/struts. </p>
		<p>Version 0.5的下载地址：http://jakarta.apache.org/builds/jakarta-struts/release/v0.5 </p>
		<p>
				<br />1.1 1、什么是MVC模式。 <br />MVC(Model/View/Controller)模式是国外用得比较多的一种设计模式，好象最早是在Smaltalk中出现。MVC包括三类对象。Model是应用对象，View是它在屏幕上的表示，Controller定义用户界面对用户输入的响应方式。 </p>
		<p>1.2 2、是否所有JSP应用都该采用MVC模式？ <br />不一定所有的JSP应用都该采用MVC模式。但对于大型应用来说，我认为还是该采用MVC模式。不使用MVC模式，用户界面界面设计往往将这些对象混在一起，而MVC则将它们分离以提高灵活性和复用性。 </p>
		<p>1.3 3、Struts中能做XML吗，与Cocoon相比有何优点？ <br />Struts把主要精力放在JSP上了。Cocoon才是专业级的XML Framework。 </p>
		<p>
				<br />2. Struts的安装 <br />2.1 安装Struts需要的软件 </p>
		<p>Java Development Kit - 你需要download和install 1.2(或之后)版本的JDK。下载地址：http://java.sun.com/j2se <br />Servlet Container - 通常的选择是下载Tomcat(至少是3.1版，推荐使用3.2版)。下载地址：http://jakarta.apache.org/tomcat <br />Ant Build System - 如果你通过Struts源码发布包安装，你必须下载1.1或之后版本的ant build system。在你通过Struts来开发你自己的Web应用程序是，我也推荐使用ant来build你的应用。下载地址：http://jakarta.apache.org/ant <br />Servlet API Classes - 为了编译Structs自己，或应用程序使用Struts，你需要一个包含Servlet和JSP API对象的servlet.jar包。大多数Servlet container（例如Tomcat)已经自带了这个文件。否则，你必需下载：http://jakarta.apache.org/builds/jakarta-servletapi <br />XML Parser - Structs需要一个与Java API for XML Parsing(JAXP)规格兼容的XML处理器。我推荐使用Xerces。下载地址：http://xml.apache.org/xerces-j <br />Xalan XSLT Processor - 如果你通过Structs源码发布版来构造你的Structs系统，你必须下载和安装1_2_D01或之后版本的Xalan XSLT处理器(Xerces中已自带Xalan)。这个处理器用于将基于XML的Structs文档转换为Html文档。 <br /></p>
		<p>
				<br />2.2 通过源码构造Structs </p>
		<p>1.下载Structs的源码发布包。 <br />2.设置ANT_HOME环境变量，指向你的Ant目录。 <br />3.设置JAVA_HOME环境变量，指向你的JDK目录。 <br />4.设置SERVLETAPI_HOME环境变量，指向你的Servlet API目录（如果你的CLASSPATH已经包含了servlet.jar，就不需要指定该目录） <br />5.将Structs的源码发布包进行解包。 <br />6.进入Structs目录，运行以下命令： <br />./build.sh dist <br />该命令将创建Struts的二进制发布包，目录在../dist/structs(相对于你的编译目录）。 <br /></p>
		<p>
				<br />2.3 通过Struts的二进制发布包安装Structs </p>
		<p>1.下载Struts的二进制发布版。 <br />2.将Struts的二进制发布版进行解包。(如果你是通过Struts源码构造Struts，build的结果就已经是已解包的Struts)。解包后的Struts包含以下内容： <br />lib/struts.jar - 这个文件包含了Struts的所有Java对象。你需要把它拷贝到你的Web应用的WEB-INF/lib目录。 <br />lib/structs.tld - 这是一个"tag library descriptor"文件，它描述了Struts库的自由tag。需要将它拷贝到你的Web应用的WEB-INF目录。 <br />webapps/struts-documentation.war - 这是一个"web application archive"文件，包含了所有的Struts文档。你可以将它安装到支持Servlet API 2.2或之后版本的servlet container(推荐使用tomcat)中。 <br />webapps/struts-example.war - 这是一个web应用实例，它广泛地演示了Struts的许多功能。你可以将它安装到兼容Servlet2.2或之后版本以及JSP1.1或之后版本规范的servlet容器中(推荐使用tomcat)。 <br />webapps/struts-test.war - 这个web应用包含了Struts支持的许多tag的测试网页，可以作为使用Struts tag的例子。 </p>
		<p>可通过以下的步骤在你自己的应用程序中使用Struts： <br />1.将Struts目录的lib/struts.jar拷贝到web应用的WEB-INF/lib目录。 <br />2.将Struts目录的lib/struts*.tld拷贝到web应用的WEB-INF目录。 <br />3.修改Web应用目录的WEB-INF/web.xml文件，增加一个&lt;servlet&gt;元素来定义controller servlet，增加一个&lt;servlet-mapping&gt;元素来建立URI请求与servlet的对应关系。可以参照Struts例子中的WEB-INF/web.xml文件来了解详细的语法要求。 <br />4.修改Web应用目录的WEB-INF/web.xml文件，使之包含以下的tag库定义： <br />&lt;taglib&gt; <br />&lt;taglib-uri&gt;/WEB-INF/struts.tld&lt;/taglib-uri&gt; <br />&lt;taglib-location&gt;/WEB-INF/struts.tld&lt;/taglib-location&gt; <br />&lt;/taglib&gt; <br />&lt;taglib&gt; <br />&lt;taglib-uri&gt;/WEB-INF/struts-bean.tld&lt;/taglib-uri&gt; <br />&lt;taglib-location&gt;/WEB-INF/struts-bean.tld&lt;/taglib-location&gt; <br />&lt;/taglib&gt; <br />&lt;taglib&gt; <br />&lt;taglib-uri&gt;/WEB-INF/struts-logic.tld&lt;/taglib-uri&gt; <br />&lt;taglib-location&gt;/WEB-INF/struts-logic.tld&lt;/taglib-location&gt; <br />&lt;/taglib&gt; <br />5.创建一个WEB-INF/action.xml文件来定义你的web应用的action映射关系。可以参照Struts例子中的action.xml文件来了解详细的语法要求。 <br />6.在使用Struts tag库的JSP网页中加入以下tag库定义： <br />&lt;@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %&gt; <br />&lt;@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %&gt; <br />&lt;@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %&gt; <br />7.最后，在编译你的web应用的java程序时，不要忘了在CLASSPATH中包含struts.jar文件哟。 <br /></p>
<img src ="http://www.blogjava.net/iKingQu/aggbug/36161.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-20 04:11 <a href="http://www.blogjava.net/iKingQu/articles/36161.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]XDoclet 说明</title><link>http://www.blogjava.net/iKingQu/articles/36067.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sun, 19 Mar 2006 06:57:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/36067.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/36067.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/36067.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/36067.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/36067.html</trackback:ping><description><![CDATA[XDoclet是一个扩展的Javadoc Doclet引擎。它是一种通用的java工具，可以让你创建自己的javadoc @tags进而利用XDoclet中的Templet enging基于这些@tags生成源代码或其他文件（例如xml的deployment descriptors）。XDoclet已经支持一些常见的任务了，例如生成web.xml和ejb-jar.xml等，用户可以创建其他templets和@tags，以增加对其他技术的支持 <br /><br />更宏伟的目标，是让你可以在基于组件的开发工程中可以实现“持续集成”(Continuous Integration)。要点是在你编写每一个组件代码的同时，指定它们的“原数据”(meta-data)，也就是设定每个组件的配布属性(deployment meta-data)。你不必担心这些配布属性会过时，因为你可以接触代码，这些配布属性和代码同时被修改。这样就做到了持续集成，整个过程很自然的就是round-trip了。我们称之为“持续再配置”(Continuous Reconfiguation)。 XDoclet很适合成为Apache-Ant这样的build过程的一部分。 <br /><br />整个系统是可以扩展的。如果需要，你可以为你的特定任务写特别的templet（如支持新的App Server，为Toplink等定义OR Mapping schema, 甚至将servlet当作组件来使用）。XDoclet已经支持一些预先写好的Templet和@tags，例如为EJB关联的东西提供的，为自动生成web.xml提供的等等。 <br /><br />XDoclet基于以下几个部分： <br /><br /><br />Apache Ant Task: 和就是这种任务的例子。在你的build.xml文件中，在编译代码的taget之前定义。 <br />task的嵌套元素: 这是定义对于源代码需要执行的子任务的地方。例如 和。每一个子任务都可以单独配置。 <br />Template文件: 子任务可以基于template文件生成输出。template可以是包含类似于 的xml元素的文本文件。Template文件类似于JSP文件，类似于JSP tags, 实际的实现位于子任务类中，一个基类定义了一些共通的tag <br />特别的JavaDoc @tags: 通过使用特别的JavaDoc @tags, 给每个组件定义设定。例如在SimpleServlet.java中定义一个 @web:servlet name="The Simple Servlet"，让 子任务知道SimpleServlet.java包含一个servlet的定义，这样就可以利用@web:servlet tag中的信息生成相应的web.xml描述。 <br />The mege system: 为了避免过多的tags， XDoclet同时也可以使用一种merge system。例如，为了避免在EJBean源代码中写@jboss:table-name account，可以定义一个 jaws-db-setting-Accoutn.xml文件，这个文件包含实际的XML代码，可以被子任务合并到最终生成的jaws.xml文件中 <br /><br />实际的例子，可以参见sample code和sample build.xml文件 <br /><br />XDoclet是EJBDoclet的后继者，而EJBDoclet是由Rickard Oberg -- 世界上最好的程序员之一，开放源代码的先锋 -- 发起的项目，在这个项目的开发过程中，逐渐发现不仅仅可以用于EJB，于是开始了一个新的项目，一开始就以一个更宽广的应用作为目标。 <br /><br />You can download it from http://sourceforge.net/projects/xdoclet. <img src ="http://www.blogjava.net/iKingQu/aggbug/36067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-19 14:57 <a href="http://www.blogjava.net/iKingQu/articles/36067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]解决web开发中的中文问题</title><link>http://www.blogjava.net/iKingQu/articles/35507.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Wed, 15 Mar 2006 16:49:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/35507.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/35507.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/35507.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/35507.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/35507.html</trackback:ping><description><![CDATA[
		<p>
				<a href="/rickhunter/articles/33571.html">原文地址</a>
				<br />
				<br />这段时间经常看到有人问到web开发中怎么中文总是?号。原因其实很简单，因为大家大多用的是tomcat服务器，而tomcat服务器的默认编码为 iso-8859-1(西欧字符)。就是因为iso-8859-1(西欧字符)编码造成了我们经常看到？号。关于iso-8859-1(西欧字符)更多知识请看<a href="http://www.regexlab.com/zh/encoding.htm#un" name="main">《字节，字符和编码</a><a href="http://www.regexlab.com/zh/encoding.htm#un">》</a>这篇文章。<br /><br />方法一：最简单也是用的最多的方法。<br />&lt;%@ page language="java" pageEncoding="GBK" %&gt;<br />或者&lt;%@ page contenttype="text/html;charset=gbk";&gt;这里可以用gb2312或者gbk，只是gbk比gb2312支持跟多的字符。<br /><br />这个方法用于jsp页面中的中文显示。<br /><br />方法二：使用过滤器。<br />过滤器使用主要针对表单提交，插入数据库的数据都是？号。这也是应为tomcat不按request所指定的编码进行编码，还是自作主张的采用默认编码方式iso-8859-1编码。<br />编写一个SetCharacterEncodingFilter类。<br />import java.io.IOException;<br /><br />import javax.servlet.Filter;<br />import javax.servlet.FilterChain;<br />import javax.servlet.FilterConfig;<br />import javax.servlet.ServletException;<br />import javax.servlet.ServletRequest;<br />import javax.servlet.ServletResponse;<br /><br />public class SetCharacterEncodingFilter implements Filter {<br />protected String encoding = null;<br />protected FilterConfig filterConfig = null;<br />protected boolean ignore = true;<br /><br />public void init(FilterConfig filterConfig) throws ServletException {<br />this.filterConfig=filterConfig;<br />this.encoding=filterConfig.getInitParameter("encoding");<br />String value=filterConfig.getInitParameter("ignore");<br />if(value==null)<br />this.ignore=true;<br />else if(value.equalsIgnoreCase("true"))<br />this.ignore=true;<br />else<br />this.ignore=false;<br />}<br /><br />public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {<br />// TODO 自动生成方法存根<br />if (ignore || (request.getCharacterEncoding() == null)) {<br />String encoding = selectEncoding(request);<br />if (encoding != null)<br />request.setCharacterEncoding(encoding);<br />}<br />chain.doFilter(request, response);<br />}<br /><br />public void destroy() {<br />// TODO 自动生成方法存根<br />this.encoding = null;<br />this.filterConfig = null;<br />}<br /><br />protected String selectEncoding(ServletRequest request) {<br />return (this.encoding);<br />}<br />}<br /><br />然后再web.xml加上<br />&lt;!-- Set Character Encoding--&gt;<br />&lt;filter&gt;<br />&lt;filter-name&gt;Set Character Encoding&lt;/filter-name&gt;<br />&lt;filter-class&gt;com.struts.common.SetCharacterEncodingFilter&lt;/filter-class&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;encoding&lt;/param-name&gt;<br />&lt;param-value&gt;UTF-8&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;/filter&gt;<br /><br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Set Character Encoding&lt;/filter-name&gt;<br />&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />&lt;/filter-mapping&gt;<br />&lt;!-- Set Character Encoding--&gt;<br /><br />使用过滤器的好处很多，特别是项目之中。<br />而且在使用国际化时就更有用了，只要在页面指定&lt;%@ page language="java" pageEncoding="UTF-8" %&gt;，服务器就会根据本地Locale来显示正确的字符集。<br /><br />所以我特别推荐使用过滤器。<br /><br />方法三：修改tomcat的server.xml文件中URIEncoding。<br />&lt;Connector<br />debug="0"<br />acceptCount="100"<br />connectionTimeout="20000"<br />disableUploadTimeout="true"<br />port="80"<br />redirectPort="8443"<br />enableLookups="false"<br />minSpareThreads="25"<br />maxSpareThreads="75"<br />maxThreads="150"<br />maxPostSize="0"<br /><font color="#0000ff"><b>URIEncoding="GBK"</b></font><br />&gt;<br />&lt;/Connector&gt;<br />这个方法主要针对从url中获取字符串的问题。<br />在tomcat5.0及以上版本，post和get方法在处理编码时有所不同。如果你在url中获取中文就会出现？号。但在tomcat4.1版本没有问题，因为tomcat4.1的post和get方法在处理编码时是一样的。 </p>
<img src ="http://www.blogjava.net/iKingQu/aggbug/35507.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-16 00:49 <a href="http://www.blogjava.net/iKingQu/articles/35507.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]所有weblogic版本下载 </title><link>http://www.blogjava.net/iKingQu/articles/35157.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 13 Mar 2006 18:53:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/35157.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/35157.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/35157.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/35157.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/35157.html</trackback:ping><description><![CDATA[<DIV class=postText>直接下载wls的地址，可以用flashget等多线程工具来下：<BR>带_zh_CN后缀名的是中文版的。<BR>windows版：<BR>http://download2.bea.com/pub/platform/90/server900_win32.exe<BR>http://download2.bea.com/pub/platform/90/server900_zh_CN_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform815_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform814_zh_CN_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform812_zh_CN_win32.exe<BR>linux版：<BR>http://download2.bea.com/pub/platform/81/platform815_linux32.bin<BR>http://download2.bea.com/pub/platform/90/server900_linux32.bin<BR>hp_ux版&nbsp;&nbsp;http://download2.bea.com/pub/platform/90/server900_zh_CN_hpux32.bin<BR>Sun&nbsp;Solaris(8\9\10)版&nbsp;http://download2.bea.com/pub/platform/90/server900_zh_CN_solaris32.bin<BR><BR><BR>８.15中文版<BR>下载地址：<BR>windows版：<BR>http://download2.bea.com/pub/platform/81/platform815_zh_CN_win32.exe<BR>hp_unix版：<BR>http://download2.bea.com/pub/platform/81/platform815_zh_CN_hpux32.bin<BR>Linux版：（暂无）<BR><BR>＝＝＝＝＝＝＝＝＝＝＝＝＝＝要注册的下载＝＝＝＝＝＝＝＝＝＝<BR>1.在哪里下得着中文版的<BR>http://commerce.bea.com/index.jsp<BR>进去后，点击<BR>International<BR>Versions<BR>然后就会到<BR>http://commerce.bea.com/products/intl_versions.jsp<BR>再选简体中文就OK了。<BR>2.下载所有英文版本地址：<BR>http://commerce.bea.com/showallversions.jsp?family=WLP<BR>3.下载所有中文版本地址：<BR>http://commerce.bea.com/showallversions.jsp?family=WLPCH<BR><BR><BR><BR><BR>--------------------------------------------------------------------------------<BR>SE，BEA&nbsp;Systems<BR>EMail:&nbsp;nizhigang2000@gmail.com<BR>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<BR>WLS:&nbsp;http://dev2dev.bea.com.cn/bbs/forum.jspa?forumID=81&amp;start=0<BR>Workshop:&nbsp;http://dev2dev.bea.com.cn/bbs/forum.jspa?forumID=103&amp;start=0<BR>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<BR>BEA新闻组：http://forums.bea.com/bea/index.jspa<BR>BEA技术支持热线：800-810-2327<BR>BEA技术支持网站：http://support.bea.com<BR>BEA产品英文文档：http://edocs.bea.com<BR>BEA产品中文文档：http://dev2dev.bea.com.cn/download/school/workshop/WorkshopCNHelp/doc/zh/core/index.html<BR><BR>直接下载wls的地址，可以用flashget等多线程工具来下：<BR>windows版：<BR>http://download2.bea.com/pub/platform/90/server900_win32.exe<BR>http://download2.bea.com/pub/platform/90/server900_zh_CN_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform815_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform814_zh_CN_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform812_zh_CN_win32.exe<BR>linux版：<BR>http://download2.bea.com/pub/platform/81/platform815_linux32.bin<BR>http://download2.bea.com/pub/platform/90/server900_linux32.bin<BR><BR>８.15中文版<BR>下载地址：<BR>windows版：<BR>http://download2.bea.com/pub/platform/81/platform815_zh_CN_win32.exe<BR>hp_unix版：<BR>http://download2.bea.com/pub/platform/81/platform815_zh_CN_hpux32.bin<BR>Linux版：（暂无）<BR>详细请访问：<BR>http://commerce.bea.com/showallversions.jsp?family=WLPCH<BR><BR><BR>hp_ux版&nbsp;&nbsp;http://download2.bea.com/pub/platform/90/server900_zh_CN_hpux32.bin<BR>Sun&nbsp;Solaris(8\9\10)版&nbsp;http://download2.bea.com/pub/platform/90/server900_zh_CN_solaris32.bin<BR><BR><BR>这些都不用注册可以直接下载呀，不信你整一个试试，<BR>如果是注册成功了，那肯定是可以下载，怎么会骗人呢？<BR>直接下载wls的地址，可以用flashget等多线程工具来下：<BR>windows版：<BR>http://download2.bea.com/pub/platform/90/server900_win32.exe<BR>http://download2.bea.com/pub/platform/90/server900_zh_CN_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform815_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform814_zh_CN_win32.exe<BR>http://download2.bea.com/pub/platform/81/platform812_zh_CN_win32.exe<BR>linux版：<BR>http://download2.bea.com/pub/platform/81/platform815_linux32.bin<BR>http://download2.bea.com/pub/platform/90/server900_linux32.bin<BR>只贴这么多了，不知道大家有没有从上面找到下载地址的规律，呵呵<BR><BR>
<P id=TBPingURL>Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=591298</P></DIV><img src ="http://www.blogjava.net/iKingQu/aggbug/35157.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-14 02:53 <a href="http://www.blogjava.net/iKingQu/articles/35157.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]初识HTTP协议</title><link>http://www.blogjava.net/iKingQu/articles/34953.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sun, 12 Mar 2006 17:36:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/34953.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/34953.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/34953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/34953.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/34953.html</trackback:ping><description><![CDATA[<P style="TEXT-INDENT: 2em">当我们想浏览一个网站的时候，只要在浏览器的地址栏里输入网站的地址就可以了，例如：www.microsoft.com，但是在浏览器的地址栏里面出现的却是：http://www.microsoft.com，你知道为什么会多出一个“http”吗？</P>
<P style="TEXT-INDENT: 2em">一、HTTP协议是什么</P>
<P style="TEXT-INDENT: 2em">我们在浏览器的地址栏里输入的网站地址叫做URL(UniformResourceLocator，统一资源定位符)。就像每家每户都有一个门牌地址一样，每个网页也都有一个Internet地址。当你在浏览器的地址框中输入一个URL或是单击一个超级链接时，URL就确定了要浏览的地址。浏览器通过超文本传输协议(HTTP)，将Web服务器上站点的网页代码提取出来，并翻译成漂亮的网页。因此，在我们认识HTTP之前，有必要先弄清楚URL的组成,例如：http://www.microsoft.com/china/index.htm。它的含义如下：</P>
<P style="TEXT-INDENT: 2em">1.http://：代表超文本传输协议，通知microsoft.com服务器显示Web页，通常不用输入；</P>
<P style="TEXT-INDENT: 2em">2.www：代表一个Web(万维网)服务器；</P>
<P style="TEXT-INDENT: 2em">3.Microsoft.com/：这是装有网页的服务器的域名，或站点服务器的名称；</P>
<P style="TEXT-INDENT: 2em">4.China/：为该服务器上的子目录，就好像我们的文件夹；</P>
<P style="TEXT-INDENT: 2em">5.Index.htm：index.htm是文件夹中的一个HTML文件(网页)。</P>
<P style="TEXT-INDENT: 2em">我们知道，Internet的基本协议是TCP/IP协议，然而在TCP/IP模型最上层的是应用层(Applicationlayer)，它包含所有高层的协议。高层协议有：文件传输协议FTP、电子邮件传输协议SMTP、域名系统服务DNS、网络新闻传输协议NNTP和HTTP协议等。</P>
<P style="TEXT-INDENT: 2em">HTTP协议(HypertextTransferProtocol，超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效，使网络传输减少。它不仅保证计算机正确快速地传输超文本文档，还确定传输文档中的哪一部分，以及哪部分内容首先显示(如文本先于图形)等。这就是你为什么在浏览器中看到的网页地址都是以“http://”开头的原因。</P>
<P style="TEXT-INDENT: 2em">自WWW诞生以来，一个多姿多彩的资讯和虚拟的世界便出现在我们眼前，可是我们怎么能够更加容易地找到我们需要的资讯呢？当决定使用超文本作为WWW文档的标准格式后，于是在1990年，<A href="http://tech.163.com/discover/"><FONT color=#0066cc>科学</FONT></A>家们立即制定了能够快速查找这些超文本文档的协议，即HTTP协议。经过几年的使用与发展，得到不断的完善和扩展，目前在WWW中使用的是HTTP/1.0的第六版。</P>
<P style="TEXT-INDENT: 2em">二、HTTP是怎样工作的</P>
<P style="TEXT-INDENT: 2em">既然我们明白了URL的构成，那么HTTP是怎么工作呢？我们接下来就要讨论这个问题。</P>
<P style="TEXT-INDENT: 2em">由于HTTP协议是基于请求/响应范式的(相当于客户机/服务器)。一个客户机与服务器建立连接后，发送一个请求给服务器，请求方式的格式为：统一资源标识符(URL)、协议版本号，后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后，给予相应的响应信息，其格式为一个状态行，包括信息的协议版本号、一个成功或错误的代码，后边是MIME信息包括服务器信息、实体信息和可能的内容。</P>
<P style="TEXT-INDENT: 2em">许多HTTP通讯是由一个用户代理初始化的并且包括一个申请在源服务器上资源的请求。最简单的情况可能是在用户代理和服务器之间通过一个单独的连接来完成。在Internet上，HTTP通讯通常发生在TCP/IP连接之上。缺省端口是TCP80，但其它的端口也是可用的。但这并不预示着HTTP协议在Internet或其它网络的其它协议之上才能完成。HTTP只预示着一个可靠的传输。</P>
<P style="TEXT-INDENT: 2em">这个过程就好像我们打电话订货一样，我们可以打电话给商家，告诉他我们需要什么规格的商品，然后商家再告诉我们什么商品有货，什么商品缺货。这些，我们是通过电话线用电话联系(HTTP是通过TCP/IP)，当然我们也可以通过传真，只要商家那边也有传真。</P>
<P style="TEXT-INDENT: 2em">以上简要介绍了HTTP协议的宏观运作方式，下面介绍一下HTTP协议的内部操作过程。</P>
<P style="TEXT-INDENT: 2em">在WWW中，“客户”与“服务器”是一个相对的概念，只存在于一个特定的连接期间，即在某个连接中的客户在另一个连接中可能作为服务器。基于HTTP协议的客户/服务器模式的信息交换过程，它分四个过程：建立连接、发送请求信息、发送响应信息、关闭连接。这就好像上面的例子，我们电话订货的全过程。</P>
<P style="TEXT-INDENT: 2em">其实简单说就是任何服务器除了包括HTML文件以外，还有一个HTTP驻留程序，用于响应用户请求。你的浏览器是HTTP客户，向服务器发送请求，当浏览器中输入了一个开始文件或点击了一个超级链接时，浏览器就向服务器发送了HTTP请求，此请求被送往由IP地址指定的URL。驻留程序接收到请求，在进行必要的操作后回送所要求的文件。在这一过程中，在网络上发送和接收的数据已经被分成一个或多个数据包(packet)，每个数据包包括：要传送的数据；控制信息，即告诉网络怎样处理数据包。TCP/IP决定了每个数据包的格式。如果事先不告诉你，你可能不会知道信息被分成用于传输和再重新组合起来的许多小块。</P>
<P style="TEXT-INDENT: 2em">也就是说商家除了拥有商品之外，它也有一个职员在接听你的电话，当你打电话的时候，你的声音转换成各种复杂的数据，通过电话线传输到对方的电话机，对方的电话机又把各种复杂的数据转换成声音，使得对方商家的职员能够明白你的请求。这个过程你不需要明白声音是怎么转换成复杂的数据的。 </P><img src ="http://www.blogjava.net/iKingQu/aggbug/34953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-13 01:36 <a href="http://www.blogjava.net/iKingQu/articles/34953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]WebLogic的初步研究</title><link>http://www.blogjava.net/iKingQu/articles/34948.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Sun, 12 Mar 2006 16:17:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/34948.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/34948.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/34948.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/34948.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/34948.html</trackback:ping><description><![CDATA[<STRONG><FONT color=#ac0000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;简介</FONT></STRONG> 
<P>　　WebLogic 是一套基于JAVA功能强大的电子商务套件，提供了许多功能强大的中间件以方便编程人员编写的JSP、SERVLET 等电子商务应用，可以为企业提供一个完整的商务应用解决方案。对于开发人员 WebLogic 可以在 www.bea.com 免费下载一套完整的 WebLogic，并得到一个限制了 IP 的license，用于学习和开发基于这个套件的代码。而要是需要正式的投入使用的话，那么就必须支付一定的费用获取没限制的license。由于这个套件基于这种发布方式，对于一般网站开发人员可以很轻易地得到 WebLogic 用于学习开发，当然投入使用是另一回事。</P>
<P>　　我获得的 WebLogic5.10是两个大大的zip文件，一个是WebLogic程序包，一个是资料文档。因为是基于JAVA，虽然在下载时有区分操作系统，但是我得到的那套经过实践发现在WINNT和LINUX都可以运行，下面主要是以LINUX的为例，WINNT的安装方法也差不多。</P>
<P>　　<B><FONT color=#ac000>安装篇 <BR></FONT></B><BR>　<B>　安装前准备：</B></P>
<P>　　在安装前，用户必须获得一套对应于用户的操作系统的JDK（在 www.sun.com 免费下载），安装好后把WebLogic5.10的压缩包解开，建议放在根目录上，这样会省去很多修改设置的麻烦，在linux下可以解在其他目录，然后在根目录再做一个硬连接也可以。</P>
<P>　　我的安装的文件目录是</P>
<TABLE cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD>/usr/local/jdk1.2/<BR>/usr/local/weblogic/<BR>ln -s / /usr/local/weblogic/</TD></TR></TBODY></TABLE>
<P>　　<B>配置weblogic：</B></P>
<P>　　启动weblogic需要执行两个脚本文件：</P>
<P>linux：setEnv.sh和startWebLogic.sh</P>
<P>WINNT对应的是：setEnv.cmd和startWebLogic.cmd</P>
<P>　　1、weblogic.properties</P>
<P>　　打开/usr/local/weblogic/的 weblogic.properties 文件，找到这一行 weblogic.password.system=<BR>这是设置管理员密码用的，这个设置项不能为空，所以必须设置一个可靠的管理员密码。<BR><BR>　　例如：weblogic.password.system=sdfjkdshfds</P>
<P>　　设置运行JSP：</P>
<TABLE cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD># WEBLOGIC JSP PROPERTIES<BR># ------------------------------------------------<BR># Sets up automatic page compilation for JSP. Adjust init args for<BR># directory locations and uncomment to use.<BR>#weblogic.httpd.register.*.jsp=\<BR>#weblogic.servlet.JSPServlet<BR>#weblogic.httpd.initArgs.*.jsp=\<BR>#pageCheckSeconds=1,\<BR>#compileCommand=c:/jdk1.2.1/bin/javac.exe, \<BR>#workingDir=/weblogic/myserver/classfiles, \<BR>#verbose=true</TD></TR></TBODY></TABLE>
<P>　　把那些注释删去，即改为</P>
<TABLE cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD># WEBLOGIC JSP PROPERTIES<BR># ------------------------------------------------<BR># Sets up automatic page compilation for JSP. Adjust init args for<BR># directory locations and uncomment to use.<BR>weblogic.httpd.register.*.jsp=\<BR>weblogic.servlet.JSPServlet<BR>weblogic.httpd.initArgs.*.jsp=\<BR>pageCheckSeconds=1,\<BR>compileCommand=c:/jdk1.2.1/bin/javac.exe, \<BR>workingDir=/weblogic/myserver/classfiles, \<BR>verbose=true</TD></TR></TBODY></TABLE>
<P>　　 要注意的是还要配置好这一行：<BR></P>
<TABLE cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD>compileCommand=/usr/local/jdk1.2/bin/javac, \</TD></TR></TBODY></TABLE>
<P>　　这是JDK的JAVA编译器的路径。</P>
<P>　　2、setEnv.sh</P>
<P>　　打开/weblogic/setEnv.sh，找到这一行<BR><BR>　　　JAVA_HOME=/usr/java<BR><BR>　　改为<BR><BR>　　　JAVA_HOME=/usr/local/jdk1.2/</P>
<P>　　3、 startWebLogic.sh</P>
<P>　　找到一个全是大写的 "LINUX" 字符串，改为 "Linux"，很奇怪是为何要这样是吗？这是因为启动时，脚本文件调用了uname 指令来得到系统的名字，再与"LINUX" 字符串比较确认是否是linux系统，但是uname 指令来返回的系统的名字是Linux，所以我们要改一下，这应该是这个启动脚本的一个小小的BUG，WINT就不用那么麻烦了。</P>
<P>　　<B>运行weblogic：</B></P>
<P>　　经过简单的配置就试运行了。</P>
<P>　　在目录/weblogic/下执行</P>
<P>　　　. ./setEnv.sh （大家请留意，我这里有两个 ".",因为我们需要在当前的shell下执行这个脚本 ）</P>
<P>　　　./startWebLogic.sh</P>
<P>　　当看到成功启动 WebLogic 的信息时，说明启动成功了。</P>
<P>　　<B>服务器简单的测试：</B></P>
<P>　　WebLogic 默认的WEB端口为7001，我们可以在打开一个浏览器输入地址<BR><BR>　　　http://localhost:7001/<BR><BR>　　测试是否能连接得上。</P>
<P>　　<B>Servlet的测试</B></P>
<P>　　如果能连得上得话，那么就可以进行下一步的Servlet的测试，在浏览器输入地址<BR><BR>　　　http://localhost:7001/helloWorld<BR><BR>　　这个就是WebLogic Servlet的演示（至于怎样安装 Servlet请看下文）</P>
<P>　　<B>JSP的测试</B></P>
<P>　　在目录 /weblogic/myserver/public_html/下建立一个名为test.jsp的文件</P>
<P>　　test.jsp</P>
<TABLE cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD>
<P>＜%</P>
<P>Out.print("test JSP");</P>
<P>%＞;</P></TD></TR></TBODY></TABLE>
<P>　　在浏览器输入地址<BR><BR>　　http://localhost:7001/test.jsp<BR><BR>　　测试能否看到正确的输出"test JSP"的信息。</P>
<P>　<B><FONT color=#ac000>　结构篇</FONT></B></P>
<P>　　要学习好一套系统首先要了解它的结构，本文详细的介绍 WebLogic 的一些结构和特点：<BR></P>
<P>　　WebLogic的大部分配置是在 weblogic.properties 里完成的，只要仔细的研究这个文件就可以清楚得知关于 WebLogic 的一些结构和特点，下面就对 weblogic.properties 文件里的一些配置项作一些说明：</P>
<P>　　weblogic.httpd.documentRoot=public_html/<BR><BR>　　这就是WebLogic 的WEB 服务器的根目录，即是目录/weblogic/myserver/public_html/　</P>
<P>　　　weblogic.password.system=sdfjkdshfds<BR><BR>　　这个前文已经提到，是设置管理员密码。</P>
<P>　　　weblogic.system.listenPort=7001<BR><BR>　　这是设置 WebLogic 的 WEB 服务器端口。</P>
<P>　　　weblogic.httpd.servlet.classpath=/weblogic/myserver/servletclasses<BR><BR>　　设置Servlet存放的路径</P>
<P>　　<B>关于Servlet</B></P>
<P>　　出于安全的目的，在 WebLogic 下运行的 WebLogic 必须在 weblogic.properties 里登记后才能运行，例如上文的提到Servlet http://localhost:7001/helloWorld，它在weblogic.properties 里的登记项是<BR></P>
<TABLE cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD>　　　weblogic.httpd.register.helloWorld=examples.servlets.HelloWorldServlet</TD></TR></TBODY></TABLE>
<P>　　实际上，这个 Servlet 的实际路径是<BR></P>
<TABLE cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD>　　　/weblogic/myserver/servletclasses/examples/servlets/HelloWorldServlet.class </TD></TR></TBODY></TABLE>
<P>　　对照一下weblogic.properties里的登记项和HelloWorldServlet.class文件的路径，应该不难找出其登记Servlet的规律吧。</P>
<P>　　在weblogic.properties里有一下几个Servlet的登记项：</P>
<TABLE cellPadding=0 width="100%" bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD>weblogic.httpd.register.AdminEvents=admin.AdminEvents<BR>weblogic.httpd.register.AdminClients=admin.AdminClients weblogic.httpd.register.AdminConnections=<BR>admin.AdminConnections weblogic.httpd.register.AdminJDBC=admin.AdminJDBC<BR>weblogic.httpd.register.AdminLicense=admin.AdminLicense<BR>weblogic.httpd.register.AdminMain=admin.AdminMain<BR>weblogic.httpd.register.AdminProps=admin.AdminProps<BR>weblogic.httpd.register.AdminRealm=admin.AdminRealm<BR>weblogic.httpd.register.AdminThreads=admin.AdminThreads weblogic.httpd.register.AdminVersion=admin.AdminVersion</TD></TR></TBODY></TABLE>
<P>　　这就是管理员管理 WebLogic 用的Servlet，通过URL访问http://localhost:7001/AdminMain，在弹出的身份验证对话框了输入 system 和在 weblogic.password.system= 设置的密码，就可以进入 WebLogic 的Web管理界面进行管理。</P><img src ="http://www.blogjava.net/iKingQu/aggbug/34948.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-13 00:17 <a href="http://www.blogjava.net/iKingQu/articles/34948.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Hibernate入门</title><link>http://www.blogjava.net/iKingQu/articles/34571.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Thu, 09 Mar 2006 15:43:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/34571.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/34571.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/34571.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/34571.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/34571.html</trackback:ping><description><![CDATA[也许你听说过Hibernate的大名，但可能一直不了解它，也许你一直渴望使用它进行开发，那么本文正是你所需要的！在本文中，我向大家重点介绍Hibernate的核心API调用库，并讲解一下它的基本配置。<br /><br />　　看完本文后，我相信你对什么是ORM（对像/关系映射）以及它的优点会有一个深刻的认识，我们先通过一个简单的例子开始来展现它的威力。<br /><br />　　正如一些传统的经典计算机文章大都会通过一个“hello,world”的例子开始讲解一样，我们也不例外，我们也将从一个相对简单的例子来阐述Hibernate的开发方法，但如果要真正阐述Hibernate的一些重要思想，仅仅靠在屏幕上打印一些字符是远远不够的，在我们的示例程序中，我们将创建一些对象，并将其保存在数据库中，然后对它们进行更新和查询。 
<p></p><p></p><table cellspacing="0" cellpadding="0" width="590" align="center" border="0"><tbody><tr><td><span class="f14">　　<strong>“Hello World”</strong><br /><br />　　Hibernate应用程序定义了一些持久类，并且定义了这些类与数据库表格的映射关系。在我们这个“Hello world”示例程序中包含了一个类和一个映射文件。让我们看看这个简单的持久类包含有一些什么？映射文件是怎样定义的？另外，我们该怎样用Hibernate来操作这个持久类。<br /><br />　　我们这个简单示例程序的目的是将一些持久类存储在数据库中，然后从数据库取出来，并将其信息正文显示给用户。其中Message正是一个简单的持久类：，它包含我们要显示的信息，其源代码如下：<br /><br />　　列表1　Message.Java　一个简单的持久类<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>package hello;<br />public class Message {<br />　private Long id;<br />　private String text;<br />　private Message nextMessage;<br />　private Message() {}<br />　public Message(String text) {<br />　　this.text = text;<br />　}<br />　public Long getId() {<br />　　return id;<br />　}<br />　private void setId(Long id) {<br />　　this.id = id;<br />　}<br />　public String getText() {<br />　　return text; <br />　}<br />　public void setText(String text) {<br />　　this.text = text;<br />　}<br />　public Message getNextMessage() {<br />　　return nextMessage;<br />　}<br />　public void setNextMessage(Message nextMessage) {<br />　　this.nextMessage = nextMessage;<br />　}<br />} </td></tr></tbody></table><br />　　Message类有三个属性：Message的id 、消息正文、以及一个指向下一条消息的指针。其中id属性让我们的应用程序能够唯一的识别这条消息，通常它等同于数据库中的主键，如果多个Message类的实例对象拥有相同的id，那它们代表数据库某个表的同一个记录。在这里我们选择了长整型作为我们的id值，但这不是必需的。Hibernate允许我们使用任意的类型来作为对象的id值，在后面我们会对此作详细描述。<br /><br />　　你可能注意到Message类的代码类似于JavaBean的代码风格，并且它有一个没有参数的构造函数，在我们以后的代码中我将继续使用这种风格来编写持久类的代码。<br /><br />　　Hibernate会自动管理Message类的实例，并通过内部机制使其持久化，但实际上Message对象并没有实现任何关于Hibernate的类或接口，因此我们也可以将它作为一个普通的Java类来使用：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>Message message = new Message("Hello World");<br />System.out.println( message.getText() ); </td></tr></tbody></table><br />　　以上这段代码正是我们所期望的结果：它打印“hello world”到屏幕上。但这并不是我们的最终目标；实际上Hibernate与诸如EJB容器这样的环境在持久层实现的方式上有很大的不同。我们的持久类(Message类)可以用在与容器无关的环境中，不像EJB必须要有EJB容器才能执行。为了能更清楚地表现这点，以下代码将我们的一个新消息保存到数据库中去：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>Session session = getSessionFactory().openSession();<br />Transaction tx = session.beginTransaction();<br />Message message = new Message("Hello World");<br />session.save(message);<br />tx.commit();<br />session.close(); </td></tr></tbody></table><br />　　以上这段代码调用了Hibernate的Session和Transaction接口（关于getSessionFactory()方法我们将会马上提到）。它相当于我们执行了以下SQL语句：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)<br />values (1, 'Hello World', null) </td></tr></tbody></table><br />　　在以上的SQL语句中，MESSAGE_ID字段到底被初始化成了什么值呢？由于我们并没有在先前的代码中为message对象的id属性赋与初始值，那它是否为null呢？实际上Hibernate对id属性作了特殊处理：由于它是一个对象的唯一标识，因此当我们进行save()调用时，Hibernate会为它自动赋予一个唯一的值（我们将在后面内容中讲述它是如何生成这个值的）。<br /><br />　　我们假设你已经在数据库中创建了一个名为MESSAGE的表，那么既然前面这段代码让我们将Message对象存入了数据库中，那么现在我们就要将它们一一取出来。下面这段代码将按照字母顺序，将数据库中的所有Message对象取出来，并将它们的消息正文打印到屏幕上：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>Session newSession = getSessionFactory().openSession();<br />Transaction newTransaction = newSession.beginTransaction();<br />List messages =newSession.find("from Message as m order by m.text asc");<br />System.out.println( messages.size() + " message(s) found:" );<br />for ( Iterator iter = messages.iterator(); iter.hasNext(); ) {<br />　Message message = (Message) iter.next();<br />　System.out.println( message.getText() );<br />}<br />newTransaction.commit();<br />newSession.close(); </td></tr></tbody></table><br />　　在以上这段代码中，你可能被find()方法的这个参数困扰着："from Message as m order by m.text asc"，其实它是Hibernate自己定义的查询语言，全称叫Hibernate Query Language(HQL)。通俗地讲HQL与SQL的关系差不多就是方言与普通话之间的关系，咋一看，你会觉得它有点类似于SQL语句。其实在find()调用时，Hibernate会将这段HQL语言翻译成如下的SQL语句：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID<br />from MESSAGES m<br />order by m.MESSAGE_TEXT asc </td></tr></tbody></table><br />　　以下就是运行结果： <br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>1 message(s) found:<br />Hello World </td></tr></tbody></table><br />　　如果你以前没有ORM（对象－关系映射）的开发经验，那你可能想在代码的某个地方去寻找这段SQL语句，但在Hibernate中你可能会失望：它根本不存在！所有就SQL语句都是Hibernate动态生成的。 <br /><br />　　也许你会觉得还缺点什么，对！仅凭以上代码Hibernate是无法将我们的Message类持久化的。我们还需要一些更多的信息，这就是映射定义表！这个表在Hibernate中是以XML格式来体现的，它定义了Message类的属性是怎样与数据库中的MESSAGES表的字段进行一一对应的，列表2是这个示例程序的映射配置文件清单：<br /><br />　　列表2：示例程序的对象－关系映射表 <br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>＜?xml version="1.0"?＞<br />＜!DOCTYPE hibernate-mapping PUBLIC<br />"-//Hibernate/Hibernate Mapping DTD//EN"<br />"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"＞<br />＜hibernate-mapping＞<br />＜class name="hello.Message" table="MESSAGES"＞<br />　＜id name="id" column="MESSAGE_ID"＞<br />　　＜generator class="increment"/＞<br />　＜/id＞<br />　＜property name="text" column="MESSAGE_TEXT"/＞<br />　＜many-to-one name="nextMessage" cascade="all" column="NEXT_MESSAGE_ID"/＞<br />＜/class＞<br />＜/hibernate-mapping＞ </td></tr></tbody></table><br />　　以上这个文档告诉Hibernate怎样将Message类映射到MESSAGES表中，其中Message类的id属性与表的MESSAGE_ID字段对应，text属性与表的MESSAGE_TEXT字段对应，nextMessage属性是一个多对一的关系，它与表中的NEXT_MESSAGE_ID相对应。 <br /><br />　　相对于有些开源项目来说，Hibernate的配置文件其实是很容易理解的。你可以轻松地修改与维护它。只要你定义好了持久类与数据库中表字段的对应关系就行了，Hibernate会自动帮你生成SQL语句来对Message对象进行插入、更新、删除、查找工作，你可以不写一句SQL语句，甚至不需要懂得SQL语言！<br /><br />　　现在让我们做一个新的试验，我们先取出第一个Message对象，然后修改它的消息正文，最后我们再生成一个新的Message对象，并将它作为第一个Message对象的下一条消息，其代码如下：<br /><br />　　列表3　更新一条消息<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>Session session = getSessionFactory().openSession();<br />Transaction tx = session.beginTransaction();<br />// 1 is the generated id of the first message<br />Message message =(Message) session.load( Message.class, new Long(1) );<br />message.setText("Greetings Earthling");<br />Message nextMessage = new Message("Take me to your leader (please)");<br />message.setNextMessage( nextMessage );<br />tx.commit();<br />session.close(); </td></tr></tbody></table><br />　　以上这段代码在调用时，Hibernate内部自动生成如下的SQL语句：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID<br />from MESSAGES m<br />where m.MESSAGE_ID = 1<br /><br />insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)<br />values (2, 'Take me to your leader (please)', null)<br /><br />update MESSAGES<br />set MESSAGE_TEXT = 'Greetings Earthling', NEXT_MESSAGE_ID = 2<br />where MESSAGE_ID = 1 </td></tr></tbody></table><br />　　当第一个Message对象的text属性和nextMessage被程序修改时，请注意Hibernate是如何检测到这种变化，并如何在数据库中自动对它更新的。这实际上是Hibernate的一个很有价值的特色，我们把它称为“自动脏数据检测”，Hibernate的这个特色使得当我们修改一个持久对象的属性后，不必显式地通知Hibernate去将它在数据库中进行更新。同样的，当第一个Message对象调用setNextMessage()方法将第二个Message对象作为它的下一条消息的引用时，第二条消息会无需调用save()方法，便可以自动地保存在数据库中。这种特色被称为“级联保存”，它也免去了我们显式地对第二个Message对象调用save()方法之苦。<br /><br />　　如果我们再运行先前的那段将数据库中所有的Message对象都打印出来的代码，那它的运行结果如下：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>2 message(s) found:<br />Greetings Earthling<br />Take me to your leader (please) </td></tr></tbody></table><br />　　“Hello world”示例程序现在介绍完毕。我们总算对Hibernate有了一个简单的认识，下面我们将回过头来，对Hibernate的主要API调用作一下简要的介绍：</span></td></tr></tbody></table><span class="f14">　　<strong>理解Hibernate的架构</strong><br /><br />　　当你想用Hibernate开发自己的基于持久层的应用时，第一件事情应当是熟悉它的编程接口。Hibernate的API接口设计得尽量简洁明了，以方便开发人员。然而实际上由于ORM的复杂性，它的API一般都不可能设计得很简单。但是别担心，你没有必要一下子了解所有的Hibernate的API接口。下面这张图描述了Hibernate在应用层和持久层中的一些重要的接口类：<br /><br /><table width="90%" align="center" border="0"><tbody><tr><td><div align="center"></div></td></tr></tbody></table><p><br />　　在上图中，我们将应用层放在了持久层的上部，实际上在传统的项目中，应用层充当着持久层的一个客户端角色。但对于一些简单的项目来说，应用层和持久层并没有区分得那么清楚，这也没什么，在这种情况下你可以将应用层和持久层合并成了一层。<br /><br />　　在上图中，Hibernate的接口大致可以分为以下几种类型：<br /><br />　　· 一些被用户的应用程序调用的，用来完成基本的创建、读取、更新、删除操作以及查询操作的接口。这些接口是Hibernate实现用户程序的商业逻辑的主要接口，它们包括Session、Transaction和Query。<br /><br />　　· Hibernate用来读取诸如映射表这类配置文件的接口，典型的代表有Configuration类。<br /><br />　　· 回调(Callback)接口。它允许应用程序能对一些事件的发生作出相应的操作，例如Interceptor、Lifecycle和Validatable都是这一类接口。<br /><br />　　· 一些可以用来扩展Hibernate的映射机制的接口，例如UserType、CompositeUserType和IdentifierGenerator。这些接口可由用户程序来实现（如果有必要）。<br /><br />　　Hibernate使用了J2EE架构中的如下技术：JDBC、JTA、JNDI。其中JDBC是一个支持关系数据库操作的一个基础层；它与JNDI和JTA一起结合，使得Hibernate可以方便地集成到J2EE应用服务器中去。<br /><br />　　在这里，我们不会详细地去讨论Hibernate API接口中的所有方法，我们只简要讲一下每个主要接口的功能，如果你想了解得更多的话，你可以在Hibernate的源码包中的net.sf.hibernate子包中去查看这些接口的源代码。下面我们依次讲一下所有的主要接口：<br /><br />　　<strong>核心接口</strong><br /><br />　　以下5个核心接口几乎在任何实际开发中都会用到。通过这些接口，你不仅可以存储和获得持久对象，并且能够进行事务控制。<br /><br />　　Session接口<br /><br />　　Session接口对于Hibernate 开发人员来说是一个最重要的接口。然而在Hibernate中，实例化的Session是一个轻量级的类，创建和销毁它都不会占用很多资源。这在实际项目中确实很重要，因为在客户程序中，可能会不断地创建以及销毁Session对象，如果Session的开销太大，会给系统带来不良影响。但值得注意的是Session对象是非线程安全的，因此在你的设计中，最好是一个线程只创建一个Session对象。<br /><br />　　在Hibernate的设计者的头脑中，他们将session看作介于数据连接与事务管理一种中间接口。我们可以将session想象成一个持久对象的缓冲区，Hibernate能检测到这些持久对象的改变，并及时刷新数据库。我们有时也称Session是一个持久层管理器，因为它包含这一些持久层相关的操作，诸如存储持久对象至数据库，以及从数据库从获得它们。请注意，Hibernate 的session不同于JSP应用中的HttpSession。当我们使用session这个术语时，我们指的是Hibernate中的session，而我们以后会将HttpSesion对象称为用户session。<br /><br />　　SessionFactory 接口<br /><br />　　这里用到了一个设计模式――工厂模式，用户程序从工厂类SessionFactory中取得Session的实例。<br /><br />　　令你感到奇怪的是SessionFactory并不是轻量级的！实际上它的设计者的意图是让它能在整个应用中共享。典型地来说，一个项目通常只需要一个SessionFactory就够了，但是当你的项目要操作多个数据库时，那你必须为每个数据库指定一个SessionFactory。<br />SessionFactory在Hibernate中实际起到了一个缓冲区的作用，它缓冲了Hibernate自动生成的SQL语句和一些其它的映射数据，还缓冲了一些将来有可能重复利用的数据。<br /><br />　　Configuration 接口<br /><br />　　Configuration接口的作用是对Hibernate进行配置，以及对它进行启动。在Hibernate的启动过程中，Configuration类的实例首先定位映射文档的位置，读取这些配置，然后创建一个SessionFactory对象。<br /><br />　　虽然Configuration接口在整个Hibernate项目中只扮演着一个很小的角色，但它是启动hibernate时你所遇到的每一个对象。<br /><br />　　Transaction 接口<br /><br />　　Transaction接口是一个可选的API，你可以选择不使用这个接口，取而代之的是Hibernate的设计者自己写的底层事务处理代码。 Transaction接口是对实际事务实现的一个抽象，这些实现包括JDBC的事务、JTA中的UserTransaction、甚至可以是CORBA事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面，使得自己的项目可以在不同的环境和容器之间方便地移值。<br /><br />　　Query和Criteria接口<br /><br />　　Query接口让你方便地对数据库及持久对象进行查询，它可以有两种表达方式：HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量，并最终执行查询操作。<br /><br />　　Criteria接口与Query接口非常类似，它允许你创建并执行面向对象的标准化查询。<br /><br />　　值得注意的是Query接口也是轻量级的，它不能在Session之外使用。<br /><br />　　Callback 接口 <br /><br />　　当一些有用的事件发生时――例如持久对象的载入、存储、删除时，Callback接口会通知Hibernate去接收一个通知消息。一般而言，Callback接口在用户程序中并不是必须的，但你要在你的项目中创建审计日志时，你可能会用到它。</p><p><span class="f14">　　<strong>一个重要的术语：Type</strong><br /><br />　　Hibernate的设计者们发明了一个术语：Type，它在整个构架中是一个非常基础、有着强大功能的元素。一个Type对象能将一个Java类型映射到数据库中一个表的字段中去（实际上，它可以映射到表的多个字段中去）。持久类的所有属性都对应一个type。这种设计思想使用Hibernate有着高度的灵活性和扩展性。<br /><br />　　Hibernate内置很多type类型，几乎包括所有的Java基本类型，例如Java.util.Currency、Java.util.calendar、byte[]和Java.io.Serializable。<br /><br />　　不仅如此，Hibernate还支持用户自定义的type，通过实现接口UserType和接口CompositeUserType，你可以加入自己的type。你可以利用这种特色让你的项目中使用自定义的诸如Address、Name这样的type，这样你就可以获得更大的便利，让你的代码更优雅。自定义type在Hibernate中是一项核心特色，它的设计者鼓励你多多使用它来创建一个灵活、优雅的项目！<br /><br />　　<strong>策略接口</strong><br /><br />　　Hibernate与某些其它开源软件不同的还有一点――高度的可扩展性，这通过它的内置策略机制来实现。当你感觉到Hibernate的某些功能不足，或者有某些缺陷时，你可以开发一个自己的策略来替换它，而你所要做的仅仅只是继承它的某个策略接口，然后实现你的新策略就可以了，以下是它的策略接口：<br /><br />　　· 主键的生成 (IdentifierGenerator 接口) <br /><br />　　· 本地SQL语言支持 (Dialect 抽象类) <br /><br />　　· 缓冲机制 (Cache 和CacheProvider 接口) <br /><br />　　· JDBC 连接管理 (ConnectionProvider接口) <br /><br />　　· 事务管理 (TransactionFactory, Transaction, 和 TransactionManagerLookup 接口) <br /><br />　　· ORM 策略 (ClassPersister 接口) <br /><br />　　· 属性访问策略 (PropertyAccessor 接口) <br /><br />　　· 代理对象的创建 (ProxyFactory接口)<br /><br />　　Hibernate为以上所列的机制分别创建了一个缺省的实现，因此如果你只是要增强它的某个策略的功能的话，只需简单地继承这个类就可以了，没有必要从头开始写代码。<br /><br />　　以上就是Hibernate的一些核心接口，但当我们真正开始用它进行开发时，你的脑海里可能总会有一个疑问：我是通过什么方式，并从哪里取得Session的呢？以下我们就解答这个问题。<br /><br />　　<strong>基础配置</strong><br /><br />　　现在回顾一下我们先前的内容：我们写出了一个示例程序，并简要地讲解了Hibernate的一些核心类。但要真正使你的项目运行起来，还有一件事必须要做：配置。Hibernate可以配置成可在任何Java环境中运行，一般说来，它通常被用在2－3层的C/S模式的项目中，并被部署在服务端。在这种项目中，Web浏览器、或Java GUI程序充当者客户端。尽管我们的焦点主要是集中在多层web应用，但实际上在一些基于命令行的应用中也可以使用Hibernate。并且，对Hibernate的配置在不同的环境下都会不同，Hibernate运行在两种环境下：可管理环境和不可管理环境<br /><br />　　· 可管理环境――这种环境可管理如下资源：池资源管理，诸如数据库连接池和，还有事务管理、安全定义。一些典型的J2EE服务器（JBoss、Weblogic、WebSphere）已经实现了这些。<br /><br />　　· 不可管理环境――只是提供了一些基本的功能，诸如像Jetty或Tomcat这样的servlet容器环境。一个普通的Java桌面应用或命令行程序也可以认为是处于这种环境下。这种环境不能提供自动事务处理、资源管理或安全管理，这些都必须由应用程序自己来定义。<br /><br />　　Hibernate的设计者们将这两种环境设计了一个统一的抽象界面，因此对于开发者来说只有一种环境：可管理环境。如果实际项目是建立在诸如Tomcat这类不可管理的环境中时，那Hibernate将会使用它自己的事务处理代码和JDBC连接池，使其变为一个可管理环境。<br />对于可管理的环境而言，Hibernate会将自己集成在这种环境中。对于开发者而言，你所要做的工作非常简单：只需从一个Configuration类中创建一个SessionFactory类就可以了。<br /><span class="f14">　　<strong>创建一个SessionFactory对象</strong><br /><br />　　为了能创建一个SessionFactory对象，你必须在Hibernate初始化时创建一个Configuration类的实例，并将已写好的映射文件交由它处理。这样，Configuration对象就可以创建一个SessionFactory对象，当SessionFactory对象创建成功后，Configuration对象就没有用了，你可以简单地抛弃它。如下是示例代码：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>Configuration cfg = new Configuration();<br />cfg.addResource("hello/Message.hbm.xml");<br />cfg.setProperties( System.getProperties() );<br />SessionFactory sessions = cfg.buildSessionFactory(); </td></tr></tbody></table><br />　　在以上代码中，Message.hb.xml这个映射文件的位置比较特殊，它与当前的classpath相关。例如classpath包含当前目录，那在上述代码中的Message.hbm.xml映射文件就可以保存在当前目录下的hello目录中。<br /><br />　　作为一种约定，Hibernate的映射文件默认以.htm.xml作为其扩展名。另一个约定是坚持为每一个持久类写一个配置文件，想一想如果你将所有持久类的映射写入一个单独的配置文件中的话，那这个配置文件肯定非常庞大，不易维护。但这里又出现了一个新问题：如果为每个类写一个配置文件的话，这么多的配置文件应该存放在哪里呢？<br /><br />　　Hibernate推荐你将每个映射文件保存在与持久类相同的目录下，并且与持久类同名。例如我们第一个示例程序中的Message持久类放在hello目录下，那你必须在这个目录下存放名为Message.hbm.xml的映射文件。这样一个持久类都有自己的一个映射文件，避免了出现像struts项目中的“struts-config.xml地狱”的情况。如果你不遵循这种规定，那你必须手动地用addResource()方法将一个个的映射文件载入；但你如果遵循这种规定，那你可以方便地用addClass()方法同时将持久类和它的映射文件载入，以下是体现这种便利性的示例代码：<br /><br /><table bordercolor="#ffcc66" cellspacing="0" cellpadding="0" width="90%" align="center" bgcolor="#e6e4dd" border="0"><tbody><tr><td>SessionFactory sessions = new Configuration()<br />.addClass(org.hibernate.auction.model.Item.class)<br />.addClass(org.hibernate.auction.model.Category.class)<br />.addClass(org.hibernate.auction.model.Bid.class)<br />.setProperties( System.getProperties() )<br />.buildSessionFactory(); </td></tr></tbody></table><br />　　当然，Hibernate的映射文件还有很多其它的配置选项，比如数据库连接的设定，或是能够改变Hibernate运行时行为的一些设定。所有的设置可能是非常庞杂的，足以让你喘不过气来，但是不必担心，因为Hibernate为绝大多数值都设定了一个合理缺省值，你只需要修改这些配置文件中的极小一部分值。<br /><br />　　你可以通过以下几种方式来修改Hibernate的系统配置参数：<br /><br />　　· 将一个Java.util.Properties实例作为参数传给Configuration类的setProperties()方法。<br /><br />　　· 在Hibernate启动时用Java –Dproperty=value的方式设置值。<br /><br />　　· 在classpath可以找到的路径下创建一个名为hibernate.properties的配置文件。 <br /><br />　　· 在classpath可以找到的路径下创建一个名为hibernate.cfg.xml的文件，并在其＜property＞标签中定义属性值。<br /><br />　　以上就是对Hibernate的一个大致介绍，如果你想知道得更多，那本文还是远远不够的，我将陆续推出更多关于Hibernate的资料。但有一点是毫无疑问的：它的确是一个非常优秀的持久层解决方案！<br /></span></span></p></span><br /><br /><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=317407</p><img src ="http://www.blogjava.net/iKingQu/aggbug/34571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-09 23:43 <a href="http://www.blogjava.net/iKingQu/articles/34571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏] 介绍一篇关于session的好文章,写的很详细(jsp-servlet 技术) </title><link>http://www.blogjava.net/iKingQu/articles/34570.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Thu, 09 Mar 2006 15:34:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/34570.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/34570.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/34570.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/34570.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/34570.html</trackback:ping><description><![CDATA[<DIV class=postText><SPAN class=content>摘要：虽然session机制在web应用程序中被采用已经很长时间了，但是仍然有很多人不清楚session机制的本质，以至不能正确的应用这一技术。本文将详细讨论session的工作机制并且对在Java&nbsp;web&nbsp;application中应用session机制时常见的问题作出解答。<BR><BR>目录：<BR>一、术语session<BR>二、HTTP协议与状态保持<BR>三、理解cookie机制<BR>四、理解session机制<BR>五、理解javax.servlet.http.HttpSession<BR>六、HttpSession常见问题<BR>七、跨应用程序的session共享<BR>八、总结<BR>参考文档<BR><BR>一、术语session<BR>在我的经验里，session这个词被滥用的程度大概仅次于transaction，更加有趣的是transaction与session在某些语境下的含义是相同的。<BR><BR>session，中文经常翻译为会话，其本来的含义是指有始有终的一系列动作/消息，比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个&nbsp;session。有时候我们可以看到这样的话“在一个浏览器会话期间，...”，这里的会话一词用的就是其本义，是指从一个浏览器窗口打开到关闭这个期间&nbsp;①。最混乱的是“用户（客户端）在一次会话期间”这样一句话，它可能指用户的一系列动作（一般情况下是同某个具体目的相关的一系列动作，比如从登录到选购商品到结账登出这样一个网上购物的过程，有时候也被称为一个transaction），然而有时候也可能仅仅是指一次连接，也有可能是指含义①，其中的差别只能靠上下文来推断②。<BR><BR>然而当session一词与网络协议相关联时，它又往往隐含了“面向连接”和/或“保持状态”这样两个含义，&nbsp;“面向连接”指的是在通信双方在通信之前要先建立一个通信的渠道，比如打电话，直到对方接了电话通信才能开始，与此相对的是写信，在你把信发出去的时候你并不能确认对方的地址是否正确，通信渠道不一定能建立，但对发信人来说，通信已经开始了。“保持状态”则是指通信的一方能够把一系列的消息关联起来，使得消息之间可以互相依赖，比如一个服务员能够认出再次光临的老顾客并且记得上次这个顾客还欠店里一块钱。这一类的例子有“一个TCP&nbsp;session”或者&nbsp;“一个POP3&nbsp;session”③。<BR><BR>而到了web服务器蓬勃发展的时代，session在web开发语境下的语义又有了新的扩展，它的含义是指一类用来在客户端与服务器之间保持状态的解决方案④。有时候session也用来指这种解决方案的存储结构，如“把xxx保存在session&nbsp;里”⑤。由于各种用于web开发的语言在一定程度上都提供了对这种解决方案的支持，所以在某种特定语言的语境下，session也被用来指代该语言的解决方案，比如经常把Java里提供的javax.servlet.http.HttpSession简称为session⑥。<BR><BR>鉴于这种混乱已不可改变，本文中session一词的运用也会根据上下文有不同的含义，请大家注意分辨。<BR>在本文中，使用中文“浏览器会话期间”来表达含义①，使用“session机制”来表达含义④，使用“session”表达含义⑤，使用具体的“HttpSession”来表达含义⑥<BR><BR>二、HTTP协议与状态保持<BR>HTTP&nbsp;协议本身是无状态的，这与HTTP协议本来的目的是相符的，客户端只需要简单的向服务器请求下载某些文件，无论是客户端还是服务器都没有必要纪录彼此过去的行为，每一次请求之间都是独立的，好比一个顾客和一个自动售货机或者一个普通的（非会员制）大卖场之间的关系一样。<BR><BR>然而聪明（或者贪心？）的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用，就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为，另一方面在服务器端则出现了CGI规范以响应客户端的动态请求，作为传输载体的HTTP协议也添加了文件上载、&nbsp;cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。<BR><BR>让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠，然而一次性消费5杯咖啡的机会微乎其微，这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案：<BR>1、该店的店员很厉害，能记住每位顾客的消费数量，只要顾客一走进咖啡店，店员就知道该怎么对待了。这种做法就是协议本身支持状态。<BR>2、发给顾客一张卡片，上面记录着消费的数量，一般还有个有效期限。每次消费时，如果顾客出示这张卡片，则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。<BR>3、发给顾客一张会员卡，除了卡号之外什么信息也不纪录，每次消费时，如果顾客出示该卡片，则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。<BR><BR>由于HTTP协议是无状态的，而出于种种考虑也不希望使之成为有状态的，因此，后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案，而session机制采用的是在服务器端保持状态的方案。同时我们也看到，由于采用服务器端保持状态的方案在客户端也需要保存一个标识，所以session机制可能需要借助于cookie机制来达到保存标识的目的，但实际上它还有其他选择。<BR><BR>三、理解cookie机制&nbsp;<BR>cookie机制的基本原理就如上面的例子一样简单，但是还有几个问题需要解决：“会员卡”如何分发；“会员卡”的内容；以及客户如何使用“会员卡”。<BR><BR>正统的cookie分发是通过扩展HTTP协议来实现的，服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。<BR><BR>而cookie&nbsp;的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie，如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置，则把该cookie附在请求资源的HTTP请求头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示，如果某家分店还发行了自己的会员卡，那么进这家店的时候除了要出示麦当劳的会员卡，还要出示这家店的会员卡。<BR><BR>cookie的内容主要包括：名字，值，过期时间，路径和域。<BR>其中域可以指定某一个域比如.google.com，相当于总店招牌，比如宝洁公司，也可以指定一个域下的具体某台机器比如www.google.com或者froogle.google.com，可以用飘柔来做比。<BR>路径就是跟在域名后面的URL路径，比如/或者/foo等等，可以用某飘柔专柜做比。<BR>路径与域合在一起就构成了cookie的作用范围。<BR>如果不设置过期时间，则表示这个cookie的生命期为浏览器会话期间，只要关闭浏览器窗口，cookie就消失了。这种生命期为浏览器会话期的&nbsp;cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里，当然这种行为并不是规范规定的。如果设置了过期时间，浏览器就会把cookie保存到硬盘上，关闭后再次打开浏览器，这些cookie仍然有效直到超过设定的过期时间。<BR><BR>存储在硬盘上的cookie&nbsp;可以在不同的浏览器进程间共享，比如两个IE窗口。而对于保存在内存里的cookie，不同的浏览器有不同的处理方式。对于IE，在一个打开的窗口上按&nbsp;Ctrl-N（或者从文件菜单）打开的窗口可以与原窗口共享，而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie；对于&nbsp;Mozilla&nbsp;Firefox0.8，所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用session机制的web应用程序开发者造成很大的困扰。<BR><BR>下面就是一个goolge设置cookie的响应头的例子<BR>HTTP/1.1&nbsp;302&nbsp;Found<BR>Location:&nbsp;<A href="http://www.google.com/intl/zh-CN/"></A><A href="http://www.google.com/intl/zh-CN/" target=_blank><FONT color=#223355>http://www.google.com/intl/zh-CN/</FONT></A><BR>Set-Cookie:&nbsp;PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8;&nbsp;expires=Sun,&nbsp;17-Jan-2038&nbsp;19:14:07&nbsp;GMT;&nbsp;path=/;&nbsp;domain=.google.com<BR>Content-Type:&nbsp;text/html<BR><BR><BR><BR><BR>这是使用HTTPLook这个HTTP&nbsp;Sniffer软件来俘获的HTTP通讯纪录的一部分<BR><BR><BR><BR><BR>浏览器在再次访问goolge的资源时自动向外发送cookie<BR><BR><BR><BR><BR>使用Firefox可以很容易的观察现有的cookie的值<BR>使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理。<BR><BR><BR><BR><BR>IE也可以设置在接受cookie前询问<BR><BR><BR><BR><BR>这是一个询问接受cookie的对话框。<BR><BR>四、理解session机制<BR>session机制是一种服务器端的机制，服务器使用一种类似于散列表的结构（也可能就是使用散列表）来保存信息。<BR><BR>当程序需要为某个客户端的请求创建一个session的时候，服务器首先检查这个客户端的请求里是否已包含了一个session标识&nbsp;-&nbsp;称为&nbsp;session&nbsp;id，如果已包含一个session&nbsp;id则说明以前已经为此客户端创建过session，服务器就按照session&nbsp;id把这个&nbsp;session检索出来使用（如果检索不到，可能会新建一个），如果客户端请求不包含session&nbsp;id，则为此客户端创建一个session并且生成一个与此session相关联的session&nbsp;id，session&nbsp;id的值应该是一个既不会重复，又不容易被找到规律以仿造的字符串，这个&nbsp;session&nbsp;id将被在本次响应中返回给客户端保存。<BR><BR>保存这个session&nbsp;id的方式可以采用cookie，这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID，而。比如weblogic对于web应用程序生成的cookie，JSESSIONID=&nbsp;ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764，它的名字就是&nbsp;JSESSIONID。<BR><BR>由于cookie可以被人为的禁止，必须有其他机制以便在cookie被禁止时仍然能够把session&nbsp;id传递回服务器。经常被使用的一种技术叫做URL重写，就是把session&nbsp;id直接附加在URL路径的后面，附加方式也有两种，一种是作为URL路径的附加信息，表现形式为<A href="http://...../xxx;jsessionid="></A><A href="http://...../xxx;jsessionid=" target=_blank><FONT color=#223355>http://...../xxx;jsessionid=</FONT></A>&nbsp;ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764<BR>另一种是作为查询字符串附加在URL后面，表现形式为<A href="http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"></A><A href="http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764" target=_blank><FONT color=#223355>http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764</FONT></A><BR>这两种方式对于用户来说是没有区别的，只是服务器在解析的时候处理的方式不同，采用第一种方式也有利于把session&nbsp;id的信息和正常程序参数区分开来。<BR>为了在整个交互过程中始终保持状态，就必须在每个客户端可能请求的路径后面都包含这个session&nbsp;id。<BR><BR>另一种技术叫做表单隐藏字段。就是服务器会自动修改表单，添加一个隐藏字段，以便在表单提交时能够把session&nbsp;id传递回服务器。比如下面的表单<BR>&lt;form&nbsp;name="testform"&nbsp;action="/xxx"&gt;<BR>&lt;input&nbsp;type="text"&gt;<BR>&lt;/form&gt;<BR>在被传递给客户端之前将被改写成<BR>&lt;form&nbsp;name="testform"&nbsp;action="/xxx"&gt;<BR>&lt;input&nbsp;type="hidden"&nbsp;name="jsessionid"&nbsp;value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"&gt;<BR>&lt;input&nbsp;type="text"&gt;<BR>&lt;/form&gt;<BR>这种技术现在已较少应用，笔者接触过的很古老的iPlanet6(SunONE应用服务器的前身)就使用了这种技术。<BR>实际上这种技术可以简单的用对action应用URL重写来代替。<BR><BR>在谈论session机制的时候，常常听到这样一种误解“只要关闭浏览器，session就消失了”。其实可以想象一下会员卡的例子，除非顾客主动对店家提出销卡，否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的，除非程序通知服务器删除一个session，否则服务器会一直保留，程序一般都是在用户做log&nbsp;off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭，因此服务器根本不会有机会知道浏览器已经关闭，之所以会有这种错觉，是大部分session机制都使用会话cookie来保存session&nbsp;id，而关闭浏览器后这个&nbsp;session&nbsp;id就消失了，再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上，或者使用某种手段改写浏览器发出的HTTP请求头，把原来的session&nbsp;id发送给服务器，则再次打开浏览器仍然能够找到原来的session。<BR><BR>恰恰是由于关闭浏览器不会导致session被删除，迫使服务器为seesion设置了一个失效时间，当距离客户端上一次使用session的时间超过这个失效时间时，服务器就可以认为客户端已经停止了活动，才会把session删除以节省存储空间。<BR><BR>五、理解javax.servlet.http.HttpSession<BR>HttpSession是Java平台对session机制的实现规范，因为它仅仅是个接口，具体到每个web应用服务器的提供商，除了对规范支持之外，仍然会有一些规范里没有规定的细微差异。这里我们以BEA的Weblogic&nbsp;Server8.1作为例子来演示。<BR><BR>首先，Weblogic&nbsp;Server提供了一系列的参数来控制它的HttpSession的实现，包括使用cookie的开关选项，使用URL重写的开关选项，session持久化的设置，session失效时间的设置，以及针对cookie的各种设置，比如设置cookie的名字、路径、域，&nbsp;cookie的生存时间等。<BR><BR>一般情况下，session都是存储在内存里，当服务器进程被停止或者重启的时候，内存里的session也会被清空，如果设置了session的持久化特性，服务器就会把session保存到硬盘上，当服务器进程重新启动或这些信息将能够被再次使用，&nbsp;Weblogic&nbsp;Server支持的持久性方式包括文件、数据库、客户端cookie保存和复制。<BR><BR>复制严格说来不算持久化保存，因为session实际上还是保存在内存里，不过同样的信息被复制到各个cluster内的服务器进程中，这样即使某个服务器进程停止工作也仍然可以从其他进程中取得session。<BR><BR>cookie生存时间的设置则会影响浏览器生成的cookie是否是一个会话cookie。默认是使用会话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解。<BR><BR>cookie的路径对于web应用程序来说是一个非常重要的选项，Weblogic&nbsp;Server对这个选项的默认处理方式使得它与其他服务器有明显的区别。后面我们会专题讨论。<BR><BR>关于session的设置参考[5]&nbsp;<A href="http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869"></A><A href="http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869" target=_blank><FONT color=#223355>http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869</FONT></A><BR><BR>六、HttpSession常见问题<BR>（在本小节中session的含义为⑤和⑥的混合）<BR><BR><BR>1、session在何时被创建<BR>一个常见的误解是以为session在有客户端访问时就被创建，然而事实是直到某server端程序调用&nbsp;HttpServletRequest.getSession(true)这样的语句时才被创建，注意如果JSP没有显示的使用&nbsp;&lt;%&nbsp;@page&nbsp;session="false"%&gt;&nbsp;关闭session，则JSP文件在编译成Servlet时将会自动加上这样一条语句&nbsp;HttpSession&nbsp;session&nbsp;=&nbsp;HttpServletRequest.getSession(true);这也是JSP中隐含的&nbsp;session对象的来历。<BR><BR>由于session会消耗内存资源，因此，如果不打算使用session，应该在所有的JSP中关闭它。<BR><BR>2、session何时被删除<BR>综合前面的讨论，session在下列情况下被删除a.程序调用HttpSession.invalidate();或b.距离上一次收到客户端发送的session&nbsp;id时间间隔超过了session的超时设置;或c.服务器进程被停止（非持久session）<BR><BR>3、如何做到在浏览器关闭时删除session<BR>严格的讲，做不到这一点。可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作，然后向服务器发送一个请求来删除session。但是对于浏览器崩溃或者强行杀死进程这些非常规手段仍然无能为力。<BR><BR>4、有个HttpSessionListener是怎么回事<BR>你可以创建这样的listener去监控session的创建和销毁事件，使得在发生这样的事件时你可以做一些相应的工作。注意是session的创建和销毁动作触发listener，而不是相反。类似的与HttpSession有关的listener还有&nbsp;HttpSessionBindingListener，HttpSessionActivationListener和&nbsp;HttpSessionAttributeListener。<BR><BR>5、存放在session中的对象必须是可序列化的吗<BR>不是必需的。要求对象可序列化只是为了session能够在集群中被复制或者能够持久保存或者在必要时server能够暂时把session交换出内存。在&nbsp;Weblogic&nbsp;Server的session中放置一个不可序列化的对象在控制台上会收到一个警告。我所用过的某个iPlanet版本如果&nbsp;session中有不可序列化的对象，在session销毁时会有一个Exception，很奇怪。<BR><BR>6、如何才能正确的应付客户端禁止cookie的可能性<BR>对所有的URL使用URL重写，包括超链接，form的action，和重定向的URL，具体做法参见[6]<BR><A href="http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770"></A><A href="http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770" target=_blank><FONT color=#223355>http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770</FONT></A><BR><BR>7、开两个浏览器窗口访问应用程序会使用同一个session还是不同的session<BR>参见第三小节对cookie的讨论，对session来说是只认id不认人，因此不同的浏览器，不同的窗口打开方式以及不同的cookie存储方式都会对这个问题的答案有影响。<BR><BR>8、如何防止用户打开两个浏览器窗口操作导致的session混乱<BR>这个问题与防止表单多次提交是类似的，可以通过设置客户端的令牌来解决。就是在服务器每次生成一个不同的id返回给客户端，同时保存在session里，客户端提交表单时必须把这个id也返回服务器，程序首先比较返回的id与保存在session里的值是否一致，如果不一致则说明本次操作已经被提交过了。可以参看《J2EE核心模式》关于表示层模式的部分。需要注意的是对于使用javascript&nbsp;window.open打开的窗口，一般不设置这个id，或者使用单独的id，以防主窗口无法操作，建议不要再window.open打开的窗口里做修改操作，这样就可以不用设置。<BR><BR>9、为什么在Weblogic&nbsp;Server中改变session的值后要重新调用一次session.setValue<BR>做这个动作主要是为了在集群环境中提示Weblogic&nbsp;Server&nbsp;session中的值发生了改变，需要向其他服务器进程复制新的session值。<BR><BR>10、为什么session不见了<BR>排除session正常失效的因素之外，服务器本身的可能性应该是微乎其微的，虽然笔者在iPlanet6SP1加若干补丁的Solaris版本上倒也遇到过；浏览器插件的可能性次之，笔者也遇到过3721插件造成的问题；理论上防火墙或者代理服务器在cookie处理上也有可能会出现问题。<BR>出现这一问题的大部分原因都是程序的错误，最常见的就是在一个应用程序中去访问另外一个应用程序。我们在下一节讨论这个问题。<BR><BR>七、跨应用程序的session共享<BR><BR>常常有这样的情况，一个大项目被分割成若干小项目开发，为了能够互不干扰，要求每个小项目作为一个单独的web应用程序开发，可是到了最后突然发现某几个小项目之间需要共享一些信息，或者想使用session来实现SSO(single&nbsp;sign&nbsp;on)，在session中保存login的用户信息，最自然的要求是应用程序间能够访问彼此的session。<BR><BR>然而按照Servlet规范，session的作用范围应该仅仅限于当前应用程序下，不同的应用程序之间是不能够互相访问对方的session的。各个应用服务器从实际效果上都遵守了这一规范，但是实现的细节却可能各有不同，因此解决跨应用程序session共享的方法也各不相同。<BR><BR>首先来看一下Tomcat是如何实现web应用程序之间session的隔离的，从&nbsp;Tomcat设置的cookie路径来看，它对不同的应用程序设置的cookie路径是不同的，这样不同的应用程序所用的session&nbsp;id是不同的，因此即使在同一个浏览器窗口里访问不同的应用程序，发送给服务器的session&nbsp;id也可以是不同的。<BR><BR><BR>&nbsp;&nbsp;<BR><BR>根据这个特性，我们可以推测Tomcat中session的内存结构大致如下。<BR><BR><BR><BR><BR>笔者以前用过的iPlanet也采用的是同样的方式，估计SunONE与iPlanet之间不会有太大的差别。对于这种方式的服务器，解决的思路很简单，实际实行起来也不难。要么让所有的应用程序共享一个session&nbsp;id，要么让应用程序能够获得其他应用程序的session&nbsp;id。<BR><BR>iPlanet中有一种很简单的方法来实现共享一个session&nbsp;id，那就是把各个应用程序的cookie路径都设为/（实际上应该是/NASApp，对于应用程序来讲它的作用相当于根）。<BR>&lt;session-info&gt;<BR>&lt;path&gt;/NASApp&lt;/path&gt;<BR>&lt;/session-info&gt;<BR><BR>需要注意的是，操作共享的session应该遵循一些编程约定，比如在session&nbsp;attribute名字的前面加上应用程序的前缀，使得&nbsp;setAttribute("name",&nbsp;"neo")变成setAttribute("app1.name",&nbsp;"neo")，以防止命名空间冲突，导致互相覆盖。<BR><BR><BR>在Tomcat中则没有这么方便的选择。在Tomcat版本3上，我们还可以有一些手段来共享session。对于版本4以上的Tomcat，目前笔者尚未发现简单的办法。只能借助于第三方的力量，比如使用文件、数据库、JMS或者客户端cookie，URL参数或者隐藏字段等手段。<BR><BR>我们再看一下Weblogic&nbsp;Server是如何处理session的。<BR><BR><BR>&nbsp;&nbsp;<BR><BR>从截屏画面上可以看到Weblogic&nbsp;Server对所有的应用程序设置的cookie的路径都是/，这是不是意味着在Weblogic&nbsp;Server中默认的就可以共享session了呢？然而一个小实验即可证明即使不同的应用程序使用的是同一个session，各个应用程序仍然只能访问自己所设置的那些属性。这说明Weblogic&nbsp;Server中的session的内存结构可能如下<BR><BR><BR><BR><BR>对于这样一种结构，在&nbsp;session机制本身上来解决session共享的问题应该是不可能的了。除了借助于第三方的力量，比如使用文件、数据库、JMS或者客户端&nbsp;cookie，URL参数或者隐藏字段等手段，还有一种较为方便的做法，就是把一个应用程序的session放到ServletContext中，这样另外一个应用程序就可以从ServletContext中取得前一个应用程序的引用。示例代码如下，<BR><BR>应用程序A<BR>context.setAttribute("appA",&nbsp;session);&nbsp;<BR><BR>应用程序B<BR>contextA&nbsp;=&nbsp;context.getContext("/appA");<BR>HttpSession&nbsp;sessionA&nbsp;=&nbsp;(HttpSession)contextA.getAttribute("appA");&nbsp;<BR><BR>值得注意的是这种用法不可移植，因为根据ServletContext的JavaDoc，应用服务器可以处于安全的原因对于context.getContext("/appA");返回空值，以上做法在Weblogic&nbsp;Server&nbsp;8.1中通过。<BR><BR>那么Weblogic&nbsp;Server为什么要把所有的应用程序的cookie路径都设为/呢？原来是为了SSO，凡是共享这个session的应用程序都可以共享认证的信息。一个简单的实验就可以证明这一点，修改首先登录的那个应用程序的描述符weblogic.xml，把cookie路径修改为/appA&nbsp;访问另外一个应用程序会重新要求登录，即使是反过来，先访问cookie路径为/的应用程序，再访问修改过路径的这个，虽然不再提示登录，但是登录的用户信息也会丢失。注意做这个实验时认证方式应该使用FORM，因为浏览器和web服务器对basic认证方式有其他的处理方式，第二次请求的认证不是通过&nbsp;session来实现的。具体请参看[7]&nbsp;secion&nbsp;14.8&nbsp;Authorization，你可以修改所附的示例程序来做这些试验。<BR><BR>八、总结<BR>session机制本身并不复杂，然而其实现和配置上的灵活性却使得具体情况复杂多变。这也要求我们不能把仅仅某一次的经验或者某一个浏览器，服务器的经验当作普遍适用的经验，而是始终需要具体情况具体分析。<BR>摘要：虽然session机制在web应用程序中被采用已经很长时间了，但是仍然有很多人不清楚session机制的本质，以至不能正确的应用这一技术。本文将详细讨论session的工作机制并且对在Java&nbsp;web&nbsp;application中应用session机制时常见的问题作出解答。</SPAN><BR><BR>
<P id=TBPingURL>Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=615990</P></DIV><img src ="http://www.blogjava.net/iKingQu/aggbug/34570.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-09 23:34 <a href="http://www.blogjava.net/iKingQu/articles/34570.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java优秀开源项目</title><link>http://www.blogjava.net/iKingQu/articles/34376.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Wed, 08 Mar 2006 14:51:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/34376.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/34376.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/34376.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/34376.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/34376.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=4 width="100%" bgColor=#cccccc border=0>
<TBODY>
<TR>
<TD style="VERTICAL-ALIGN: top" bgColor=#ffffff colSpan=2>
<DIV class=feature>
<H2>&nbsp; Hibernate</H2>
<H2>
<TABLE cellSpacing=0 cellPadding=4 width="100%" bgColor=#cccccc border=0>
<TBODY>
<TR>
<TD style="VERTICAL-ALIGN: top" bgColor=#ffffff colSpan=2>
<DIV class=feature>
<H2>
<TABLE cellSpacing=0 cellPadding=4 width="100%" bgColor=#cccccc border=0>
<TBODY>
<TR>
<TD style="VERTICAL-ALIGN: top" bgColor=#ffffff colSpan=2>
<DIV class=feature><SPAN class=style7><FONT face=宋体>Hibernate是一个开放源代码的对象关系映射框架，它对JDBC进行了非常轻量级的对象封装，使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合，既可以在Java的客户端程序实用，也可以在Servlet/JSP的Web应用中使用，最具革命意义的是，Hibernate可以在应用EJB的J2EE架构中取代CMP，完成数据持久化的重任。<FONT color=#000000>Eclipse平台下的Hibernate辅助开发工具</FONT>:【</FONT><A href="http://www.open-open.com/open5704.htm"><STRONG><FONT face=宋体 color=#002c99>Hibernate Synchronizer</FONT></STRONG></A><FONT face=宋体>】【</FONT><A href="http://www.open-open.com/open115804.htm"><STRONG><FONT face=宋体 color=#002c99>MiddlegenIDE</FONT></STRONG></A><FONT face=宋体>】 </FONT></SPAN></DIV></TD></TR>
<TR>
<TD bgColor=#ffffff colSpan=2>
<P><SPAN class="TitleColor style5"></SPAN>&nbsp;<IMG height=16 alt=主页 src="http://www.open-open.com/image/home_16.gif" width=16 border=0>&nbsp;</IMG><A href="http://www.hibernate.org"><FONT color=#002c99>http://www.hibernate.org</FONT></A></P>
<P><A href="http://www.huihoo.com/java/hibernate/hibernate-ref/2.1.2/html_single/">Hibernate - 符合Java习惯的关系数据库持久化</A></P>
<P>
<TABLE cellSpacing=0 cellPadding=4 width="100%" bgColor=#cccccc border=0>
<TBODY>
<TR>
<TD style="VERTICAL-ALIGN: top" bgColor=#ffffff colSpan=2>
<DIV class=feature>
<H2>Struts</H2><BR><SPAN class=style7><FONT face=宋体>Struts是一个基于Sun J2EE平台的MVC框架，主要是采用Servlet和JSP技术来实现的。由于Struts能充分满足应用开发的需求，简单易用，敏捷迅速，在过去的一年中颇受关注。Struts把Servlet、JSP、自定义标签和信息资源(message resources)整合到一个统一的框架中，开发人员利用其进行开发时不用再自己编码实现全套MVC模式，极大的节省了时间，所以说Struts是一个非常不错的应用框架。【</FONT><A href="http://www.open-open.com/open33204.htm"><STRONG><FONT face=宋体>StrutsIDE</FONT></STRONG></A><FONT face=宋体>：<FONT color=#000000>用于Struts辅助开发的一个Eclipse插件</FONT>】 </FONT></SPAN></DIV></TD></TR>
<TR>
<TD bgColor=#ffffff colSpan=2>
<P><SPAN class="TitleColor style5"></SPAN>&nbsp;<IMG height=16 alt=主页 src="http://www.open-open.com/image/home_16.gif" width=16 border=0>&nbsp;</IMG><A href="http://struts.apache.org/">http://struts.apache.org/</A></P>
<P><A href="http://www.yesky.com/SoftChannel/72348977504190464/20040131/1764524.shtml">Struts学习初级教程</A></P>
<P>
<TABLE cellSpacing=0 cellPadding=4 width="100%" bgColor=#cccccc border=0>
<TBODY>
<TR>
<TD style="VERTICAL-ALIGN: top" bgColor=#ffffff colSpan=2>
<DIV class=feature>
<H2>WebWork</H2><BR><SPAN class=style7><FONT face=宋体>WebWork是由OpenSymphony组织开发的，致力于组件化和代码重用的拉出式MVC模式J2EE Web框架。WebWork目前最新版本是2.1，现在的WebWork2.x前身是Rickard Oberg开发的WebWork，但现在WebWork已经被拆分成了Xwork1和WebWork2两个项目。 Xwork简洁、灵活功能强大，它是一个标准的Command模式实现，并且完全从web层脱离出来。 Xwork提供了很多核心功能：前端拦截机（interceptor），运行时表单属性验证，类型转换，强大的表达式语言（OGNL – the Object Graph Notation Language），IoC（Inversion of Control倒置控制）容器等。 WebWork2建立在Xwork之上，处理HTTP的响应和请求。WebWork2使用ServletDispatcher将HTTP请求的变成Action(业务层Action类), session（会话）application（应用程序）范围的映射，request请求参数映射。WebWork2支持多视图表示，视图部分可以使用JSP, Velocity, FreeMarker, JasperReports，XML等。在WebWork2.2中添加了对AJAX的支持，这支持是构建在DWR与Dojo这两个框架的基础之上.【</FONT><A href="http://www.open-open.com/open116804.htm"><STRONG><FONT face=宋体>EclipseWork</FONT></STRONG></A><FONT face=宋体>：<FONT color=#000000>用于WebWork辅助开发的一个Eclipse插件</FONT>】 </FONT></SPAN></DIV></TD></TR>
<TR>
<TD bgColor=#ffffff colSpan=2>
<P><SPAN class="TitleColor style5"></SPAN>&nbsp;<IMG height=16 alt=主页 src="http://www.open-open.com/image/home_16.gif" width=16 border=0>&nbsp;</IMG><A href="http://www.opensymphony.com/webwork/">http://www.opensymphony.com/webwork/</A></P>
<P>
<TABLE cellSpacing=0 cellPadding=4 width="100%" bgColor=#cccccc border=0>
<TBODY>
<TR>
<TD style="VERTICAL-ALIGN: top" bgColor=#ffffff colSpan=2>
<DIV class=feature>
<H2>Java Server Faces(JSF)</H2><BR><SPAN class=style7><FONT face=宋体>JavaServer(TM) Faces技术简化了JavaServer应用程序用户界面的开发.各种技术水平的开发者都能够快速创建web应用程序通过在一个页面中装配一些可重复使用UI组件;并可把这些组件与应用程序的数据源连接起来;也可把客户端产生的事件与服务端事件处理者连接起来.这个项目是Sun对JSF技术规范的最完整实现. </FONT></SPAN></DIV></TD></TR>
<TR>
<TD bgColor=#ffffff colSpan=2>
<P><SPAN class="TitleColor style5"></SPAN>&nbsp;<IMG height=16 alt=主页 src="http://www.open-open.com/image/home_16.gif" width=16 border=0>&nbsp;</IMG><A href="https://javaserverfaces.dev.java.net/">https://javaserverfaces.dev.java.net/</A></P>
<P><A href="http://www.inspiresky.com/Article/java/2006-01-18/408.html">JSF开发实战(一)</A></P>
<P><A href="http://www.inspiresky.com/Article/java/2006-01-18/409.html">JSF开发实战(二)</A></P>
<P><SPAN id=LblTitle><A href="http://kb.csdn.net/java/Articles/200510/3073d5c8-f64c-4f65-9945-12b64cb4a85d.html">J2EE MVC模式JSF与Struts的异同</A></SPAN></P>
<P><SPAN>
<TABLE cellSpacing=0 cellPadding=4 width="100%" bgColor=#cccccc border=0>
<TBODY>
<TR>
<TD style="VERTICAL-ALIGN: top" bgColor=#ffffff colSpan=2>
<DIV class=feature>
<H2>Spring Framework</H2><BR><SPAN class=style7><FONT face=宋体>Spring是一个解决了许多在J2EE开发中常见的问题的强大框架。 Spring提供了管理业务对象的一致方法并且鼓励了注入对接口编程而不是对类编程的良好习惯。Spring的架构基础是基于使用JavaBean属性的Inversion of Control容器。然而，这仅仅是完整图景中的一部分：Spring在使用IoC容器作为构建完关注所有架构层的完整解决方案方面是独一无二的。 Spring提供了唯一的数据访问抽象，包括简单和有效率的JDBC框架，极大的改进了效率并且减少了可能的错误。Spring的数据访问架构还集成了Hibernate和其他O/R mapping解决方案。Spring还提供了唯一的事务管理抽象，它能够在各种底层事务管理技术，例如JTA或者JDBC事务提供一个一致的编程模型。Spring提供了一个用标准Java语言编写的AOP框架，它给POJOs提供了声明式的事务管理和其他企业事务--如果你需要--还能实现你自己的aspects。这个框架足够强大，使得应用程序能够抛开EJB的复杂性，同时享受着和传统EJB相关的关键服务。Spring还提供了可以和IoC容器集成的强大而灵活的MVC Web框架。【</FONT><A href="http://www.open-open.com/open69004.htm"><STRONG><FONT face=宋体>SpringIDE</FONT></STRONG></A><FONT face=宋体>：Eclipse平台下一个辅助开发插件】. </FONT></SPAN></DIV></TD></TR>
<TR>
<TD bgColor=#ffffff colSpan=2><SPAN class="TitleColor style5"></SPAN>&nbsp;<IMG height=16 alt=主页 src="http://www.open-open.com/image/home_16.gif" width=16 border=0>&nbsp;</IMG><A href="http://www.springframework.org/">http://www.springframework.org/</A></TD></TR></TBODY></TABLE></SPAN></P></TD></TR></TBODY></TABLE></P></TD></TR></TBODY></TABLE></P></TD></TR></TBODY></TABLE></P></TD></TR></TBODY></TABLE></H2></DIV></TD></TR>
<TR>
<TD bgColor=#ffffff colSpan=2><SPAN class="TitleColor style5"></SPAN></IMG></TD></TR></TBODY></TABLE><BR></H2></DIV></TD></TR>
<TR>
<TD bgColor=#ffffff colSpan=2><SPAN class="TitleColor style5"></SPAN></IMG></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/iKingQu/aggbug/34376.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-08 22:51 <a href="http://www.blogjava.net/iKingQu/articles/34376.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]Struts原理与实践</title><link>http://www.blogjava.net/iKingQu/articles/33950.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 06 Mar 2006 15:41:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33950.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33950.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33950.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33950.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33950.html</trackback:ping><description><![CDATA[<FONT color=#000080>Struts原理与实践<BR><BR>文章地址：<BR></FONT><A href="http://blog.csdn.net/cuiweibing/archive/2005/07/22/431861.aspx">http://blog.csdn.net/cuiweibing/archive/2005/07/22/431861.aspx</A><BR><BR><img src ="http://www.blogjava.net/iKingQu/aggbug/33950.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-06 23:41 <a href="http://www.blogjava.net/iKingQu/articles/33950.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏]MySQL5.0中文问题及JDBC数据库连接和JSP汉字编码问题解决方法总结</title><link>http://www.blogjava.net/iKingQu/articles/33898.html</link><dc:creator>風向逆轉 - 就要爪哇</dc:creator><author>風向逆轉 - 就要爪哇</author><pubDate>Mon, 06 Mar 2006 10:30:00 GMT</pubDate><guid>http://www.blogjava.net/iKingQu/articles/33898.html</guid><wfw:comment>http://www.blogjava.net/iKingQu/comments/33898.html</wfw:comment><comments>http://www.blogjava.net/iKingQu/articles/33898.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iKingQu/comments/commentRss/33898.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iKingQu/services/trackbacks/33898.html</trackback:ping><description><![CDATA[原文地址：<a href="http://kb.csdn.net/java/Articles/200602/fc2fa2cd-52c6-4958-a286-eb582b2e7f9e.html">http://kb.csdn.net/java/Articles/200602/fc2fa2cd-52c6-4958-a286-eb582b2e7f9e.html</a><br /><br /><span id="LblContent">  
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; LINE-HEIGHT: 14pt; mso-line-height-rule: exactly; mso-layout-grid-align: none; mso-char-indent-count: 2.0"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">解决这类问题的方法很多，今天在此简单的终结一下，把常碰到的问题解决方法记下来!</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt"><br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-list: Ignore">1，<span style="FONT: 7pt 'Times New Roman'">   </span></span></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">MySQL5.0</span><span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">中文问题解决方案如下：</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt"> <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">    </span>1</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">、在<span lang="EN-US">dos</span>环境下，用<span lang="EN-US">mysql --default-character-set=gbk -u root -p </span>这句话进入<span lang="EN-US">mysql~~ <br /></span></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">    </span>2</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">、建数据库、表，如下：</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt"> <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">        </span>create database admin; <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">        </span>use admin;</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt"> <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">        </span>CREATE TABLE admin ( <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">       </span><span style="mso-spacerun: yes"> </span>admin_name char(20) NOT NULL, <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">        </span>admin_password char(20) NOT NULL <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">        </span>) TYPE=MyISAM, </span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">default character set gbk; <br /><br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-fareast-font-family: Verdana"><span style="mso-list: Ignore">2，<span style="FONT: 7pt 'Times New Roman'">  </span></span></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">JDBC</span><span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">的设置问题：<span lang="EN-US">(</span>这里主要讲的是</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana">mysql-connector-java-<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">3.1.8</chsdate></span><span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">这个</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana">JDBC</span><span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体">驱动程序而言</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana">) <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">   </span><span style="mso-spacerun: yes"> </span></span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">这只是一个压缩包，并不需要安装，只要将其解压，使用的是文件夹</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">mysql-connector-java-<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">3.1.8</chsdate></span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">里的文件：</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">mysql-connector-java-3.1.8-bin.jar</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">．</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"> <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"><span style="mso-spacerun: yes"> </span><span style="mso-spacerun: yes">    </span></span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">需要配置环境变量的是</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">JDBC</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">驱动．在配置前先要把刚才说到的</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">mysql-connector-java-<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">3.1.8</chsdate>-bin.jar</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">放到本地硬盘某处（我放的地方：</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">E:\JAVA\MySQLJDBC</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">），然后根据你放的地方，配置</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">classpath</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">，我的配置是这样的：</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"><br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">.;E:\Java\j2se5.0\lib\tools.jar; <span style="COLOR: red">E:\Java\j2se5.0\lib\mysql-connector-java-3.1.8-bin-g.jar; </span><span style="COLOR: green">E:\JAVA\MySQLJDBC\mysql-connector-java-3.1.8-bin.jar 
<p></p></span></span></p><p></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 14pt; TEXT-ALIGN: left; mso-line-height-rule: exactly; mso-pagination: widow-orphan" align="left"><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">    配置这个的目的是让你的</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">java</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">应用程序找到连接</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">mysql</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">的驱动．</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"> <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"> <span style="mso-spacerun: yes">     </span></span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">配置完环境变量后还有很重要一步就是为</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">JSP</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">连接数据库配置驱动，这个其实很简单，就是把</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">mysql-connector-java-<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">3.1.8</chsdate>-bin.jar</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">拷到某些文件夹里就行了，我在网上看了很多资料问了很多人，各种说法都有，我综合了一下，为了保险，我都全做了，呵呵，反正就是拷一个</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">400K</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">的文件而已，现列出要把</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">mysql-connector-java-3.1.8-bin.jar</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">拷进去的文件夹，如下：</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"><br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">E:\Java\Tomcat5.0\common\lib <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">E:\Java\Tomcat5.0\shared\lib <br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">     </span></span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">一般情况下只要考到</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">Tomcat5.0</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">上面的两个问题夹里面就可以解决问题了，如果需要，也可以将</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">mysql-connector-java-<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">3.1.8</chsdate>-bin.jar</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">这个驱动文件拷贝到你的</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">WEB</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">站点的</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">  </span></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">…\WEB-INF\lib </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">目录下面。</span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"></span></p></span><p></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 14pt; TEXT-ALIGN: left; mso-line-height-rule: exactly; mso-list: l0 level1 lfo1; mso-pagination: widow-orphan; tab-stops: list 18.0pt" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt; mso-fareast-font-family: Verdana"><span style="mso-list: Ignore">3，<span style="FONT: 7pt 'Times New Roman'">  </span></span></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">Eclipse</span><span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">中数据库插件中操作数据库时的中文编码问题：</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"><br /></span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">当在</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">Eclipse</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">中装上来你所喜欢的数据库插件的时候，都会出现在你查询某一个数据库之后出现记录中的汉字乱码。解决方法很简单，</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">只要在你建立数据库连接的时候把</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">URL</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">设置成下面这个样子就可以了：</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"><br /></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">           URL=</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: blue; mso-fareast-font-family: 楷体_GB2312"> jdbc:mysql://localhost:3306/?useUnicode=true&amp;characterEncoding=GBK</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt"></span></p><p></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 14pt; TEXT-ALIGN: left; mso-line-height-rule: exactly; mso-list: l0 level1 lfo1; mso-pagination: widow-orphan; tab-stops: list 18.0pt" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><span style="mso-list: Ignore">4，<span style="FONT: 7pt 'Times New Roman'">   </span></span></span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">在</span><span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">JSP</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">网页编辑中</span><span style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">个人经验：</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">在经过很多的次调试之后，发现在装了</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">myeclipse</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">之后，有这么条小巧：</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br /></span><span style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">①</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">在用</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">myeclipse</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">编写</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">HTML</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">文件时</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">charset=GBK</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">设置成这个样子，那么在浏览器中浏览时就不会出现乱码；</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br /></span><span style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">②</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">而在用</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">myeclipse</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">编辑<span lang="EN-US">JSP</span>文件时，</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&lt;%@ page contentType="text/html;charset=GB2312" %&gt;</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">设置成这样子，且这条语句必须是整个<span lang="EN-US">JSP</span>文件的第一条语句<span lang="EN-US">,</span>就可以避免<span lang="EN-US">JSP</span>文件在浏览器中显示时出现乱码；</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt"><span style="mso-spacerun: yes">   </span></span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt"><span style="mso-spacerun: yes"> </span></span><span style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt">③</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt">对于如果在<span lang="EN-US">JSP</span>网页中要从<span lang="EN-US">HTML</span>页面中接收数据，那么在<span lang="EN-US">JSP</span>中的接收语句的汉字编码应与数据来源的<span lang="EN-US">HTML</span>的汉字编码相同；例如</span><span style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">②</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">中的<span lang="EN-US">HTML</span>的汉字编码为</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">charset=GBK</span><span style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">，</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">那么在<span lang="EN-US">JSP</span>中的接收语句就应该这样设置：</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">request.setCharacterEncoding("GBK");</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">如果还要将接受的数据插入到数据库中<span lang="EN-US">(</span>以插入<span lang="EN-US">MySQL5.0</span>数据库为例<span lang="EN-US">)</span>，那么在插入数据库时的汉字编码也应与<span lang="EN-US">HTML</span>文件中的汉字编码相同，我的设置如下：</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">con= DriverManager.getConnection("jdbc:mysql://localhost:3306/sample_db?user=dazern&amp;password=5201314&amp;useUnicode=true&amp;characterEncoding=GBK");</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">这样设置后数据库中的数据才不会乱码<span lang="EN-US">. 
<p></p></span></span></p><p></p><p class="MsoNormal" style="MARGIN: 0cm -21.5pt 0pt 27pt; TEXT-INDENT: -27pt; LINE-HEIGHT: 14pt; mso-para-margin-left: 27.0pt; mso-line-height-rule: exactly; mso-layout-grid-align: none; mso-char-indent-count: -3.0; mso-para-margin-top: 0cm; mso-para-margin-right: -2.05gd; mso-para-margin-bottom: .0001pt"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt">    以上经验都是在</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #ff6600; FONT-FAMILY: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">myeclipse<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">3.8.3</chsdate>+Tomcat5.0.28</span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-ascii-font-family: Verdana; mso-hansi-font-family: Verdana; mso-bidi-font-family: Verdana; mso-font-kerning: 0pt">中测试过，没有错误！在此仅供大家借鉴，具体情况还得具体分析！</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"></span></p><img height="1" src="/dazern/aggbug/32520.html" width="1" /><br /><br /><div align="right">夏天的零度 2006-02-26 20:41 </div><img src ="http://www.blogjava.net/iKingQu/aggbug/33898.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iKingQu/" target="_blank">風向逆轉 - 就要爪哇</a> 2006-03-06 18:30 <a href="http://www.blogjava.net/iKingQu/articles/33898.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>