﻿<?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-seaairland-随笔分类-好文收集</title><link>http://www.blogjava.net/seaairland/category/8854.html</link><description>&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-6825418521341757";
google_ad_width = 120;
google_ad_height = 240;
google_ad_format = "120x240_as";
google_ad_type = "text_image";
google_ad_channel ="6369214374";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_url = "008000";
google_color_text = "000000";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
</description><language>zh-cn</language><lastBuildDate>Thu, 24 Apr 2008 05:16:45 GMT</lastBuildDate><pubDate>Thu, 24 Apr 2008 05:16:45 GMT</pubDate><ttl>60</ttl><item><title>js基础</title><link>http://www.blogjava.net/seaairland/archive/2008/04/24/195386.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Thu, 24 Apr 2008 01:47:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2008/04/24/195386.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/195386.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2008/04/24/195386.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/195386.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/195386.html</trackback:ping><description><![CDATA[1.document.write("");&nbsp;输出语句<br />
2.JS中的注释为//<br />
3.传统的HTML文档顺序是:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document-&gt;html-&gt;(head,body)<br />
4.一个浏览器窗口中的DOM顺序是:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window-&gt;(navigator,screen,history,location,document)<br />
5.得到表单中元素的名称和值:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById("表单中元素的ID号").name(或value)<br />
6.一个小写转大写的JS:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById("output").value=document.getElementById("input").value.toUpperCase();<br />
7.JS中的值类型:<br />
&nbsp;&nbsp;&nbsp;&nbsp;String,Number,Boolean,Null,Object,Function<br />
8.JS中的字符型转换成数值型:<br />
&nbsp;&nbsp;&nbsp;&nbsp;parseInt(),parseFloat()<br />
9.JS中的数字转换成字符型:<br />
&nbsp;&nbsp;&nbsp;&nbsp;(""&nbsp;变量)<br />
10.JS中的取字符串长度是:<br />
&nbsp;&nbsp;&nbsp;&nbsp;(length)<br />
11.JS中的字符与字符相连接使用&nbsp;号.<br />
12.JS中的比较操作符有:<br />
&nbsp;&nbsp;&nbsp;&nbsp;==等于,!=不等于,&gt;,&gt;=,&lt;.&lt;=<br />
13.JS中声明变量使用:<br />
&nbsp;&nbsp;&nbsp;&nbsp;var来进行声明<br />
14.JS中的判断语句结构:<br />
&nbsp;&nbsp;&nbsp;&nbsp;if(condition){}else{}<br />
15.JS中的循环结构:<br />
&nbsp;&nbsp;&nbsp;&nbsp;for([initial&nbsp;expression];[condition];[upadte&nbsp;expression])&nbsp;{inside&nbsp;loop}<br />
16.循环中止的命令是:<br />
&nbsp;&nbsp;&nbsp;&nbsp;break<br />
17.JS中的函数定义:<br />
&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;functionName([parameter],...){statement[s]}<br />
18.当文件中出现多个form表单时.可以用document.forms[0],document.forms[1]来代替.<br />
19.窗口:<br />
&nbsp;&nbsp;&nbsp;&nbsp;打开窗口window.open(),&nbsp;关闭一个窗口:window.close(),&nbsp;窗口本身:self<br />
20.状态栏的设置:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.status="字符";<br />
21.弹出提示信息:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.alert("字符");<br />
22.弹出确认框:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.confirm();<br />
23.弹出输入提示框:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.prompt();<br />
24.指定当前显示链接的位置:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.location.href="URL"<br />
25.取出窗体中的所有表单的数量:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.forms.length<br />
26.关闭文档的输出流:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.close();<br />
27.字符串追加连接符:&nbsp;=<br />
28.创建一个文档元素:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.createElement(),document.createTextNode()<br />
29.得到元素的方法:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById()<br />
30.设置表单中所有文本型的成员的值为空:<br />
var&nbsp;form&nbsp;=&nbsp;window.document.forms[0]<br />
for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&lt;form.elements.length;i&nbsp;){<br />
if&nbsp;(form.elements.type&nbsp;==&nbsp;"text"){<br />
form.elements.value&nbsp;=&nbsp;"";<br />
}<br />
}<br />
31.复选按钮在JS中判断是否选中:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.forms[0].checkThis.checked<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(checked属性代表为是否选中返回TRUE或FALSE)<br />
32.单选按钮组(单选按钮的名称必须相同):<br />
取单选按钮组的长度document.forms[0].groupName.length<br />
33.单选按钮组判断是否被选中也是用checked.<br />
34.下拉列表框的值:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.forms[0].selectName.options[n].value&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(n有时用下拉列表框名称加上.selectedIndex来确定被选中的值)<br />
35.字符串的定义:<br />
&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;myString&nbsp;=&nbsp;new&nbsp;String("This&nbsp;is&nbsp;lightsword");<br />
36.字符串转成大写:<br />
&nbsp;&nbsp;&nbsp;&nbsp;string.toUpperCase();&nbsp;字符串转成小写:string.toLowerCase();<br />
37.返回字符串2在字符串1中出现的位置:<br />
&nbsp;&nbsp;&nbsp;&nbsp;String1.indexOf("String2")!=-1则说明没找到.<br />
38.取字符串中指定位置的一个字符:<br />
&nbsp;&nbsp;&nbsp;&nbsp;StringA.charAt(9);<br />
39.取出字符串中指定起点和终点的子字符串:<br />
&nbsp;&nbsp;&nbsp;&nbsp;stringA.substring(2,6);<br />
40.数学函数:<br />
&nbsp;&nbsp;&nbsp;&nbsp;Math.PI(返回圆周率),Math.SQRT2(返回开方),Math.max(value1,value2)返回两个数中的<br />
最在值,Math.pow(value1,10)返回value1的十次方,Math.round(value1)四舍五入函数,<br />
Math.floor(Math.random()*(n&nbsp;1))返回随机数<br />
41.定义日期型变量:<br />
&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;today&nbsp;=&nbsp;new&nbsp;Date();<br />
42.日期函数列表:<br />
&nbsp;&nbsp;&nbsp;&nbsp;dateObj.getTime()得到时间,dateObj.getYear()得到年份,dateObj.getFullYear()得到四位的年份,<br />
&nbsp;&nbsp;&nbsp;&nbsp;dateObj.getMonth()得到月份,dateObj.getDate()得到日,dateObj.getDay()得到日期几,<br />
&nbsp;&nbsp;&nbsp;&nbsp;dateObj.getHours()得到小时,dateObj.getMinutes()得到分,dateObj.getSeconds()得到秒,<br />
&nbsp;&nbsp;&nbsp;&nbsp;dateObj.setTime(value)设置时间,dateObj.setYear(val)设置年,<br />
&nbsp;&nbsp;&nbsp;&nbsp;dateObj.setMonth(val)设置月,dateObj.setDate(val)设置日,<br />
&nbsp;&nbsp;&nbsp;&nbsp;dateObj.setDay(val)设置星期几,dateObj.setHours设置小时,dateObj.setMinutes(val)设置分,<br />
&nbsp;&nbsp;&nbsp;&nbsp;dateObj.setSeconds(val)设置秒&nbsp;[注意:此日期时间从0开始计]<br />
43.FRAME的表示方式:&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;[window.]frames[n].ObjFuncVarName,frames["frameName"].ObjFuncVarName,frameName.ObjFuncVarName<br />
44.parent代表父亲对象,top代表最顶端对象<br />
45.打开子窗口的父窗口为:opener<br />
46.表示当前所属的位置:this<br />
47.当在超链接中调用JS函数时用:(javascript&nbsp;:)来开头后面加函数名<br />
48.在老的浏览器中不执行此JS:&lt;!--&nbsp;//--&gt;<br />
49.引用一个文件式的JS:&lt;script&nbsp;type="text/javascript"&nbsp;src="aaa.js"&gt;&lt;/script&gt;<br />
50.指定在不支持脚本的浏览器显示的HTML:&lt;noscript&gt;&lt;/noscript&gt;<br />
51.当超链和onCLICK事件都有时,则老版本的浏览器转向a.html,否则转向b.html.<br />
&nbsp;&nbsp;&nbsp;&nbsp;例:&lt;a&nbsp;href="a.html"&nbsp;onclick="location.href='b.html';return&nbsp;false"&gt;dfsadf&lt;/a&gt;<br />
52.JS的内建对象有:<br />
&nbsp;&nbsp;&nbsp;&nbsp;Array,Boolean,Date,Error,EvalError,<br />
Function,Math,Number,Object,RangeError,ReferenceError,<br />
RegExp,String,SyntaxError,TypeError,URIError<br />
53.JS中的换行:\n<br />
54.窗口全屏大小:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;script&gt;function&nbsp;fullScreen(){&nbsp;this.moveTo(0,0);this.outerWidth=screen.availWidth;<br />
this.outerHeight=screen.availHeight;}window.maximize=fullScreen;&lt;/script&gt;<br />
55.JS中的all代表其下层的全部元素<br />
56.JS中的焦点顺序:document.getElementByid("表单元素").tabIndex&nbsp;=&nbsp;1<br />
57.innerHTML的值是表单元素的值:<br />
&nbsp;&nbsp;&nbsp;&nbsp;如&lt;p&nbsp;id="para"&gt;"how&nbsp;are&nbsp;&lt;em&gt;you&lt;/em&gt;"&lt;/p&gt;,则innerHTML的值就是:how&nbsp;are&nbsp;&lt;em&gt;you&lt;/em&gt;<br />
58.innerTEXT的值和上面的一样,只不过不会把&lt;em&gt;这种标记显示出来.<br />
59.contentEditable可设置元素是否可被修改,isContentEditable返回是否可修改的状态.<br />
60.isDisabled判断是否为禁止状态.disabled设置禁止状态<br />
61.length取得长度,返回整型数值<br />
62.addBehavior()是一种JS调用的外部函数文件其扩展名为.htc<br />
63.window.focus()使当前的窗口在所有窗口之前.<br />
64.blur()指失去焦点.与FOCUS()相反.<br />
65.select()指元素为选中状态.<br />
66.防止用户对文本框中输入文本:<br />
&nbsp;&nbsp;&nbsp;&nbsp;onfocus="this.blur()"<br />
67.取出该元素在页面中出现的数量:<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.all.tags("div(或其它HTML标记符)").length<br />
68.JS中分为两种窗体输出:模态和非模态.<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.showModaldialog(),window.showModeless()<br />
69.状态栏文字的设置:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.status='文字',默认的状态栏文字设置:window.defaultStatus&nbsp;=&nbsp;'文字.';<br />
70.添加到收藏夹:<br />
&nbsp;&nbsp;&nbsp;&nbsp;external.AddFavorite("<a class="contentlink" href="http://meil.cnblogs.com/" target="_blank">http://meil.cnblogs.com</a>";,"jaskdlf");<br />
71.JS中遇到脚本错误时不做任何操作:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.onerror&nbsp;=&nbsp;doNothing;&nbsp;指定错误句柄的语法为:window.onerror&nbsp;=&nbsp;handleError;<br />
72.JS中指定当前打开窗口的父窗口:<br />
&nbsp;&nbsp;&nbsp;&nbsp;window.opener,支持opener.opener...的多重继续.<br />
73.JS中的self指的是当前的窗口<br />
74.JS中状态栏显示内容:window.status="内容"<br />
75.JS中的top指的是框架集中最顶层的框架<br />
76.JS中关闭当前的窗口:window.close();<br />
77.JS中提出是否确认的框:if(confirm("Are&nbsp;you&nbsp;sure?")){alert("ok");}else{alert("Not&nbsp;Ok");}<br />
78.JS中的窗口重定向:window.navigate("<a class="contentlink" href="http://meil.cnblogs.com/" target="_blank">http://meil.cnblogs.com</a>";);<br />
79.JS中的打印:window.print()<br />
80.JS中的提示输入框:window.prompt("message","defaultReply");<br />
81.JS中的窗口滚动条:window.scroll(x,y)<br />
82.JS中的窗口滚动到位置:window.scrollby<br />
83.JS中设置时间间隔:setInterval("expr",msecDelay)或setInterval(funcRef,msecDelay)或setTimeout<br />
84.JS中的模态显示在IE4&nbsp;行,在NN中不行:showModalDialog("URL"[,arguments][,features]);<br />
85.JS中的退出之前使用的句柄:<br />
&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;verifyClose(){event.returnValue="we&nbsp;really&nbsp;like&nbsp;you&nbsp;and&nbsp;hope&nbsp;you&nbsp;will&nbsp;stay&nbsp;longer.";}}&nbsp;window.=verifyClose;<br />
86.当窗体第一次调用时使用的文件句柄:onload()<br />
87.当窗体关闭时调用的文件句柄:onunload()<br />
88.window.location的属性:<br />
&nbsp;&nbsp;&nbsp;&nbsp;protocol(http:),hostname(www.example.com),port(80),host(www.example.com:80),<br />
&nbsp;&nbsp;&nbsp;&nbsp;pathname("/a/a.html"),hash("#giantGizmo",指跳转到相应的锚记),href(全部的信息)<br />
89.window.location.reload()刷新当前页面.<br />
90.window.history.back()返回上一页,window.history.forward()返回下一页,<br />
window.history.go(返回第几页,也可以使用访问过的URL)<br />
91.document.write()不换行的输出,document.writeln()换行输出<br />
92.document.body.noWrap=true;防止链接文字折行.<br />
93.变量名.charAt(第几位),取该变量的第几位的字符.<br />
94."abc".charCodeAt(第几个),返回第几个字符的ASCii码值.<br />
95.字符串连接:string.concat(string2),或用&nbsp;=进行连接<br />
96.变量.indexOf("字符",起始位置),返回第一个出现的位置(从0开始计算)<br />
97.string.lastIndexOf(searchString[,startIndex])最后一次出现的位置.<br />
98.string.match(regExpression),判断字符是否匹配.<br />
99.string.replace(regExpression,replaceString)替换现有字符串.<br />
100.string.split(分隔符)返回一个数组存储值.<br />
101.string.substr(start[,length])取从第几位到指定长度的字符串.<br />
102.string.toLowerCase()使字符串全部变为小写.<br />
103.string.toUpperCase()使全部字符变为大写.<br />
104.parseInt(string[,radix(代表进制)])强制转换成整型.<br />
105.parseFloat(string[,radix])强制转换成浮点型.<br />
106.isNaN(变量):测试是否为数值型.<br />
107.定义常量的关键字:const,定义变量的关键字:var&nbsp;
<img src ="http://www.blogjava.net/seaairland/aggbug/195386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2008-04-24 09:47 <a href="http://www.blogjava.net/seaairland/archive/2008/04/24/195386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>职场少走弯路的十条忠告 </title><link>http://www.blogjava.net/seaairland/archive/2007/03/15/103947.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Thu, 15 Mar 2007 02:03:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2007/03/15/103947.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/103947.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2007/03/15/103947.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/103947.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/103947.html</trackback:ping><description><![CDATA[
		<div class="quote_div">
				<p>
				</p>
				<p>1。 买个闹钟 <br /><span style="COLOR: blue">作用不是早起是为了知道哪天晚了 <br />每天早晨在闹钟叫之前起床 <br />人生不是被迫的, <br />是积极的</span></p>
				<p>2。 如果你不喜欢现在的工作，要么辞职不干，要么就闭嘴不言。 <br /><span style="COLOR: blue">闭嘴能让别人看的清你, <br />闭嘴可以让你听的清别人. <br />辞职不是好办法 <br />但有时也是必须的好办法</span></p>
				<p>4。 走运时要做好倒霉的准备，退路同样重要。 <br /><span style="COLOR: blue">退路?退路如果给了你安全感?还不如不要 <br />退路有了就可以了,不要轻言退出.....</span></p>
				<p>5。 不要象玻璃那样脆弱。 <br /><span style="COLOR: blue">社会可能错了,但如果是你那么永远不要碎 <br />只要你不碎,社会还有可能变回正确. <br />那么你还是你,碎了你就是渣</span></p>
				<p>7。 机会从不会“失掉”，你失掉了，自有别人会得到。 <br /><span style="COLOR: blue">机会这东西很可爱. <br />你能力到了,机会就会在你眼前跑来跑去 <br />你能力不到,他会跑来拌倒你</span></p>
				<p>8。 若电话老是不响，你该打出去。 <br /><span style="COLOR: blue">社会 ?职业,家?朋友?都没有? <br />你应该去看看能不能帮助别人 <br />而不是只打个电话</span></p>
				<p>
				</p>
		</div>
<img src ="http://www.blogjava.net/seaairland/aggbug/103947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2007-03-15 10:03 <a href="http://www.blogjava.net/seaairland/archive/2007/03/15/103947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>职场少走弯路的十条忠告</title><link>http://www.blogjava.net/seaairland/archive/2007/03/15/103946.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Thu, 15 Mar 2007 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2007/03/15/103946.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/103946.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2007/03/15/103946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/103946.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/103946.html</trackback:ping><description><![CDATA[
		<p>
				<span style="FONT-SIZE: 16pt">
				</span> </p>
		<p>1。 买个闹钟，以便按时叫醒你。贪睡和不守时都将成为你工作和事业上的绊脚石。不仅要学会准时，更要学会提前。“闹钟”只是一种简单的标志和提示，真正灵活、实用的时间，掌握在每个人心中。</p>
		<p>2。 如果你不喜欢现在的工作，要么辞职不干，要么就闭嘴不言。初出茅庐往往眼高手低，心高气傲，大事做不了小事不愿做。不要养成捡三挑四的习惯，处处表现出不满的情绪。记住，不做则已，要做就要做好。</p>
		<p>3。 每个人都有孤独的时候，要学会忍受孤独，这样才会成熟起来。千万不要浮躁，要学会静心，更不要因为寂寞去做无聊无益的事情，白白浪费了宝贵的时间。</p>
		<p>4。 走运时要做好倒霉的准备，退路同样重要。饱带干粮，晴带雨伞，点滴积累，水到渠成。有的东西今天似乎一文不值，但有朝一日也许就会身价百倍。</p>
		<p>5。 不要象玻璃那样脆弱。有的人眼睛总盯着自己，所以长不高看不远，总是喜欢怨天尤人。没有苦中苦，哪来甜中甜？既然睁开眼睛享受风的清凉，就不要埋怨风中细小的沙粒。</p>
		<p>6。 管住自己的嘴巴。不要谈论自己，更不要谈论别人。谈论自己往往会自大虚伪，在名不副实中失去自己。议论别人往往陷入鸡毛蒜皮的是非口舌中纠缠不清。背后议论别人的短处，会降低你的人格。</p>
		<p>7。 机会从不会“失掉”，你失掉了，自有别人会得到。不要凡事在天，守株待兔，更不要寄希望于“机会”。机会是相对于充分准备而又善于创造机会的人而言的。也许，你正为失去一个机会而懊悔、埋怨的时候，机会正被你对面那个同样的“倒霉鬼”给抓住了，没有机会就要创造机会，有了机会就要巧妙的抓住。</p>
		<p>8。 若电话老是不响，你该打出去。很多时候，电话会给你带来意想不到的收获。交际的一大诀窍就是主动。好的人缘好的口碑，往往祝你的事业更上一个台阶。</p>
		<p>9。 千万不要因为自己已经到了结婚年龄而草率结婚。想结婚就要着一个能和你心心相印相辅相携的伴侣。不要因为放纵和游戏而恋爱，不要因为恋爱而影响工作和事业，更不要因为一桩草率而失败的婚姻而使人生受阻。感情用事往往会因小失大。</p>
		<p>10。 写出你一生要做的事情，把单子放在皮夹里，经常拿出来看。人生要有目标，要有计划，要有提醒，要有紧迫感。一个又一个小目标串起来，就成了你一生的大目标。</p>
<img src ="http://www.blogjava.net/seaairland/aggbug/103946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2007-03-15 10:02 <a href="http://www.blogjava.net/seaairland/archive/2007/03/15/103946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL常见错误问答</title><link>http://www.blogjava.net/seaairland/archive/2006/05/06/44773.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Sat, 06 May 2006 08:57:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/05/06/44773.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/44773.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/05/06/44773.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/44773.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/44773.html</trackback:ping><description><![CDATA[
		<h3>18.2.1<code><font face="新宋体"> MySQL server has gone away</font></code>错误</h3>
		<p>本小节也涉及有关<code><font face="新宋体">Lost connection to server during query</font></code>的错误。</p>
		<p>对<code><font face="新宋体">MySQL server has gone away</font></code>错误最常见的原因是服务器超时了并且关闭了连接。缺省地，如果没有事情发生，服务器在 8个小时后关闭连接。你可在启动mysqld时通过设置<code><font face="新宋体">wait_timeout</font></code>变量改变时间限制。</p>
		<p>你可以通过执行<code><font face="新宋体">mysqladmin version</font></code>并且检验正常运行的时间来检查<strong>MySQL</strong>还没死掉。</p>
		<p>如果你有一个脚本，你只须再发出查询让客护进行一次自动的重新连接。</p>
		<p>在这种请下，你通常能获得下列错误代码(你得到的是OS相关的)：</p>
		<table class="p4" width="100%" border="1" nosave="#101090">
				<tbody>
						<tr>
								<td>
										<code>
												<font face="新宋体">CR_SERVER_GONE_ERROR</font>
										</code>
								</td>
								<td>客户不能发送一个问题给服务器。 </td>
						</tr>
						<tr>
								<td>
										<code>
												<font face="新宋体">CR_SERVER_LOST</font>
										</code>
								</td>
								<td>当写服务器时，客户没有出错，但是它没有得到对问题的一个完整的答案(或任何答案)。 </td>
						</tr>
				</tbody>
		</table>
		<p>如果你向服务器发送不正确的或太大的查询，你也可能得到这些错误。如果<code><font face="新宋体">mysqld</font></code>得到一个太大或不正常的包，它认为客户出错了并关闭连接。如果你需要较大的查询(例如，如果你正在处理较大的<code><font face="新宋体">BLOB</font></code>列)，你可以使用<code><font face="新宋体">-O max_allowed_packet=#</font></code>选项(缺省1M)启动<code><font face="新宋体">mysqld</font></code>以增加查询限制。多余的内存按需分配，这样<code><font face="新宋体">mysqld</font></code>只有在你发出较大差询时或<code><font face="新宋体">mysqld</font></code>必须返回较大的结果行时，才使用更多的内存！</p>
		<h3>18.2.2<code><font face="新宋体"> Can't connect to [local] MySQL server</font></code>错误</h3>
		<p>一个<strong>MySQL</strong>客户可以两种不同的方式连接<code><font face="新宋体">mysqld</font></code>服务器：Unix套接字，它通过在文件系统中的一个文件(缺省<tt><font face="新宋体">“/tmp/mysqld.sock”</font></tt>)进行连接；或TCP/IP，它通过一个端口号连接。Unix套接字比TCP/IP更快，但是只有用在连接同一台计算机上的服务器。如果你不指定主机名或如果你指定特殊的主机名<code><font face="新宋体">localhost</font></code>，使用Unix套接字。</p>
		<p>错误(2002）<code><font face="新宋体">Can't connect to ...</font></code>通常意味着没有一个<strong>MySQL</strong>服务器运行在系统上或当试图连接<code><font face="新宋体">mysqld</font></code>服务器时，你正在使用一个错误的套接字文件或TCP/IP端口。 </p>
		<p>由检查(使用<code><font face="新宋体">ps</font></code>)在你的服务器上有一个名为<code><font face="新宋体">mysqld</font></code>的进程启动！如果没有任何<code><font face="新宋体">mysqld</font></code>过程，你应该启动一个。见4.15.2 启动MySQL服务器的问题。</p>
		<p>如果一个<code><font face="新宋体">mysqld</font></code>过程正在运行，你可以通过尝试这些不同的连接来检查服务器(当然，端口号和套接字路径名可能在你的安装中是不同的)：</p>
		<pre>shell&gt; mysqladmin version
shell&gt; mysqladmin variables
shell&gt; mysqladmin -h `hostname` version variables
shell&gt; mysqladmin -h `hostname` --port=3306 version
shell&gt; mysqladmin -h 'ip for your host' version
shell&gt; mysqladmin --socket=/tmp/mysql.sock version
</pre>
		<p>注意<code><font face="新宋体">hostname</font></code>命令使用反引号“`”而非正引号“'”；这些导致<code><font face="新宋体">hostname</font></code>输出（即，当前主机名)被代替进<code><font face="新宋体">mysqladmin</font></code>命令中。</p>
		<p>这是可能造成<code><font face="新宋体">Can't connect to local MySQL server</font></code>错误的一些原因： 
</p>
		<ul>
				<li>
						<code>
								<font face="新宋体">mysqld</font>
						</code>不在运行。 
</li>
				<li>你正在使用MIT-pthreads的一个系统上运行。如果正在运行在一个没有原生线程的系统上，<code><font face="新宋体">mysqld</font></code>使用 MIT-pthreads 软件包。见4.2 由MySQL支持的操作系统。然而，MIT-pthreads不支持Unix套接字，因此当与服务器连接时，在这样一个系统上，你总是必须明确地指定主机名。试试使用这个命令检查到服务器的连接：<pre>shell&gt; mysqladmin -h `hostname` version
</pre></li>
				<li>某人删除了<code><font face="新宋体">mysqld</font></code>使用的Unix套接字(缺省<tt><font face="新宋体">“/tmp/mysqld.sock”</font></tt>)。你可能有一个<code><font face="新宋体">cron</font></code>任务删除了<strong>MySQL</strong>套接字(例如，一个把旧文件从<tt><font face="新宋体">“/tmp”</font></tt>目录中删除的任务)。你总是可以运行<code><font face="新宋体">mysqladmin version</font></code>并且检查<code><font face="新宋体">mysqladmin</font></code>正在试图使用的套接字确实存在。在这种情况下，修复方法是删除<code><font face="新宋体">cron</font></code>任务而不删除<tt><font face="新宋体">“mysqld.sock </font></tt>或将套接字放在其他地方。你能用这个命令在<strong>MySQL</strong>配置时指定一个不同的套接字地点：<pre>shell&gt; ./configure --with-unix-socket-path=/path/to/socket
</pre><p>你也可以使用<code><font face="新宋体">--socket=/path/to/socket</font></code>选项启动<code><font face="新宋体">safe_mysqld</font></code>和在启动你的<strong>MySQL</strong>客户前设置环境变量<code><font face="新宋体">MYSQL_UNIX_PORT</font></code>为套接字路径名。你可用<code><font face="新宋体">--socket=/path/to/socket</font></code>选项启动<code><font face="新宋体">mysqld</font></code>服务器。如果你改变了服务器的套接字路径名，你也必须通知<strong>MySQL</strong>客户关于新路径的情况。你可以通过设置环境变量<code><font face="新宋体">MYSQL_UNIX_PORT</font></code>为套接字路径名或由提供套接字路径名作为客户的参数做到。你可用这个命令测试套接字：</p><pre>shell&gt; mysqladmin --socket=/path/to/socket version
</pre></li>
				<li>你正在使用 Linux和线程已经死了(核心倾倒了)。在这种情况中，你必须杀死其它<code><font face="新宋体">mysqld</font></code>线程(例如在启动一个新的<strong>MySQL</strong>服务器之前，可以用<code><font face="新宋体">mysql_zap</font></code>脚本）。见18.1 如果MySQL总是崩溃怎么办。 </li>
		</ul>
		<p>如果你得到错误<code><font face="新宋体">Can't connect to MySQL server on some_hostname</font></code>，你可以尝试下列步骤找出问题是什么： 
</p>
		<ul>
				<li>通过执行<code><font face="新宋体">telnet your-host-name tcp-ip-port-number</font></code>并且按几次回车来检查服务器是否正常运行。如果有一个<strong>MySQL</strong>运行在这个端口上，你应该得到一个包含正在运行的<strong>MySQL</strong>服务器的版本号的应答。如果你得到类似于<code><font face="新宋体">telnet: Unable to connect to remote host: Connection refused</font></code>的一个错误，那么没有服务器在使用的端口上运行。 
</li>
				<li>尝试连接本地机器上的<code><font face="新宋体">mysqld</font></code>守护进程，并用<code><font face="新宋体">mysqladmin variables</font></code>检查mysqld被配置使用的TCP/IP端口(变量<code><font face="新宋体">port</font></code>)。 
</li>
				<li>检查你的<code><font face="新宋体">mysqld</font></code>服务器没有用<code><font face="新宋体">--skip-networking</font></code>选项启动。 </li>
		</ul>
		<h3>18.2.3<code><font face="新宋体"> Host '...' is blocked</font></code>错误</h3>
		<p>如果你得到象这样的一个错误：</p>
		<pre>Host 'hostname' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'
</pre>
		<p>这意味着，<code><font face="新宋体">mysqld</font></code>已经得到了大量(<code><font face="新宋体">max_connect_errors</font></code>)的主机<code><font face="新宋体">'hostname'</font></code>的在中途被中断了的连接请求。在<code><font face="新宋体">max_connect_errors</font></code>次失败请求后，<code><font face="新宋体">mysqld</font></code>认定出错了(象来字一个黑客的攻击)，并且阻止该站点进一步的连接，直到某人执行命令<code><font face="新宋体">mysqladmin flush-hosts</font></code>。</p>
		<p>缺省地，<code><font face="新宋体">mysqld</font></code>在10个连接错误后阻塞一台主机。你可以通过象这样启动服务器很容易地调整它：</p>
		<pre>shell&gt; safe_mysqld -O max_connect_errors=10000 &amp;
</pre>
		<p>注意，对给定的主机，如果得到这条错误消息，你应该首先检查该主机的TCP/IP连接有没有问题。如果你的TCP/IP连接不在运行，增加<code><font face="新宋体">max_connect_errors</font></code>变量的值对你也不会有帮助！</p>
		<h3>18.2.4<code><font face="新宋体"> Too many connections</font></code>错误</h3>
		<p>如果在你试土连接<strong>MySQL</strong>时，你得到错误<code><font face="新宋体">Too many connections</font></code>，这意味着已经有<code><font face="新宋体">max_connections</font></code>个客户连接了mysqld服务器。</p>
		<p>如果你需要比缺省(100)更多的连接，那么你应该重启<code><font face="新宋体">mysqld</font></code>，用更大的 max_connections 变量值。</p>
		<p>注意，<code><font face="新宋体">mysqld</font></code>实际上允许(max_connections+1)个客户连接。最后一个连接是为一个用<code><font face="新宋体">Process</font></code>权限的用户保留的。通过不把这个权限给一般用户(他们不应该需要它)，有这个权限一个管理员可以登录并且使用<code><font face="新宋体">SHOW PROCESSLIST</font></code>找出什么可能出错。见7.21<code><font face="新宋体"> SHOW</font></code>句法(得到表，列的信息）。</p>
		<h3>18.2.5<code><font face="新宋体"> Out of memory</font></code>错误</h3>
		<p>如果你发出查询并且得到类似于下面的错误： </p>
		<pre>mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory
</pre>
		<p>注意，错误指向了<strong>MySQL</strong>客<code><font face="新宋体">户mysql</font></code>。这个错误的原因很简单，客户没有足够的内存存储全部结果。</p>
		<p>为了修正这个问题，首先检查你的查询是否正确。它应该返回这么多的行，这合理吗？如果是这样，你可以使用<code><font face="新宋体">mysql --quick</font></code>，它使用<code><font face="新宋体">mysql_use_result()</font></code>检索结果集合。这将较少的负担放在了客户端(只是服务器更多)。</p>
		<h3>18.2.6<code><font face="新宋体"> Packet too large</font></code>错误</h3>
		<p>当一个<strong>MySQL</strong>客户或<code><font face="新宋体">mysqld</font></code>服务器得到一个比<code><font face="新宋体">max_allowed_packet</font></code>个字节长的包，它发出一个<code><font face="新宋体">Packet too large</font></code>错误并终止连接。</p>
		<p>如果你正在使用<code><font face="新宋体">mysql</font></code>客户，你可以通过用<code><font face="新宋体">mysql --set-variable=max_allowed_packet=8M</font></code>指定一个更大的缓冲区来启动客户程序。</p>
		<p>如果你正在使用不允许你指定最大包大小的其他客户(例如<code><font face="新宋体"> DBI</font></code>)，你需要在你启动服务器时设置包大小。你可以使用<code><font face="新宋体">mysqld</font></code>的命令行选项设置<code><font face="新宋体">max_allowed_packet</font></code>为一个更大的尺寸。例如，如果你正期望将一个全长的<code><font face="新宋体">BLOB</font></code>存入一张表中，你将需要用<code><font face="新宋体">--set-variable=max_allowed_packet=24M</font></code>选项来启动服务器。</p>
		<p>　</p>
		<h3>18.2.7<code><font face="新宋体"> The table is full</font></code>错误</h3>
		<p>这个错误发生在内存临时表变得比<code><font face="新宋体">tmp_table_size</font></code>字节大时。为了避免这个问题，你可以使用<code><font face="新宋体">mysqld</font></code>的<code><font face="新宋体">-O tmp_table_size=#</font></code>选项来增加临时表的大小，或在你发出有疑问的查询之前使用SQL选项<code><font face="新宋体">SQL_BIG_TABLES</font></code>。见7.25<code><font face="新宋体"> SET OPTION</font></code>句法。</p>
		<p>你也可以使用<code><font face="新宋体">--big-tables</font></code>选项启动<code><font face="新宋体">mysqld</font></code>。这与为所有查询使用<code><font face="新宋体">SQL_BIG_TABLES</font></code>完全相同。</p>
		<p>
		</p>
		<h3>18.2.8<code><font face="新宋体"> Commands out of sync</font></code> in client错误</h3>
		<p>如果你在你的客户代码中得到<code><font face="新宋体">Commands out of sync; You can't run this command now</font></code>，你正在以错误的次序调用客户函数！</p>
		<p>这可能发生，例如，如果你正在使用<code><font face="新宋体">mysql_use_result()</font></code>并且在你已经调用了<code><font face="新宋体">mysql_free_result()</font></code>之前试图执行新查询。如果你在<code><font face="新宋体">mysql_use_result()</font></code>或<code><font face="新宋体">mysql_store_result()</font></code>之间试图执行返回数据的2个查询，它也可能发生。</p>
		<h3>18.2.9<code><font face="新宋体"> Ignoring user</font></code>错误</h3>
		<p>如果你得到下列错误： </p>
		<p>
				<code>
						<font face="新宋体">Found wrong password for user: 'some_user@some_host'; Ignoring user</font>
				</code>
		</p>
		<p>这意味着在<code><font face="新宋体">mysqld</font></code>启动时或在它再次装载权限表时，它在<code><font face="新宋体">user</font></code>表中找到了一个有一个无效口令的条目。结果，条目简单地被权限系统忽略。</p>
		<p>可能导致这个问题的原因和修正： 
</p>
		<ul>
				<li>你可能正在运行一个有一个老的<code><font face="新宋体">user</font></code>表的新版本<code><font face="新宋体">mysqld</font></code>。你可以通过执行<code><font face="新宋体">mysqlshow mysql user</font></code>看看口令字段是否少于 16个字符来检查它。如果是这样，你可以通过运行<code><font face="新宋体">scripts/add_long_password</font></code>脚本改正这种情况。 
</li>
				<li>用户有一个老式的口令(8个字符长)并且你没使用<code><font face="新宋体">--old-protocol</font></code>选项启动<code><font face="新宋体">mysqld</font></code>。用一个新口令更新在<code><font face="新宋体">user</font></code>表中的用户或用<code><font face="新宋体">--old-protocol</font></code>重启<code><font face="新宋体">mysqld</font></code>。 
</li>
				<li>你没有使用<code><font face="新宋体">PASSWORD()</font></code>函数在在<code><font face="新宋体">user</font></code>表中指定了一个口令。使用<code><font face="新宋体">mysql</font></code>以一个新口令更新在<code><font face="新宋体">user</font></code>表中的用户。确保使用<code><font face="新宋体">PASSWORD()</font></code>函数：<pre>mysql&gt; update user set password=PASSWORD('your password')
           where user='XXX';
</pre></li>
		</ul>
		<h3>18.2.10<code><font face="新宋体"> Table 'xxx' doesn't exist</font></code>错误</h3>
		<p>如果你得到错误<code><font face="新宋体">Table 'xxx' doesn't exist</font></code>或<code><font face="新宋体">Can't find file: 'xxx' (errno: 2)</font></code>，这意味着在当前数据库中没有名为<code><font face="新宋体">xxx</font></code>的表存在。</p>
		<p>注意，因为<strong>MySQL</strong>使用目录和文件存储数据库和表，数据库和表名件是<strong>区分大小写的</strong>！（在Win32上，数据库和表名不是区分大小写的，但是在查询中对所有表的引用必须使用相同的大小写！）</p>
		<p>你可以用<code><font face="新宋体">SHOW TABLES</font></code>检查你在当前数据库中有哪个表。见7.21<code><font face="新宋体"> SHOW</font></code>句法(得到表、列的信息）。<br /></p>
		<h2>18.3 MySQL怎样处理一个溢出的磁盘</h2>
		<p>当出现一个磁盘溢出的情况时，<strong>MySQL</strong>做下列事情： 
</p>
		<ul>
				<li>它每分钟检查一次看是否有足够空间写入当前行。如果有足够的空间，它继续好像发生什么事情。 
</li>
				<li>每6分钟它将有关磁盘溢出的警告写入日志文件。 </li>
		</ul>
		<p>为了缓和这个问题，你可以采取下列行动： 
</p>
		<ul>
				<li>继续，你只需释放足够的空闲磁盘空间以便插入所有记录。 
</li>
				<li>放弃线程，你必须发一个<code><font face="新宋体">mysqladmin kill</font></code>到线程。在下一次检查磁盘时，线程将被放弃(在1分钟内)。 
</li>
				<li>注意，其他线程可能正在等待引起“磁盘溢出”条件的表。如果你有几个“锁定的”的线程，杀死正在等待磁盘溢出条件的那个线程将允许其他线程继续。 </li>
		</ul>
		<h2>18.4 如何从一个文本文件运行SQL命令</h2>
		<p>一般地，<code><font face="新宋体">mysql</font></code>客户被交互性地使用，象这样：</p>
		<pre>shell&gt; mysql database</pre>
		<p>然而，也可以把你的SQL命令放在一个文件中并且告诉<code><font face="新宋体">mysql</font></code>从该文件读取其输入。要想这样做，创造一个文本文件<tt><font face="新宋体">“text_file”</font></tt>，它包含你想要执行的命令。然后如下那样调用<code><font face="新宋体">mysql</font></code>：</p>
		<pre>shell&gt; mysql database &lt; text_file
</pre>
		<p>你也能启动有一个<code><font face="新宋体">USE db_name</font></code>语句的文本文件。在这种情况下，在命令行上指定数据库名是不必要的：</p>
		<pre>shell&gt; mysql &lt; text_file
</pre>
		<pre>见12.1 不同的MySQL程序概述。 </pre>
		<h2>18.5 MySQL在哪儿存储临时文件</h2>
		<p>
				<strong>MySQL</strong>使用<code><font face="新宋体">TMPDIR</font></code>环境变量的值作为存储临时文件的目录的路径名。如果你没有设置<code><font face="新宋体">TMPDIR</font></code>，<strong>MySQL</strong>使用系统缺省值，它通常是<tt><font face="新宋体">“/tmp”</font></tt>或<tt><font face="新宋体">“/usr/tmp”</font></tt>。如果包含你的临时文件目录的文件系统太小，你应该编辑<code><font face="新宋体">safe_mysqld</font></code>设定<code><font face="新宋体">TMPDIR</font></code>指向你有足够空间的一个文件系统！你也可以使用<code><font face="新宋体">mysqld的--tmpdir</font></code>选项目设置临时目录。</p>
		<p>
				<strong>MySQL</strong>以“隐含文件”创建所有临时文件。这保证了如果<code><font face="新宋体">mysqld</font></code>被终止，临时文件也将被删除。使用隐含文件的缺点是你将看不到一个大的临时文件填满了临时文件目录所在的文件系统。</p>
		<p>当排序(<code><font face="新宋体">ORDER BY</font></code>或<code><font face="新宋体">GROUP BY</font></code>)时，<strong>MySQL</strong>通常使用一个或两个临时文件。最大磁盘空间需求是：</p>
		<pre>(存储东西的长度 + sizeof (数据库指针))
* 匹配的行数
* 2
</pre>
		<p>
				<code>
						<font face="新宋体">sizeof(数据库指针)</font>
				</code>通常是4，但是在未来对确实很大的表可能增加。</p>
		<p>对一些<code><font face="新宋体">SELECT</font></code>查询，<strong>MySQL</strong>也创建临时SQL表。这些没被隐含且有<tt><font face="新宋体">“SQL_*”</font></tt>格式的名字。</p>
		<p>
				<code>
						<font face="新宋体">ALTER TABLE</font>
				</code>和<code><font face="新宋体">OPTIMIZE TABLE</font></code>在原数据库表的同一个目录中创建一张临时表。</p>
		<h2>18.6 怎样保护<tt><font face="新宋体">“/tmp/mysql.sock ”</font></tt>不被删除</h2>
		<p>如果你有这个问题，事实上任何人可以删除<strong>MySQL</strong>通讯套接字<tt><font face="新宋体">“/tmp/mysql.sock”</font></tt>，在Unix的大多数版本上，你能通过为其设置<code><font face="新宋体">sticky</font></code>（t）位来保护你的<tt><font face="新宋体">“/tmp”</font></tt>文件系统。作为<code><font face="新宋体">root</font></code>登录并且做下列事情：</p>
		<pre>shell&gt; chmod +t /tmp
</pre>
		<p>这将保护你的<tt><font face="新宋体">“/tmp”</font></tt>文件系统使得文件仅能由他们的所有者或超级用户(<code><font face="新宋体">root</font></code>)删除。</p>
		<p>你能执行<code><font face="新宋体">ls -ld /tmp</font></code>检查<code><font face="新宋体">sticky</font></code>位是否被设置，如果最后一位许可位是<code><font face="新宋体">t</font></code>，该位被设置了。</p>
		<h2>18.7<code><font face="新宋体"> Access denied</font></code>错误</h2>
		<p>见6.6 权限系统如何工作。并且特别要看6.13 引起<code><font face="新宋体">Access denied</font></code>错误的原因。 </p>
		<h2>18.8 怎样作为一个一般用户运行MySQL</h2>
		<p>
				<strong>MySQL</strong>服务器<code><font face="新宋体">mysqld</font></code>能被任何用户启动并运行。为了将<code><font face="新宋体">mysqld</font></code>改由Unix用户<code><font face="新宋体">user_name</font></code>来运行，你必须做下列事情： 
</p>
		<ol>
				<li>如果它正在运行，停止服务器(使用<code><font face="新宋体">mysqladmin shutdown</font></code>)。 
</li>
				<li>改变数据库目录和文件以便<code><font face="新宋体">user_name</font></code>有权限读和写文件(你可能需要作为Unix的<code><font face="新宋体">root</font></code>用户才能做到)：<pre>shell&gt; chown -R user_name /path/to/mysql/datadir
</pre><p>如果在<strong>MySQL</strong>数据目录中的目录或文件是符号链接，你也将需要顺着那些链接并改变他们指向的目录和文件。<code><font face="新宋体">chown -R</font></code>不能跟随符号链接。</p></li>
				<li>以<code><font face="新宋体">user_name</font></code>用户启动服务器，或如果你正在使用<strong>MySQL</strong> 3.22或以后版本，以Unix<code><font face="新宋体"> root</font></code>用户启动<code><font face="新宋体">mysqld</font></code>并使用<code><font face="新宋体">--user=user_name</font></code>选项，<code><font face="新宋体">mysqld</font></code>将在接受任何连接之前切换到以Unix <code><font face="新宋体">user_name</font></code>用户运行。 
</li>
				<li>如果在系统被重新启动时，你使用<code><font face="新宋体">mysql.server</font></code>脚本启动<code><font face="新宋体">mysqld</font></code>，你应该编辑<code><font face="新宋体">mysql.server</font></code>用<code><font face="新宋体">su</font></code>以用户<code><font face="新宋体">user_name</font></code>运行<code><font face="新宋体">mysqld</font></code>，或使用<code><font face="新宋体">--user</font></code>选项调用<code><font face="新宋体">mysqld</font></code>。（不改变<code><font face="新宋体">safe_mysqld</font></code>是必要的。） </li>
		</ol>
		<p>现在，你的<code><font face="新宋体">mysqld</font></code>进程应该正在作为Unix用户<code><font face="新宋体">user_name</font></code>运行，并运行完好。尽管有一件事情没有变化：权限表的内容。缺省 地(就在运行了脚本<code><font face="新宋体">mysql_install_db</font></code>安装的权限表后)，<strong>MySQL</strong>用户<code><font face="新宋体">root</font></code>是唯一有存取<code><font face="新宋体">mysql</font></code>数据库或创建或抛弃数据库权限的用户。除非你改变了那些权限，否则他们仍然保持。当你作为一个Unix用户而不是<code><font face="新宋体">root</font></code>登录时，这不应该阻止你作为<strong>MySQL</strong><code><font face="新宋体">root</font></code>用户来存取<strong>MySQL</strong>；只要为客户程序指定<code><font face="新宋体">-u root</font></code>的选项。</p>
		<p>注意通过在命令行上提供<code><font face="新宋体">-u root</font></code>，作为<code><font face="新宋体">root</font></code>存取<strong>MySQL</strong>，与作为Unix <code><font face="新宋体">root</font></code>用户或其他Unix用户运行<strong>MySQL</strong><em>没有关系</em>。<strong>MySQL</strong>的存取权限和用户名与Unix用户名字是完全分开的。唯一与Unix用户名有关的是，如果当你调用一个客户程序时，你不提供一个<code><font face="新宋体">-u</font></code>选项，客户将试图使用你的Unix登录名作为你的<strong>MySQL</strong>用户名进行连接。</p>
		<p>如果你的Unix机器本身不安全，你可能应该至少在存取表中为<strong>MySQL</strong><code><font face="新宋体">root</font></code>用户放上一个口令。否则，在那台机器上有一个帐号的任何用户能运行<code><font face="新宋体">mysql -u root db_name</font></code>并且做他喜欢做的任何事情。</p>
		<h2>18.9 怎样重新设置一个忘记的口令</h2>
		<p>如果你忘记了<strong>MySQL</strong>的<code><font face="新宋体">root</font></code>用户的口令，你可以用下列过程恢复它。 
</p>
		<ol>
				<li>通过发送一个<code><font face="新宋体">kill</font></code>（不是<code><font face="新宋体">kill -9</font></code>)到<code><font face="新宋体">mysqld</font></code>服务器来关闭mysqld服务器。pid 被保存在一个<code><font face="新宋体">.pid</font></code>文件中，通常在<strong>MySQL</strong>数据库目录中：<pre>kill `cat /mysql-data-directory/hostname.pid`
</pre><p>你必须是一个UNIX<code><font face="新宋体"> root</font></code>用户或运行服务器的相同用户做这个。</p></li>
				<li>使用<code><font face="新宋体">--skip-grant-tables</font></code>选项重启<code><font face="新宋体">mysqld</font></code>。 
</li>
				<li>用<code><font face="新宋体">mysql -h hostname mysql</font></code>连接mysqld服务器并且用一条<code><font face="新宋体">GRANT</font></code>命令改变口令。见7.26<code><font face="新宋体"> GRANT</font></code>和<code><font face="新宋体">REVOKE</font></code>句法。你也可以用<code><font face="新宋体">mysqladmin -h hostname -u user password 'new password'</font></code> 进行。 
</li>
				<li>用<code><font face="新宋体">mysqladmin -h hostname flush-privileges</font></code>或用SQL命令<code><font face="新宋体">FLUSH PRIVILEGES</font></code>来装载权限表。 </li>
		</ol>
		<h2>18.10 文件许可权限问题</h2>
		<p>如果你有与文件许可有关的问题，例如，如果当你创建一张表时，<code><font face="新宋体">mysql</font></code>发出下列错误消息： </p>
		<pre>ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13) 
</pre>
		<p>那么可能是在<code><font face="新宋体">mysqld</font></code>启动时，环境变量<code><font face="新宋体">UMASK</font></code>可能设置不正确。缺省的umask值是<code><font face="新宋体">0660</font></code>。你可以如下启动<code><font face="新宋体">safe_mysqld</font></code>改变其行为：</p>
		<pre>shell&gt; UMASK=384  # = 600 in octal
shell&gt; export UMASK
shell&gt; /path/to/safe_mysqld &amp;
</pre>
		<h2>18.11 文件没找到</h2>
		<p>如果你从<strong>MySQL</strong>得到<code><font face="新宋体">ERROR '...' not found (errno: 23)</font></code>, <code><font face="新宋体">Can't open file: ... (errno: 24)</font></code>或任何其他有<code><font face="新宋体">errno 23</font></code>或<code><font face="新宋体">errno 24</font></code>的错误，它意味着，你没有为<strong>MySQL</strong>分配足够的文件描述符。你能使用<code><font face="新宋体">perror</font></code>实用程序得到错误号含义是什么的描述：</p>
		<pre>shell&gt; perror 23
File table overflow
shell&gt; perror 24
Too many open files
</pre>
		<p>这里的问题是<code><font face="新宋体">mysqld</font></code>正在试图同时保持打开太多的文件。你也可以告诉<code><font face="新宋体">mysqld</font></code>一次不打开那么多的文件，或增加<code><font face="新宋体">mysqld</font></code>可得到的文件描述符数量。</p>
		<p>为了告诉<code><font face="新宋体">mysqld</font></code>一次保持打开更少的文件，你可以通过使用<code><font face="新宋体">safe_mysqld</font></code>的<code><font face="新宋体">-O table_cache=32</font></code>选项（缺省值是64)使表缓冲更小。减小<code><font face="新宋体">max_connections</font></code>值也将减少打开文件的数量(缺省值是90)。</p>
		<p>要想改变<code><font face="新宋体">mysqld</font></code>可用的文件描述符数量，修改<code><font face="新宋体">safe_mysqld</font></code>脚本。脚本中有一条注释了的行<code><font face="新宋体">ulimit -n 256</font></code>。你可以删除<code><font face="新宋体">'#'</font></code>字符来去掉该行的注释，并且改变数字256改变为<code><font face="新宋体">mysqld</font></code>可用的文件描述符的数量。</p>
		<p>
				<code>
						<font face="新宋体">ulimit</font>
				</code>能增加文件描述符的数量，但是只能到操作系统强加的限制。如果你需要增加每个进程可用的文件描述符数量的OS限制，参见你的操作系统文档。</p>
		<p>注意，如果你运行<code><font face="新宋体">tcsh</font></code>外壳，<code><font face="新宋体">ulimit</font></code>将不工作！当你请求当前限制时，<code><font face="新宋体">tcsh</font></code>也将报告不正确的值！在这种情况下，你应该用<code><font face="新宋体">sh</font></code>启动<code><font face="新宋体">safe_mysqld</font></code>！<br /></p>
		<h2>18.12 使用<code><font face="新宋体">DATE</font></code>列的问题</h2>
		<p>一个<code><font face="新宋体">DATE</font></code>值的格式是<code><font face="新宋体">'YYYY-MM-DD'</font></code>。根据ANSI SQL，不允许其他格式。你应该在<code><font face="新宋体">UPDATE</font></code>表达式和<code><font face="新宋体">SELECT</font></code>语句的WHERE子句中使用这个格式。例如：</p>
		<pre>mysql&gt; SELECT * FROM tbl_name WHERE date &gt;= '1997-05-05';
</pre>
		<p>为了方便，如果日期用在数字上下文，<strong>MySQL</strong>自动变换一个日期到一个数字(并且反过来也如此)。当更新时和将一个日期与<code><font face="新宋体">TIMESTAMP</font></code>、<code><font face="新宋体">DATE</font></code>或<code><font face="新宋体">DATETIME</font></code>列比较的一个<code><font face="新宋体">WHERE</font></code>子句中，也是足够灵活以允许一种“宽松”的字符串格式。（宽松格式意味着任何标点字符用作在部件之间的分割符。例如，<code><font face="新宋体">'1998-08-15'</font></code>和<code><font face="新宋体">'1998#08#15'</font></code>是等价的。）<strong>MySQL</strong>也能变换不包含分割符的一个字符串(例如<code><font face="新宋体"> '19980815'</font></code>)，如果它作为一个日期说得通。</p>
		<p>特殊日期<code><font face="新宋体">'0000-00-00'</font></code>可以作为<code><font face="新宋体">'0000-00-00'</font></code>被存储和检索<code><font face="新宋体">。</font></code>当通过<strong>MyODBC</strong>使用一个<code><font face="新宋体">'0000-00-00'</font></code>日期时，在<strong>MyODBC</strong> 2.50.12和以上版本，它将自动被转换为<code><font face="新宋体">NULL</font></code>，因为ODBC不能处理这种日期。</p>
		<p>因为<strong>MySQL</strong>实行了上述的变换，下列语句可以工作：</p>
		<pre>mysql&gt; INSERT INTO tbl_name (idate) VALUES (19970505);
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('19970505');
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('97-05-05');
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('1997.05.05');
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('1997 05 05');
mysql&gt; INSERT INTO tbl_name (idate) VALUES ('0000-00-00');

mysql&gt; SELECT idate FROM tbl_name WHERE idate &gt;= '1997-05-05';
mysql&gt; SELECT idate FROM tbl_name WHERE idate &gt;= 19970505;
mysql&gt; SELECT mod(idate,100) FROM tbl_name WHERE idate &gt;= 19970505;
mysql&gt; SELECT idate FROM tbl_name WHERE idate &gt;= '19970505';
</pre>
		<p>然而，下列将不工作： </p>
		<pre>mysql&gt; SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;
</pre>
		<p>
				<code>
						<font face="新宋体">STRCMP()</font>
				</code>是字符串函数，因此它将<code><font face="新宋体">idate</font></code>转换为一个字符串并且实施字符串比较。它不将<code><font face="新宋体">'19970505'</font></code>转换为一个日期并实施日期比较。</p>
		<p>注意，<strong>MySQL</strong>不检查日期是否正确。如果你存储一个不正确的日期，例如<code><font face="新宋体">'1998-2-31'</font></code>，错误的日期将被存储。如果日期不能被变换到任何合理的值，在<code><font face="新宋体">DATE</font></code>字段中存储一个<code><font face="新宋体">0</font></code>。这主要是一个速度问题并且我们认为检查日期是应用程序的责任，而不服务器。</p>
		<p>
		</p>
		<h2>18.13 时区问题</h2>
		<p>如果你有一个问题，<code><font face="新宋体">SELECT NOW()</font></code>以GMT时间返回值而不是你的本地时间，你必须设定<code><font face="新宋体">TZ</font></code>环境变量为你的当前时区。这应该在服务器运行的环境进行，例如在<code><font face="新宋体">safe_mysqld</font></code>或<code><font face="新宋体">mysql.server</font></code>中。</p>
		<p>
		</p>
		<h2>18.14 在搜索中的大小写敏感性</h2>
		<p>缺省地，<strong>MySQL</strong>搜索是大小写不敏感的(尽管有一些字符集从来不是忽略大小写的，例如<code><font face="新宋体">捷克语</font></code>)。这意味着，如果你用<code><font face="新宋体">col_name LIKE 'a%'</font></code>搜寻，你将得到所有以<code><font face="新宋体">A</font></code>或<code><font face="新宋体">a</font></code>开始的列值。如果你想要使这个搜索大小写敏感，使用象<code><font face="新宋体">INDEX(col_name, "A")=0</font></code>检查一个前缀。或如果列值必须确切是<code><font face="新宋体">"A"</font></code>，使用<code><font face="新宋体">STRCMP(col_name, "A") = 0</font></code>。</p>
		<p>简单的比较操作(<code><font face="新宋体">&gt;=、&gt;、= 、&lt; 、&lt;=</font></code>、排序和聚合)是基于每个字符的“排序值”。有同样排序值的字符(象E，e和'e)被视为相同的字符！</p>
		<p>
				<code>
						<font face="新宋体">LIKE</font>
				</code>比较在每个字符的大写值上进行(E==e 但是E&lt;&gt;'e）。</p>
		<p>如果你想要一个列总是被当作大小写敏感的方式，声明它为<code><font face="新宋体">BINARY</font></code>。见7.7<code><font face="新宋体"> CREATE TABLE</font></code>句法。</p>
		<p>如果你使用以所谓的big5编码的中文数据，你要使所有的字符列是<code><font face="新宋体">BINARY</font></code>，它可行，是因为big5编码字符的排序顺序基于 ASCII代码的顺序。</p>
		<p>
		</p>
		<h2>18.15 <code><font face="新宋体">NULL</font></code>值问题</h2>
		<p>
				<code>
						<font face="新宋体">NULL</font>
				</code>值的概念是造成SQL的新手的混淆的普遍原因，他们经常认为<code><font face="新宋体">NULL</font></code>是和一个空字符串<code><font face="新宋体">''</font></code>的一样的东西。不是这样的！例如，下列语句是完全不同的：</p>
		<pre>mysql&gt; INSERT INTO my_table (phone) VALUES (NULL);
mysql&gt; INSERT INTO my_table (phone) VALUES ("");
</pre>
		<p>两个语句把值插入到<code><font face="新宋体">phone</font></code>列，但是第一个插入一个<code><font face="新宋体">NULL</font></code>值而第二个插入一个空字符串。第一个的含义可以认为是“电话号码不知道”，而第二个则可意味着“她没有电话”。 </p>
		<p>在SQL中，<code><font face="新宋体">NULL</font></code>值在于任何其他值甚至<code><font face="新宋体">NULL</font></code>值比较时总是假的（FALSE）。包含<code><font face="新宋体">NULL</font></code>的一个表达式总是产生一个<code><font face="新宋体">NULL</font></code>值，除非在包含在表达式中的运算符和函数的文档中指出。在下列例子，所有的列返回<code><font face="新宋体">NULL</font></code>：</p>
		<pre>mysql&gt; SELECT NULL,1+NULL,CONCAT('Invisible',NULL);
</pre>
		<p>如果你想要寻找值是<code><font face="新宋体">NULL</font></code>的列，你不能使用<code><font face="新宋体">=NULL</font></code>测试。下列语句不返回任何行，因为对任何表达式，<code><font face="新宋体">expr = NULL</font></code>是假的：</p>
		<pre>mysql&gt; SELECT * FROM my_table WHERE phone = NULL;
</pre>
		<p>要想寻找<code><font face="新宋体">NULL</font></code>值，你必须使用<code><font face="新宋体">IS NULL</font></code>测试。下例显示如何找出<code><font face="新宋体">NULL</font></code>电话号码和空的电话号码：</p>
		<pre>mysql&gt; SELECT * FROM my_table WHERE phone IS NULL;
mysql&gt; SELECT * FROM my_table WHERE phone = "";
</pre>
		<p>在<strong>MySQL</strong>中，就像很多其他的SQL服务器一样，你不能索引可以有<code><font face="新宋体">NULL</font></code>值的列。你必须声明这样的列为<code><font face="新宋体">NOT NULL</font></code>，而且，你不能插入<code><font face="新宋体">NULL</font></code>到索引的列中。</p>
		<p>当用<code><font face="新宋体">LOAD DATA INFILE</font></code>读取数据时，空列用<code><font face="新宋体">''</font></code>更新。如果你想要在一个列中有<code><font face="新宋体">NULL</font></code>值，你应该在文本文件中使用<code><font face="新宋体">\N</font></code>。字面上的词<code><font face="新宋体">'NULL'</font></code>也可以在某些情形下使用。见7.16<code><font face="新宋体"> LOAD DATA INFILE</font></code>句法。</p>
		<p>当使用<code><font face="新宋体">ORDER BY</font></code>时，首先呈现<code><font face="新宋体">NULL</font></code>值。如果你用<code><font face="新宋体">DESC</font></code>以降序排序，<code><font face="新宋体">NULL</font></code>值最后显示。当使用<code><font face="新宋体">GROUP BY</font></code>时，所有的<code><font face="新宋体">NULL</font></code>值被认为是相等的。</p>
		<p>为了有助于<code><font face="新宋体">NULL</font></code>的处理，你能使用<code><font face="新宋体">IS NULL</font></code>和<code><font face="新宋体">IS NOT NULL</font></code>运算符和<code><font face="新宋体">IFNULL()</font></code>函数。</p>
		<p>对某些列类型，<code><font face="新宋体">NULL</font></code>值被特殊地处理。如果你将<code><font face="新宋体">NULL</font></code>插入表的第一个<code><font face="新宋体">TIMESTAMP</font></code>列，则插入当前的日期和时间。如果你将<code><font face="新宋体">NULL</font></code>插入一个<code><font face="新宋体">AUTO_INCREMENT</font></code>列，则插入顺序中的下一个数字。</p>
		<p>　</p>
		<h2>18.16 <code><font face="新宋体">alias</font></code>问题</h2>
		<p>你可以在<code><font face="新宋体">GROUP BY</font></code>、<code><font face="新宋体">ORDER BY</font></code>或在<code><font face="新宋体">HAVING</font></code>部分中使用别名引用列。别名也可以用来为列取一个更好点的名字：</p>
		<pre>SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt &gt; 0;
SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt &gt; 0;
SELECT id AS "Customer identity" FROM table_name;
</pre>
		<p>注意，你的 ANSI SQL 不允许你在一个<code><font face="新宋体">WHERE</font></code>子句中引用一个别名。这是因为在<code><font face="新宋体">WHERE</font></code>代码被执行时，列值还可能没有终结。例如下列查询是<strong>不合法</strong>：</p>
		<pre>SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt &gt; 0 GROUP BY id;
</pre>
		<p>
				<code>
						<font face="新宋体">WHERE</font>
				</code>语句被执行以确定哪些行应该包括<code><font face="新宋体">GROUP BY</font></code>部分中，而<code><font face="新宋体">HAVING</font></code>用来决定应该只用结果集合中的哪些行。 </p>
		<h2>18.17 从关联的表中删除行</h2>
		<p>因为<strong>MySQL</strong>不支持子选择或在<code><font face="新宋体">DELETE</font></code>语句中使用多个表，你应该使用下列方法从2个关联的表中删除行： 
</p>
		<ol>
				<li>在主表中基于某个<code><font face="新宋体">WHERE</font></code>条件<code><font face="新宋体">SELECT</font></code>行。 
</li>
				<li>在主表中基于相同的条件<code><font face="新宋体">DELETE</font></code>行。 
</li>
				<li>
						<code>
								<font face="新宋体">DELETE FROM related_table WHERE related_column IN (selected_rows)</font>
						</code>
				</li>
		</ol>
		<p>如果在<code><font face="新宋体">related_column</font></code>查询中的字符的全部数量超过1,048,576(缺省值<code><font face="新宋体">max_allowed_packet</font></code>），你应该分成更小的部分并且执行多个<code><font face="新宋体">DELETE</font></code>语句。如果<code><font face="新宋体">related_column</font></code>是一个索引，你每次只删除100-1000个<code><font face="新宋体">related_column</font></code> id将可能使得<code><font face="新宋体">DELETE</font></code>最快。如果<code><font face="新宋体">related_column</font></code>不是一个索引，速度与<code><font face="新宋体">IN</font></code>子句中参数的数量无关。<br /></p>
		<h2>18.18 解决没有匹配行的问题</h2>
		<p>如果你有一个复杂的查询，涉及多个表，但没有返回任何行，你应该使用下列过程查找你的询问有什么不对： 
</p>
		<ol>
				<li>
						<code>
								<font face="新宋体">EXPLAIN</font>
						</code>测试查询并且检查你是否能找出显然是错误的一些东西。见7.22<code><font face="新宋体"> EXPLAIN</font></code>句法(得到关于一个<code><font face="新宋体">SELECT</font></code>的信息)。 
</li>
				<li>仅选择那些在<code><font face="新宋体">WHERE</font></code>子句中使用的字段。 
</li>
				<li>一次从查询中删除一个表，直到它返回一些行。如果表很大，对查询使用<code><font face="新宋体">LIMIT 10</font></code>是一个好主意。 
</li>
				<li>对应该已经匹配一行的列做一个<code><font face="新宋体">SELECT</font></code>，针对从询问中做后被删除的表。 
</li>
				<li>如果你将<code><font face="新宋体">FLOAT</font></code>或<code><font face="新宋体">DOUBLE</font></code>列与有小数的数字进行比较，你不能使用<code><font face="新宋体">=</font></code>!。这个问题在大多数计算机语言是常见的，因为浮点值不是准确的值。<pre>mysql&gt; SELECT * FROM table_name WHERE float_column=3.5;
   -&gt;
mysql&gt; SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;
</pre><p>在大多数情况下，将<code><font face="新宋体">FLOAT</font></code>改成一个<code><font face="新宋体">DOUBLE</font></code>将修正它！</p></li>
				<li>如果你仍然不能发现错误是什么，创建一个最小的可运行<code><font face="新宋体">mysql test &lt; query.sql</font></code>的测试来显示你的问题。你可以用<code><font face="新宋体">mysqldump --quick database tables &gt; query.sql</font></code>创建一个测试文件，在一个编辑器编辑文件，删除一些插入行(如果有太多这些语句)并且在文件末尾加入你的选择语句。测试你仍然有问题，可以这样做：<pre>shell&gt; mysqladmin create test2
shell&gt; mysql test2 &lt; query.sql
</pre><p>使用<code><font face="新宋体">mysqlbug</font></code>的邮寄测试文件到mysql@lists.mysql.com。</p></li>
		</ol>
		<h2>18.19 与<code><font face="新宋体">ALTER TABLE</font></code>有关的问题</h2>
		<p>如果<code><font face="新宋体">ALTER TABLE</font></code>死于这样一个错误：</p>
		<pre>Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17)
</pre>
		<p>问题可能是<strong>MySQL</strong>在前一个<code><font face="新宋体">ALTER TABLE</font></code>中已经崩溃并且留下了一个名为<tt><font face="新宋体">“A-xxx”</font></tt>或<tt><font face="新宋体">“B-xxx”</font></tt>的老的数据库表。在这种情况下，到<strong>MySQL</strong>数据目录中并删除所有名字以<code><font face="新宋体">A-</font></code>或<code><font face="新宋体">B-</font></code>开始的文件。（你可以把他们移到别的地方而不是删除他们)。</p>
		<p>
				<code>
						<font face="新宋体">ALTER TABLE</font>
				</code>工作方式是： 
</p>
		<ul>
				<li>以要求的改变创建一个名为<tt><font face="新宋体">“A-xxx”</font></tt>的新表。 
</li>
				<li>从老表把所有行拷贝到<tt><font face="新宋体">“A-xxx”</font></tt>。 
</li>
				<li>老表被改名为<tt><font face="新宋体">“B-xxx”</font></tt>。 
</li>
				<li>
						<tt>
								<font face="新宋体">“A-xxx”</font>
						</tt>被改名为你的老表的名字。 
</li>
				<li>
						<tt>
								<font face="新宋体">“B-xxx”</font>
						</tt>被删除。 </li>
		</ul>
		<p>如果某些改名操作出错，<strong>MySQL</strong>试图还原改变。如果出错严重(当然，这不应该发生。)，<strong>MySQL</strong>可能留下了老表为<tt><font face="新宋体">“B-xxx”</font></tt>但是一个简单改名就应该恢复你的数据。</p>
		<h2>18.20 怎样改变一张表中列的顺序</h2>
		<p>SQL的要点是中抽象应用程序以避免数据存储格式。你应该总是以你想要检索数据的意愿指定顺序。例如：</p>
		<pre>SELECT col_name1, col_name2, col_name3 FROM tbl_name;
</pre>
		<p>将以<code><font face="新宋体">col_name1</font></code>、<code><font face="新宋体">col_name2</font></code>、<code><font face="新宋体">col_name3</font></code>的顺序返回列，而：</p>
		<pre>SELECT col_name1, col_name3, col_name2 FROM tbl_name; 
</pre>
		<p>将以<code><font face="新宋体">col_name1</font></code>、<code><font face="新宋体">col_name3</font></code>、<code><font face="新宋体">col_name2</font></code>的顺序返回列。</p>
		<p>在一个应用程序中，你应该<strong>决不</strong>基于他们的位置使用<code><font face="新宋体">SELECT *</font></code> 检索列，因为被返回的列的顺序永远<strong>不能</strong>保证；对你的数据库的一个简单改变可能导致你的应用程序相当有戏剧性地失败。</p>
		<p>不管怎样，如果你想要改变列的顺序，你可以这样做： 
</p>
		<ol>
				<li>以正确的列顺序创建一张新表。 
</li>
				<li>执行<code><font face="新宋体">INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table</font></code>. 
</li>
				<li>删除或改名<code><font face="新宋体">old_table</font></code>。 
</li>
				<li>
						<code>
								<font face="新宋体">ALTER TABLE new_table RENAME old_table</font>
						</code>。</li>
		</ol>
<img src ="http://www.blogjava.net/seaairland/aggbug/44773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-05-06 16:57 <a href="http://www.blogjava.net/seaairland/archive/2006/05/06/44773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有效和正确定义hashCode()和equals()</title><link>http://www.blogjava.net/seaairland/archive/2006/05/04/44522.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Thu, 04 May 2006 06:01:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/05/04/44522.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/44522.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/05/04/44522.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/44522.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/44522.html</trackback:ping><description><![CDATA[有效和正确定义hashCode()和equals()<br /><br /><br /><br />级别：入门级<br /><br /><br /><br />Brian Goetz (brian@quiotix.com)<br />Quiotix Corp首席顾问<br />2003年 8 月<br /><br /><br />每个Java对象都有hashCode()和 equals()方法。许多类忽略（Override)这些方<br /><br />法的缺省实施,以在对象实例之间提供更深层次的语义可比性。在Java理念和实践<br /><br />这一部分，Java开发人员Brian Goetz向您介绍在创建Java类以有效和准确定义<br /><br />hashCode()和equals()时应遵循的规则和指南。您可以在讨论论坛与作者和其它<br /><br />读者一同探讨您对本文的看法。(您还可以点击本文顶部或底部的讨论进入论坛。<br /><br />)<br /><br />虽然Java语言不直接支持关联数组 -- 可以使用任何对象作为一个索引的数组 -- <br /><br />但在根Object类中使用hashCode()方法明确表示期望广泛使用HashMap(及其前辈<br /><br />Hashtable)。理想情况下基于散列的容器提供有效插入和有效检索；直接在对象<br /><br />模式中支持散列可以促进基于散列的容器的开发和使用。 <br /><br /><br /><br />定义对象的相等性<br />Object类有两种方法来推断对象的标识：equals()和hashCode()。一般来说，如<br /><br />果您忽略了其中一种，您必须同时忽略这两种，因为两者之间有必须维持的至关<br /><br />重要的关系。特殊情况是根据equals() 方法，如果两个对象是相等的，它们必须<br /><br />有相同的hashCode()值(尽管这通常不是真的)。 <br /><br /><br /><br />特定类的equals()的语义在Implementer的左侧定义；定义对特定类来说equals()<br /><br />意味着什么是其设计工作的一部分。Object提供的缺省实施简单引用下面等式： <br /><br /><br /><br />  public boolean equals(Object obj) { return (this == obj); }<br /><br /><br />在这种缺省实施情况下，只有它们引用真正同一个对象时这两个引用才是相等的<br /><br />。同样，Object提供的hashCode()的缺省实施通过将对象的内存地址对映于一个<br /><br />整数值来生成。由于在某些架构上，地址空间大于int值的范围，两个不同的对象<br /><br />有相同的hashCode()是可能的。如果您忽略了hashCode()，您仍旧可以使用<br /><br />System.identityHashCode()方法来接入这类缺省值。 <br /><br /><br /><br />忽略 equals() -- 简单实例 <br />缺省情况下，equals()和hashCode()基于标识的实施是合理的，但对于某些类来<br /><br />说，它们希望放宽等式的定义。例如，Integer类定义equals() 与下面类似： <br /><br /><br /><br />  public boolean equals(Object obj) {<br />    return (obj instanceof Integer <br />            &amp;&amp; intValue() == ((Integer) obj).intValue());<br />  }<br /><br /><br />在这个定义中，只有在包含相同的整数值的情况下这两个Integer对象是相等的。<br /><br />结合将不可修改的Integer，这使得使用Integer作为HashMap中的关键字是切实可<br /><br />行的。这种基于值的Equal方法可以由Java类库中的所有原始封装类使用，如<br /><br />Integer、Float、Character和Boolean以及String(如果两个String对象包含相同<br /><br />顺序的字符，那它们是相等的)。由于这些类都是不可修改的并且可以实施<br /><br />hashCode()和equals()，它们都可以做为很好的散列关键字。 <br /><br /><br /><br />为什么忽略 equals()和hashCode()?<br />如果Integer不忽略equals() 和 hashCode()情况又将如何?如果我们从未在<br /><br />HashMap或其它基于散列的集合中使用Integer作为关键字的话，什么也不会发生<br /><br />。但是，如果我们在HashMap中使用这类Integer对象作为关键字，我们将不能够<br /><br />可*地检索相关的值，除非我们在get()调用中使用与put()调用中极其类似的<br /><br />Integer实例。这要求确保在我们的整个程序中，只能使用对应于特定整数值的<br /><br />Integer对象的一个实例。不用说，这种方法极不方便而且错误频频。 <br /><br /><br /><br />Object的interface contract要求如果根据 equals()两个对象是相等的，那么它<br /><br />们必须有相同的hashCode()值。当其识别能力整个包含在equals()中时，为什么<br /><br />我们的根对象类需要hashCode()？hashCode()方法纯粹用于提高效率。Java平台<br /><br />设计人员预计到了典型Java应用程序中基于散列的集合类（Collection Class)的<br /><br />重要性--如Hashtable、HashMap和HashSet，并且使用equals()与许多对象进行比<br /><br />较在计算方面非常昂贵。使所有Java对象都能够支持 hashCode()并结合使用基于<br /><br />散列的集合，可以实现有效的存储和检索。 <br /><br /><br /><br />实施equals()和hashCode()的需求<br />实施equals()和 hashCode()有一些限制，Object文件中列举出了这些限制。特别<br /><br />是equals()方法必须显示以下属性：<br /><br /><br />Symmetry：两个引用，a和 b,a.equals(b) if and only if b.equals(a) <br />Reflexivity：所有非空引用， a.equals(a) <br />Transitivity：If a.equals(b) and b.equals(c), then a.equals(c) <br />Consistency with hashCode()：两个相等的对象必须有相同的hashCode()值<br /><br />Object的规范中并没有明确要求equals()和 hashCode() 必须一致 -- 它们的结<br /><br />果在随后的调用中将是相同的，假设“不改变对象相等性比较中使用的任何信息<br /><br />。”这听起来象“计算的结果将不改变，除非实际情况如此。”这一模糊声明通<br /><br />常解释为相等性和散列值计算应是对象的可确定性功能，而不是其它。 <br /><br /><br /><br />对象相等性意味着什么？<br />人们很容易满足Object类规范对equals() 和 hashCode() 的要求。决定是否和如<br /><br />何忽略equals()除了判断以外，还要求其它。在简单的不可修值类中，如<br /><br />Integer(事实上是几乎所有不可修改的类)，选择相当明显 -- 相等性应基于基本<br /><br />对象状态的相等性。在Integer情况下，对象的唯一状态是基本的整数值。 <br /><br /><br /><br />对于可修改对象来说，答案并不总是如此清楚。equals() 和hashCode() 是否应<br /><br />基于对象的标识(象缺省实施)或对象的状态(象Integer和String)？没有简单的答<br /><br />案 -- 它取决于类的计划使用。对于象List和Map这样的容器来说，人们对此争论<br /><br />不已。Java类库中的大多数类，包括容器类，错误出现在根据对象状态来提供<br /><br />equals()和hashCode()实施。 <br /><br /><br /><br />如果对象的hashCode()值可以基于其状态进行更改，那么当使用这类对象作为基<br /><br />于散列的集合中的关键字时我们必须注意，确保当它们用于作为散列关键字时，<br /><br />我们并不允许更改它们的状态。所有基于散列的集合假设，当对象的散列值用于<br /><br />作为集合中的关键字时它不会改变。如果当关键字在集合中时它的散列代码被更<br /><br />改，那么将产生一些不可预测和容易混淆的结果。实践过程中这通常不是问题 -- <br /><br />我们并不经常使用象List这样的可修改对象做为HashMap中的关键字。 <br /><br /><br /><br />一个简单的可修改类的例子是Point，它根据状态来定义equals()和hashCode()。<br /><br />如果两个Point 对象引用相同的(x, y)座标，Point的散列值来源于x和y座标值的<br /><br />IEEE 754-bit表示，那么它们是相等的。 <br /><br /><br /><br />对于比较复杂的类来说，equals()和hashCode()的行为可能甚至受到superclass<br /><br />或interface的影响。例如，List接口要求如果并且只有另一个对象是List，而且<br /><br />它们有相同顺序的相同的Elements(由Element上的Object.equals() 定义)，List<br /><br />对象等于另一个对象。hashCode()的需求更特殊--list的hashCode()值必须符合<br /><br />以下计算： <br /><br /><br /><br />  hashCode = 1;<br />  Iterator i = list.iterator();<br />  while (i.hasNext()) {<br />      Object obj = i.next();<br />      hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());<br />  }<br /><br /><br />不仅仅散列值取决于list的内容，而且还规定了结合各个Element的散列值的特殊<br /><br />算法。(String类规定类似的算法用于计算String的散列值。) <br /><br /><br /><br />编写自己的equals()和hashCode()方法<br />忽略缺省的equals()方法比较简单，但如果不违反对称（Symmetry）或传递性<br /><br />（Transitivity）需求，忽略已经忽略的equals() 方法极其棘手。当忽略<br /><br />equals()时，您应该总是在equals()中包括一些Javadoc注释，以帮助那些希望能<br /><br />够正确扩展您的类的用户。 <br /><br /><br /><br />作为一个简单的例子，考虑以下类： <br /><br /><br /><br />  class A {<br />    final B someNonNullField;<br />    C someOtherField;<br />    int someNonStateField;<br />  }<br /><br /><br />我们应如何编写该类的equals()的方法？这种方法适用于许多情况： <br /><br /><br /><br />  public boolean equals(Object other) {<br />    // Not strictly necessary, but often a good optimization<br />    if (this == other)<br />      return true;<br />    if (!(other instanceof A))<br />      return false;<br />    A otherA = (A) other;<br />    return <br />      (someNonNullField.equals(otherA.someNonNullField))<br />        &amp;&amp; ((someOtherField == null) <br />            ? otherA.someOtherField == null <br />            : someOtherField.equals(otherA.someOtherField)));<br />  }<br /><br /><br />现在我们定义了equals()，我们必须以统一的方法来定义hashCode()。一种统一<br /><br />但并不总是有效的定义hashCode()的方法如下： <br /><br /><br /><br />  public int hashCode() { return 0; }<br /><br /><br />这种方法将生成大量的条目并显著降低HashMaps的性能，但它符合规范。一个更<br /><br />合理的hashCode()实施应该是这样： <br /><br /><br /><br />  public int hashCode() { <br />    int hash = 1;<br />    hash = hash * 31 + someNonNullField.hashCode();<br />    hash = hash * 31 <br />                + (someOtherField == null ? 0 : <br /><br />someOtherField.hashCode());<br />    return hash;<br />  }<br /><br /><br />注意：这两种实施都降低了类状态字段的equals()或hashCode()方法一定比例的<br /><br />计算能力。根据您使用的类，您可能希望降低superclass的equals()或hashCode<br /><br />()功能一部分计算能力。对于原始字段来说，在相关的封装类中有helper功能，<br /><br />可以帮助创建散列值，如Float.floatToIntBits。 <br /><br /><br /><br />编写一个完美的equals()方法是不现实的。通常，当扩展一个自身忽略了equals<br /><br />()的instantiable类时，忽略equals()是不切实际的，而且编写将被忽略的<br /><br />equals()方法(如在抽象类中)不同于为具体类编写equals()方法。关于实例以及<br /><br />说明的更详细信息请参阅Effective Java Programming Language Guide, Item 7 <br /><br />(参考资料) 。 <br /><br /><br /><br />有待改进?<br />将散列法构建到Java类库的根对象类中是一种非常明智的设计折衷方法 -- 它使<br /><br />使用基于散列的容器变得如此简单和高效。但是，人们对Java类库中的散列算法<br /><br />和对象相等性的方法和实施提出了许多批评。java.util中基于散列的容器非常方<br /><br />便和简便易用，但可能不适用于需要非常高性能的应用程序。虽然其中大部分将<br /><br />不会改变，但当您设计严重依赖于基于散列的容器效率的应用程序时必须考虑这<br /><br />些因素，它们包括： <br /><br /><br />太小的散列范围。使用int而不是long作为hashCode()的返回类型增加了散列冲突<br /><br />的几率。<br /><br /><br />糟糕的散列值分配。短strings和小型integers的散列值是它们自己的小整数，接<br /><br />近于其它“邻近”对象的散列值。一个循规导矩（Well-behaved）的散列函数将<br /><br />在该散列范围内更均匀地分配散列值。<br /><br /><br />无定义的散列操作。虽然某些类，如String和List，定义了将其Element的散列值<br /><br />结合到一个散列值中使用的散列算法，但语言规范不定义将多个对象的散列值结<br /><br />合到新散列值中的任何批准的方法。我们在前面编写自己的equals()和hashCode<br /><br />()方法中讨论的List、String或实例类A使用的诀窍都很简单，但算术上还远远不<br /><br />够完美。类库不提供任何散列算法的方便实施，它可以简化更先进的hashCode()<br /><br />实施的创建。<br /><br /><br />当扩展已经忽略了equals()的 instantiable类时很难编写equals()。当扩展已经<br /><br />忽略了equals()的 instantiable类时，定义equals()的“显而易见的”方式都不<br /><br />能满足equals()方法的对称或传递性需求。这意味着当忽略equals()时，您必须<br /><br />了解您正在扩展的类的结构和实施详细信息，甚至需要暴露基本类中的机密字段<br /><br />，它违反了面向对象的设计的原则。 <br /><br />结束语<br />通过统一定义equals()和hashCode()，您可以提升类作为基于散列的集合中的关<br /><br />键字的使用性。有两种方法来定义对象的相等性和散列值：基于标识，它是<br /><br />Object提供的缺省方法；基于状态，它要求忽略equals()和hashCode()。当对象<br /><br />的状态更改时如果对象的散列值发生变化，确信当状态作为散列关键字使用时您<br /><br />不允许更更改其状态。 <br /><br /><br /><br /><br /><br />关于作者 <br />Brian Goetz过去15年以来一直是专业软件开发人员。他是Quiotix的首席顾问，<br /><br />Quiotix是位于加利福尼亚 Los Altos的一家软件开发和咨询公司。参阅Brian在<br /><br />流行行业出版物中已经出版和即将出版的文章。可以通过brian@quiotix.com与 <br /><br />Brian联系。 <br />  <br /><a href="http://www.scjp.com.cn/" target="_blank">http://www.scjp.com.cn</a><!-- the post be hidden --><img src ="http://www.blogjava.net/seaairland/aggbug/44522.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-05-04 14:01 <a href="http://www.blogjava.net/seaairland/archive/2006/05/04/44522.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Commons-collection </title><link>http://www.blogjava.net/seaairland/archive/2006/05/04/44513.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Thu, 04 May 2006 04:15:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/05/04/44513.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/44513.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/05/04/44513.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/44513.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/44513.html</trackback:ping><description><![CDATA[
		<p>Commons项目理解<br />        在java项目中有很多公用的算法实现和工具类<br />        jarkata项目组把这些公用的东西作为开源项目加以实现<br />        以后在项目使用中就可以统一算法，不必写象StringUtil或者DateHelper之类的工具类了<br />        很多算法也不必再查文档，熬夜写个通宵了，:)<br />        最近需要针对collection作一些扩展，自己写了半天，才发现<a href="http://jakarta.apache.org/commons/collections/">commons-collection</a>里面已经有了实现<br />        而且比自己写的好更完善，效率更高<br />        索性来研究一下这个项目，因为很多开源项目也使用它<br />        以后看开源项目代码的时候也就不用那么费力了<br />        <br />概述<br />        首先这个包是基于JDK1.2开发的，所以以后在调用的时候就不用关心JDK版本的问题<br />        其二这个包在大部分的开源项目中使用，已经成为事实上的行业集合类处理标准<br />特性描述<br />        Bag集合接口，用于在集合中保存一个对象的多次拷贝<br />        Buffer接口，用于处理FIFO等定义好移除顺序的结合类<br />        BidiMap接口，用于通过value查找key<br />        MapIterator，这个就不用多说了，以后就不用使用map.keyset.iterator去处理map循环了<br />        型别检查装饰，其实就是可以创建一个具有指定型别的集合类<br />                比如定义了一个整型的list，就不能再向这个list里面放String，否则会抛出异常<br />        转换修饰，就是在向集合中放入对象时，可以将对象转换为需要的类型的对象再放入集合中<br />        组合集合，一个非常好的概念，就是把多个集合当一个集合去使用<br />        排序Map和Set，保持集合的加入顺序<br />        Identity Map，这个Map中使用==而不是equal()方法去比较对象</p>
		<p>        * Reference map that allows keys and/or values to be garbage collected under close control<br />        更多的比较实现<br />        更多的迭代实现<br />        将数组或枚举类型装换到集合类中，非常好用的功能，毕竟array的功能有限<br />        <br />        * Utilities to test or create typical set-theory properties of collections such as union, intersection, and closure</p>
		<p>个人对于一些类的体会<br />        第一个就是TypedList(还有map,set都一样)<br />        可以创建一个String的List，或者一个只能放入指定Class的List，避免编程时候的误写<br />        java编程思想中提到过创建指定型别的集合的问题，不过使用这个类就不用那么麻烦了</p>
		<p>        CollectionUtils<br />                针对集合进行与/并/判断是否包含/等于等工具方法<br />                查找一个集合中某个对象出现的数量<br />                查找（或过滤）一个集合中某种class的子集合，或者计算数量<br />                将集合中的对象进行转换处理<br />                将数组或枚举对象放入集合中<br />                提供针对所有集合类的index，size，get等方法<br />                提供数组翻转方法<br />                提供集合的同步修饰<br />                        比如HashMap本身是不支持同步的，但这个类提供了一个同步修饰<br />                        以后再使用经过修饰后的HashMap时就不用考虑同步的问题了<br />                提供禁止修改集合的工具方法<br />        同CollectionUtils一样还有相应的ListUtils，SetUtils等工具类<br />                这些工具类提供的方法基本都出现在CollectionUtils中</p>
		<p>        ArrayStack<br />                一个继承自ArrayList的Stack实现<br />        BeanMap<br />                一个用于分析javaBean的Map容器，个人感觉用于测试比较方便<br />                因为beanUtils类也可以做这个类的事情，这个类方便的是读取所有属性并显示<br />        BidiMap <br />                就是一个可以通过value查找key的Map<br />                限制：添加对象时，value不能相同<br />                因为这个类还有一个方法就是创建一个反向Map，把value作为key，把key作为value再创建一个Map<br />        BoundedCollection接口<br />                所有实现此接口的集合均被限制了集合大小，不过超过约束的大小<br />        Buffer接口<br />                非常好的一个接口，实现了按照指定顺序移除对象<br />                可以用来实现FIFO，LIFO等算法<br />                也可以通过Comprator来构造，指定确定的移除算法<br />        Ordered**接口<br />                用来实现集合排序<br />        Predicate接口（断言）<br />                用来验证或过滤对象<br />        Transformer接口<br />                用来把一个对象转换成另为一个对象<br />        Closure接口<br />                用来封闭一段代码，针对对象进行指定的处理<br />        Unmodifiable接口<br />                所以实现（或包含了）此接口的对象均不可以改变</p>
		<p>        ComparatorUtils类<br />                实现了各种比较<br />                布尔值比较实现<br />                null判断比较<br />                比较链的实现 <br />                获取min，max对象<br />        AbstractDualBidiMap<br />                一个包含了两个bidiMap的抽象类<br />                因为bidiMap可以做双向查找<br />                继承AbstractDualBidiMap后，内部的两个map一个针对key排序，一个针对value排序<br />                可以加快访问速度<br />        EnumerationUtils<br />                包含了toList()方法，可以简化代码<br />        ExtendedProperties 比较好玩<br />                提供了增强的properties处理 <br />                处理多行<br />                处理多个相同的声明<br />        Fast***<br />                提供了在多线程中针对集合的快速访问<br />                当进行只读操作时，不进行同步处理<br />                当进行写操作时<br />                        克隆整个集合<br />                        针对克隆执行修改<br />                        使用克隆替换现有对象<br />        MultiHashMap<br />                实现了多key的map<br />                当get时返回list对象<br />        <a href="http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_1/org/apache/commons/collections/map/StaticBucketMap.html">StaticBucketMap</a> ***********（高效）<br />                是一个非常高效的Map， get, put, remove 和 containsKey  操作都被进行了优化<br />                这个Map里面有多个Buck（桶）用于存储数据<br />                这样在多线程中取数据的使用，是从不同的桶中取，真正实现了同步机制<br />                当然，在进行批量操作时无法保证原子性，要注意这一点</p>
<img src ="http://www.blogjava.net/seaairland/aggbug/44513.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-05-04 12:15 <a href="http://www.blogjava.net/seaairland/archive/2006/05/04/44513.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 图解利用Eclipse3 + Lomboz 调试JSP </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41727.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 11:48:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41727.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41727.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41727.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41727.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41727.html</trackback:ping><description><![CDATA[
		<div class="postTitle"> </div>
		<div class="postText"> 
<div> </div><div> </div><div> <strong>Sysdeo Eclipse Tomcat Launcher plugin 与 Lomboz插件的比较：</strong></div><div><strong></strong> </div><div>   这两个插件都可以利用Eclipse来开发JSP，不过Lomboz还可以开发Html、EJB等。</div><div>   Sysdeo plugin是通过设置Context来加载Web应用；而Lomboz是通过在Tomcat目录\webapps目录下生成的WAR文件来加载Web应用的。</div><div> </div><div>   在Sysdeo plugin调试JSP文件比较简单，是因为eclipse通过Context直接控制Web应用。</div><div>而在Lomboz中，eclipse是通过生成的WAR文件间接控制Web应用的，甚至可以说没有控制。</div><div> </div><div>   在Sysdeo plugin中，例如  TomcatSample目录中含有work目录，这个目录是JSP的工作目录，先把jsp文件编译成Servlet文件，存放在work\org\apache\jsp目录下。如 index.jsp在work\org\apache\jsp目录下生成了index_jsp.java文件。</div><div>   在Lomboz中，work目录存放在Tomcat目录\work\Catalina\localhost中。</div><div><br />  
<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="75%" border="0"><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>Context解释</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><div>  Context元素代表一个web应用，运行在某个特定的虚拟主机上。每个web应用基于一个Web Application Archive(WAR)文件，或者是一个目录，包含WAR文件解压后的内容。</div><div>  通过将请求URI的最长可能前缀与每个Context的context路径进行匹配，Catalina选择相应的web 应用处理HTTP请求。一旦选定，根据web application deployment descriptor 文件中定义的servlet映射，Context会选择一个正确的servlet来处理进来的请求。servlet映射必须定义在该web应用目录层次结构中的/WEB-INF/web.xml中。</div><div>  你可以在一个Host元素中嵌套任意多的Context元素。每个Context的路径必须是惟一的，由path属性定义。另外，你必须定义一个context路径长度为0的Context，这个Context称为该虚拟主机的缺省web应用，用来处理那些不能匹配任何Context的Context路径的请求。</div><div>  除了在Host元素中嵌套Context元素以外，你也可以将它们存储在单个文件中（以.xml为后缀），放在$CATALINA_HOME/conf/[enginename]/[hostname]/目录下面。</div><div>   （注：Catalina是Tomcat的别称）</div></td></tr></tbody></table>  </div><div>      </div><div> </div><div><strong><font size="4">下面用一个实例详细谈谈如何用Lomboz调试JSP。</font></strong></div><div><strong><font size="4"></font></strong> </div><div>  
<div> </div><div><strong>目录结构</strong></div><div>   F:\j2sdk                    JDK目录  
<div>   D:\eclipse                  Eclipse 目录</div><div>   F:\java\jakarta-tomcat      Tomcat 5.0.28 目录</div><div>   D:\plug-in\lomboz.301       Lomboz目录（我这里是采用links方式<font color="#000000">安装的）</font></div><div>   根据安装的软件，自己作个合适的配置。</div></div></div><div> </div><div>1.在eclipse窗口中，窗口-&gt;首选项-&gt;Lomboz-&gt;Server Definitions，添加jsper-runtime.jar，</div><div>  最后点击“应用”，“确定”。</div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz80.jpg" /></div><div> </div><div> </div><div>2.新建一个Lomboz项目</div><div>  项目名：    Lomboz Debug</div><div>  Web模块名： debugWeb</div><div>  Server名：  Tomcat 5.0.28</div><div> </div><div>3.修改debugWeb目录下的index.jsp文件如下：   
<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="75%" border="0"><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>debugWeb/index.jsp</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><pre>&lt;%<br />    String s = "Welcome javamxj Blog!";<br />    out.println(s);<br />%&gt;</pre></td></tr></tbody></table></div><p style="MARGIN-BOTTOM: 0in">4. 打开$Tomcat_Home/conf目录下面的server.xml文件，在文件尾部如下添加一条语句。 </p><pre style="BORDER-RIGHT: #000000 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #000000 1px solid; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; MARGIN: 10px 50px; OVERFLOW: scroll; BORDER-LEFT: #000000 1px solid; WIDTH: 466px; COLOR: #465584; PADDING-TOP: 5px; BORDER-BOTTOM: #000000 1px solid; FONT-FAMILY: Courier New; HEIGHT: 157px; BACKGROUND-COLOR: #ffffff"><div><font color="#ff0000">........上面的语句省略了</font></div><div><font color="#ff0000">只要添加下面的一行即可</font></div><div><font color="#0000ff">&lt;Context path="/debugWeb" reloadable="true" docBase="D:\eclipse\workspace\Lomboz Debug\debugWeb" workDir="D:\eclipse\workspace\Lomboz Debug\j2src" /&gt;<br /></font>      </div><div>     &lt;/Host&gt;</div><div> </div><div>    &lt;/Engine&gt;</div><div> </div><div>  &lt;/Service&gt;<br />  <br />&lt;/Server&gt;</div></pre><p></p><p style="MARGIN-BOTTOM: 0in"> </p><div>  或者，$Tomcat_Home/conf/Catalina/localhost目录下新建一个debugWeb.xml文件，内容如下：     <pre style="BORDER-RIGHT: #000000 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #000000 1px solid; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; MARGIN: 10px 50px; OVERFLOW: scroll; BORDER-LEFT: #000000 1px solid; WIDTH: 466px; COLOR: #465584; PADDING-TOP: 5px; BORDER-BOTTOM: #000000 1px solid; FONT-FAMILY: Courier New; HEIGHT: 84px; BACKGROUND-COLOR: #ffffff"><div><font color="#0000ff" size="2">&lt;?xml version='1.0' encoding='utf-8'?&gt;<br />&lt;Context path="/debugWeb" reloadable="true" docBase="D:\eclipse\workspace\Lomboz Debug\debugWeb" workDir="D:\eclipse\workspace\Lomboz Debug\j2src" /&gt;<br />&lt;/Context&gt;</font></div></pre></div><div> </div><div>5. 右击“Lomboz Debug” 项目，点击“属性”，切换到“Java构建路径”，如下修改：  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz81.jpg" /></div><div> </div><div> </div><div>6.右击“debugWeb”模块-&gt;Lomboz J2EE -&gt;Debug Server，<strong>注意：不要选择“Run Server”</strong></div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz82.jpg" /></div><div> </div><div> </div><div>7.在浏览器窗口中输入“http://localhost:8080/debugWeb”，OK！编辑成功。</div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz83.jpg" /></div><div> </div><div> </div><div>8.刷新“Lomboz Debug”目录下的j2src目录，可以看到刷新后此文件夹下有一个index_jsp.java文件，</div><div>  双击打开此文件，然后增加一个断点。</div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz84.jpg" /></div><div> </div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz85.jpg" /></div><div> </div><div> </div><div>9. 刷新浏览器窗口，此时eclipse会自动切换到“调试”视图，</div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz86.jpg" /></div><div> </div><div> </div><div>10.此时浏览器窗口</div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz87.jpg" /></div><div> </div><div> </div><div> </div><div> </div><div><font size="4"><strong>小结</strong></font></div><div> </div><div>    利用Lomboz调试JSP要比Sysdeo plugin麻烦一些，而且如果要部署模块时，部署后的模块将不会自动解压，因为Tomcat会首先加载Context，所以只有卸载定义的Context才能自动解压模块。</div></div>
<img src ="http://www.blogjava.net/seaairland/aggbug/41727.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 19:48 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41727.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 图解利用Eclipse3+Sysdeo Tomcat plugin编辑和调试JSP(3) </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41726.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 11:44:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41726.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41726.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41726.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41726.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41726.html</trackback:ping><description><![CDATA[
		<div class="postTitle"> </div>
		<div class="postText">
				<div>
						<strong>
								<font size="4">
										<p>
												<br />五. 编辑Servlet程序</p>
								</font>
						</strong>
				</div>
				<div>   在成功编辑和调试JSP的基础上，再进行编辑和调试Servlet程序就比较简单了。</div>
				<div>   </div>
				<div>   1. 先停止Tomcat服务器。 右击“WEB-INF/src”目录，新建-&gt;类， </div>
				<div>      填写包名：“javamxj.tomcat.servlet”</div>
				<div>      填写类名：“ServletSample”</div>
				<div>      点击完成。</div>
				<div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz71.jpg" /></div>
				<div> </div>
				<div>   2. 修改ServletSample.java如下：   
<table style="WIDTH: 614px; HEIGHT: 454px" bordercolor="#000000" cellspacing="0" cellpadding="4" width="614" border="0"><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>ServletSample.java</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><div> /*<br /> * 创建日期 2004-10-18<br /> * 作者 javamxj （CSDN Blog）<br /> */<br />package javamxj.tomcat.servlet;</div><div> </div><div>import java.io.*;</div><div> </div><div>import javax.servlet.http.*;<br />import javax.servlet.*;</div><div> </div><div>public class ServletSample extends HttpServlet {<br />  private String s;</div><div> </div><div>  public void doGet (HttpServletRequest req, HttpServletResponse res)<br />        throws ServletException, IOException<br />  {<br />        PrintWriter out = res.getWriter();<br />        String s="Hello, javamxj Blog!";<br />        out.println(s);<br />        out.close();<br />   }<br />} </div></td></tr></tbody></table><div> </div><div>   3. 在WEB-INF目录下建立一个web.xml文件，保存文件。</div><div><table style="WIDTH: 627px; HEIGHT: 352px" bordercolor="#000000" cellspacing="0" cellpadding="4" width="627" border="0"><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>WEB-INF/web.xml</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><div>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;</div><div> </div><div>&lt;web-app xmlns="<a href="http://java.sun.com/xml/ns/j2ee"><font color="#3f68a6">http://java.sun.com/xml/ns/j2ee</font></a>"<br />    xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance"><font color="#3f68a6">http://www.w3.org/2001/XMLSchema-instance</font></a>"<br />    xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee"><font color="#3f68a6">http://java.sun.com/xml/ns/j2ee</font></a> web-app_2_4.xsd"<br />    version="2.4"&gt;<br />    <br />  &lt;servlet&gt;<br />    &lt;servlet-name&gt;ServletSample&lt;/servlet-name&gt;<br />    &lt;servlet-class&gt;javamxj.tomcat.servlet.ServletSample&lt;/servlet-class&gt;<br />  &lt;/servlet&gt;<br />  <br />  &lt;servlet-mapping&gt;<br />    &lt;servlet-name&gt;ServletSample&lt;/servlet-name&gt;<br />    &lt;url-pattern&gt;/ServletSample&lt;/url-pattern&gt;<br />  &lt;/servlet-mapping&gt;<br />&lt;/web-app&gt;</div></td></tr></tbody></table></div><div> </div>  4.启动Tomcat服务器，在浏览器窗口中输入“http://localhost:8080/TomcatSample/ServletSample”</div>
				<div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz72.jpg" /></div>
				<div> </div>
				<div> </div>
				<div> </div>
				<div>
						<div>
								<strong>
										<font size="4">六. 调试Servlet程序</font>
								</strong>
						</div>
				</div>
				<div>    </div>
				<div>  1. 在ServletSample.java文件中添加一个断点，如图：</div>
				<div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz73.jpg" /></div>
				<div> </div>
				<div> </div>
				<div>  2. 刷新浏览器窗口，切换到eclipse的“调试”视图，如下更改：</div>
				<div>    </div>
				<div>
						<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz74.jpg" />
				</div>
				<div> </div>
				<div> </div>
				<div>  3.此时浏览器窗口如下：</div>
				<div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz75.jpg" /></div>
				<div> </div>
				<div> </div>
				<div> </div>
				<div> </div>
				<div>
						<strong>
								<font size="4">七. 探讨一下机理</font>
						</strong>
						<strong>
								<font size="4">  </font>
						</strong>
				</div>
				<div>
						<strong>
								<font size="4">
								</font>
						</strong> </div>
				<div>   1. Tomcat目录\conf\server.xml文件中，或者在Tomcat目录\conf\Catalina\localhost存在一个TomcatSample.xml文件， 这两个文件中都应该含有如下语句：</div>
				<div>&lt;Context path="/TomcatSample" reloadable="true" docBase="D:\eclipse\workspace\TomcatSample" workDir="D:\eclipse\workspace\TomcatSample\work" /&gt;</div>
				<div>   （注意，由于eclipse的目录不同，上述语句也将不同。）</div>
				<div> </div>
				<div>    2. 在浏览器窗口中输入：“http://localhost:8080/”，点击左边的“Tomcat Manager”链接，会弹出一个窗口，让你输入用户名和密码，在第二大节“环境配置”中的第3小节中，曾经为Tomcat管理界面添加一个用户，输入这个用户的用户名和密码，这里就是“admin”、“javamxj”。</div>
				<div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz76.jpg" /></div>
				<div>   </div>
				<div>   3. 在输入正确的用户名和密码之后，会进入Tomcat管理界面，可以看到，TomcatSample处于运行状态。你可以停止、重载、或卸载它。</div>
				<div> </div>
				<div>
						<strong>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz77.jpg" /></strong>
				</div>
				<div>
						<strong>
						</strong> </div>
				<div>
						<strong>   </strong>
				</div>
				<div>
						<strong> </strong> 4. 现在从eclipse中卸载Context定义</div>
				<div>      右击TomcatSample目录-&gt;Tomcat Project-&gt;Remove context Difinition，如下图：</div>
				<div> </div>
				<div>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz78.jpg" /></div>
				<div> </div>
				<div>   </div>
				<div>   5. 此时刷新Tomcat管理界面的浏览器窗口，会发现“/TomcatSample”已经消失了。同时，</div>
				<div>
						<div>“&lt;Context path="/TomcatSample" reloadable="true" docBase="D:\eclipse\workspace\TomcatSample" workDir="D:\eclipse\workspace\TomcatSample\work" /&gt; ” 这个语句也消失了。</div>
						<div>   </div>
						<div>   6. 要重新把“/TomcatSample”添加到Tomcat应用中去，需要右击TomcatSample目录-&gt;Tomcat Project-&gt;Update context Difinition，然后重启Tomcat。</div>
						<div> </div>
						<div>   <em>讲了这么多，主要是为了下一篇文章“如何利用Lomboz插件编译JSP”做个铺垫，同时也是为了更好地理解这个插件的使用过程</em>。</div>
				</div>
		</div>
<img src ="http://www.blogjava.net/seaairland/aggbug/41726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 19:44 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 图解利用Eclipse3+Sysdeo Tomcat plugin编辑和调试JSP(2) </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41725.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 11:43:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41725.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41725.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41725.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41725.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<script language="javascript"><![CDATA[ocument.title="图解利用Eclipse3+Sysdeo Tomcat plugin编辑和调试JSP(2)  - "+document.title]]&gt;</script>
		</div>
		<div class="postText">
				<div>
						<font size="4">
								<br />
								<strong>三. 编写程序</strong>
						</font>
				</div>
				<div> </div>
				<div>  1.创建一个Tomcat项目。</div>
				<div>     右击“包资源管理器”窗口中的空白处，新建-&gt;Tomcat Project</div>
				<div>   <img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz58.jpg" /></div>
				<div>
						<strong>
								<font size="4">  </font>
						</strong>
				</div>
				<div> 在项目名中填写：TomcatSample，点击“完成”即可。</div>
				<div> </div>
				<div>2.右击“TomcatSample”，新建-&gt;文件， 在文件名中填写：index.jsp</div>
				<div>   <img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz59.jpg" /></div>
				<div> </div>
				<div>3.修改index.jsp  </div>
				<div>
						<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="70%" border="0">
								<tbody>
										<tr>
												<td style="FONT-WEIGHT: bold; BORDER-BOTTOM: rgb(51,51,204) thin inset; FONT-STYLE: italic" valign="top" width="100%" bgcolor="#ffffcc" height="20">
														<p> TomcatSample\index.jsp</p>
												</td>
										</tr>
										<tr>
												<td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edefd7">
														<div>
																<font face="宋体">
																		<div>&lt;%<br />String s = "Welcome javamxj Blog!";<br />out.println(s);<br />%&gt;  </div>
																</font>
														</div>
												</td>
										</tr>
								</tbody>
						</table>
						<div style="MARGIN-BOTTOM: 0in"> </div>
						<div style="MARGIN-BOTTOM: 0in">4. 点击“运行Tomcat”图标</div>
				</div>
				<div>   <img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz60.jpg" /></div>
				<div> </div>
				<div> 5. 如果一切正常，在浏览器窗口中输入“http://localhost:8080/TomcatSample/index.jsp”</div>
				<div>   <img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz61.jpg" /></div>
				<div> </div>
				<div> </div>
				<div>
						<strong>
								<font size="4">四. 调试JSP程序</font>
						</strong>
				</div>
				<div> </div>
				<div>  1. 右击TomcatSample项目下的work目录，在弹出菜单中点击“刷新”。点击后，会发现此目录下有文件，打开“index_jsp.java”文件，在右栏中“out.println(s);”语句增加一个断点。</div>
				<div>    <img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz62.jpg" /></div>
				<div> </div>
				<div>  2. 然后刷新浏览器窗口，此时，eclipse会弹出一个窗口，询问是否切换到“debug”视图，选择“是”。</div>
				<div>    <img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz63.jpg" /></div>
				<div> </div>
				<div>  3. 在此视图中，找到变量s，右击，选择“更改值”，在弹出窗口中输入“Sysdeo Tomcat Plugin!”。</div>
				<div>    <img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz65.jpg" /></div>
				<div> </div>
				<div>  4. 点击“继续”按钮。   <br /><br /><img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz64.jpg" /></div>
				<div> </div>
				<div> 5. 此时，浏览器窗口已经反映出了调试后的变化。</div>
				<div>  <img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz66.jpg" /><br /></div>
		</div>
<img src ="http://www.blogjava.net/seaairland/aggbug/41725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 19:43 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图解利用Eclipse3+Sysdeo Tomcat plugin编辑和调试JSP(1)</title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41722.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 11:35:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41722.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41722.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41722.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41722.html</trackback:ping><description><![CDATA[这篇文章主要介绍如何利用Sysdeo Eclipse Tomcat Launcher plugin 编辑和调试JSP与Servlet，最好先参考我的以前的文章<a href="http://blog.csdn.net/javamxj/archive/2004/10/13/134840.aspx"><font color="#3f68a6">《图解利用Eclipse3.0.1 + Lomboz3.0.1 + Tomcat5.0.28开发JSP》</font></a>系列，可以加深对文章的理解。 
<p><strong><font size="4">一. 需要的软件</font></strong></p><div>   <strong>Sysdeo Eclipse Tomcat Launcher plugin<em></em></strong></div><div>   主页      <a href="http://www.sysdeo.com/eclipse/tomcatPlugin.html"><font color="#3f68a6">http://www.sysdeo.com/eclipse/tomcatPlugin.html</font></a> </div><div>   下载      <a href="http://www.sysdeo.com/eclipse/tomcatPluginV3.zip"><font color="#3f68a6">http://www.sysdeo.com/eclipse/tomcatPluginV3.zip</font></a>    </div><div>   这是一个eclipse插件，可以帮助编辑JSP文件。</div><div>   安装插件，参考    <a href="http://blog.csdn.net/javamxj/archive/2004/10/11/132311.aspx"><font color="#3f68a6">《使用links方式安装Eclipse插件》</font></a></div><div><font color="#3f68a6"></font> </div><div><font color="#3f68a6"></font> </div><div><font size="4"><strong>二. 环境配置</strong></font></div><div>   为了编辑和调试JSP文件，环境配置有些麻烦，有几点要注意。</div><div> </div><div>1. 检查环境变量的设置。</div><div>   右击“我的电脑”-&gt;高级-&gt;环境变量，</div><div>   检查JAVA_HOME,TOMCAT_HOME变量是否指向其安装的目录；</div><div>   PATH变量中是否含有“%JAVA_HOME%\bin;”；</div><div>   CLASSPATH变量中是否含有“%JAVA_HOME%\lib\tools.jar;”</div><div>     </div><div></div><div>2. 将eclipse中java运行环境指向JDK，不是JRE。</div><div>   在eclipe主窗口中，“窗口”-&gt;首选项-&gt;java-&gt;已安装的JRE</div><div>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz52.jpg" /></div><div> </div><div> </div><div>3. 配置Sysdeo Tomcat 插件    </div><div>    </div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz53.jpg" /></div><div>  
<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="90%" border="0"><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>Context解释</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><div>  Context元素代表一个web应用，运行在某个特定的虚拟主机上。每个web应用基于一个Web Application Archive(WAR)文件，或者是一个目录，包含WAR文件解压后的内容。</div><div>  通过将请求URI的最长可能前缀与每个Context的context路径进行匹配，Catalina选择相应的web 应用处理HTTP请求。一旦选定，根据web application deployment descriptor 文件中定义的servlet映射，Context会选择一个正确的servlet来处理进来的请求。servlet映射必须定义在该web应用目录层次结构中的/WEB-INF/web.xml中。</div><div>  你可以在一个Host元素中嵌套任意多的Context元素。每个Context的路径必须是惟一的，由path属性定义。另外，你必须定义一个context路径长度为0的Context，这个Context称为该虚拟主机的缺省web应用，用来处理那些不能匹配任何Context的Context路径的请求。</div><div>  除了在Host元素中嵌套Context元素以外，你也可以将它们存储在单个文件中（以.xml为后缀），放在$CATALINA_HOME/conf/[enginename]/[hostname]/目录下面。</div><div>   （注：Catalina是Tomcat的别称）</div></td></tr></tbody></table></div><div> </div><div>  切换到Advanced选项</div><div> <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz54.jpg" /></div><div> </div><div>   切换到JVM Setting选项</div><div> <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz55.jpg" /></div><div> </div><div>切换到Tomcat Manger App，为管理界面增加一个用户。</div><div> </div><div>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz56.jpg" /></div><div> </div><div> 点击“应用”、“确定”即可。</div><div> </div><div>4. 将“Tomcat Project”添加到“新建”菜单。</div><div>    窗口-&gt;定制透视图-&gt;快捷方式-&gt;新建-&gt;Java</div><div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz57.jpg" /><br /></div><img src ="http://www.blogjava.net/seaairland/aggbug/41722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 19:35 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图解利用Eclipse3+Lomboz3+Tomcat开发JSP －－ 4.一个Servlet实例 </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41718.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 11:21:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41718.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41718.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41718.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41718.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41718.html</trackback:ping><description><![CDATA[这篇文章主要介绍如何利用Lomboz开发JSTL和EL，最好先参考我的以前的文章<a href="http://blog.csdn.net/javamxj/archive/2004/10/13/134840.aspx"><font color="#3f68a6">《图解利用Eclipse3.0.1 + Lomboz3.0.1 + Tomcat5.0.28开发JSP》</font></a>，环境配置与它类似，这里从略。 
<div><strong><font size="4">一. 需要的软件</font></strong></div><div>   <strong>XML Buddy</strong>   </div><div>   主页        <a href="http://xmlbuddy.com/"><font color="#3f68a6">http://xmlbuddy.com</font></a>        <a href="http://xmlbuddy.com/2.0/58904908428240984589/409502405985075764578/3.0M9/xmlbuddy_2.0.10.zip"><font color="#3f68a6">下载</font></a></div><div>   这是一个eclipse插件，可以帮助编辑xml文件。</div><div>   安装插件，参考    <a href="http://blog.csdn.net/javamxj/archive/2004/10/11/132311.aspx"><font color="#3f68a6">《使用links方式安装Eclipse插件》</font></a></div><div><font color="#3f68a6"></font> </div><div><font color="#3f68a6"></font> </div><div><font size="4"><strong>二. 环境配置</strong></font></div><div> </div><div>1.新建一个Lomboz J2EE Project，</div><div>  工程名称：“Servlet Sample”；</div><div>  填写Web Modules：“servletWeb”；</div><div>  添加的Servers：“Tomcat 5.0.28”，</div><div> 由于我的上篇文章对eclipse新建工程介绍的比较详细，这里从简。</div><div> </div><div> </div><div>2.目录结构</div><div>   F:\j2sdk                    JDK目录  
<div>   D:\eclipse                  Eclipse 目录</div><div>   F:\java\jakarta-tomcat      Tomcat 5.0.28 目录</div><div>   D:\plug-in\lomboz.301       Lomboz目录（我这里是采用links方式<font color="#000000">安装的，</font></div><div>   D:\eclipse\workspace\Servlet Sample     刚建立的JSTL Sample工程目录</div></div><div>    <strong>根据安装的软件，自己作个合适的配置。</strong></div><div><strong></strong> </div><div><strong></strong> </div><div> 3.对xml文件进行自动格式化</div><div>   Eclipse主界面-&gt;窗口-&gt;首选项-&gt;XMLBuddy-&gt;Formatting：勾选右栏中的两个单选框。</div><p>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz41.jpg" /></p><p> </p><p>4.为了使Lomboz自动向配置文件web.xml中添加参数，需要修改web.xml的名称空间，由原先的“web-app_2_3.dtd”换成“web-app_2_4.xsd”。</p><p> 打开web.xml文件，修改后如下：  
</p><table bordercolor="#000000" cellspacing="0" cellpadding="4" width="90%" border="0"><colgroup><col width="256" /></colgroup><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>Servlet Sample\servletWeb\WEB-INF\web.xml</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><pre>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;</pre><pre>&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"<br />    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"<br />    version="2.4"&gt;<br />    <br /> &lt;welcome-file-list&gt;<br />  &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br /> &lt;/welcome-file-list&gt;</pre><pre> &lt;error-page&gt;<br />  &lt;error-code&gt;404&lt;/error-code&gt;<br />  &lt;location&gt;/error.jsp&lt;/location&gt;<br /> &lt;/error-page&gt;</pre><pre>&lt;/web-app&gt;  </pre></td></tr></tbody></table><p> </p><p> <strong><font size="4">三. 编写实例</font></strong></p><p>  一定要把前面的准备工作做好，才能得到好的效果。</p><p>  1. 右击servletWeb，新建一个Servlet</p><p>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz42.jpg" /></p><p> </p><p> 2. 如下填写</p><p>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz43.jpg" /></p><p>   下一步：</p><p>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz44.jpg" /></p><p> </p><p>3.再次打开web.xml文件，发现参数已经自动添加。 
</p><table bordercolor="#000000" cellspacing="0" cellpadding="4" width="90%" border="0"><colgroup><col width="256" /></colgroup><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>Servlet Sample\servletWeb\WEB-INF\web.xml</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee" <br />    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <br />    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd" <br />    version="2.4"&gt;<br />    <br />    <br />    &lt;servlet&gt;<br />        &lt;servlet-name&gt;HelloServlet&lt;/servlet-name&gt;<br />        &lt;servlet-class&gt;javamxj.servlet.HelloServlet&lt;/servlet-class&gt;<br />        &lt;init-param&gt;<br />            &lt;param-name&gt;greeting&lt;/param-name&gt;<br />            &lt;param-value&gt;Hello&lt;/param-value&gt;<br />        &lt;/init-param&gt;<br />        &lt;init-param&gt;<br />            &lt;param-name&gt;name&lt;/param-name&gt;<br />            &lt;param-value&gt;javamxj blog&lt;/param-value&gt;<br />        &lt;/init-param&gt;<br />    &lt;/servlet&gt;<br />    <br />    &lt;servlet-mapping&gt;<br />        &lt;servlet-name&gt;HelloServlet&lt;/servlet-name&gt;<br />        &lt;url-pattern&gt;/hello&lt;/url-pattern&gt;<br />    &lt;/servlet-mapping&gt;<br />    <br />    <br />    &lt;welcome-file-list&gt;<br />        &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br />    &lt;/welcome-file-list&gt;<br />    &lt;error-page&gt;<br />        &lt;error-code&gt;404&lt;/error-code&gt;<br />        &lt;location&gt;/error.jsp&lt;/location&gt;<br />    &lt;/error-page&gt;<br />    <br />&lt;/web-app&gt;</pre></td></tr></tbody></table><div> </div><div>4.修改HelloServlet.java，修改如下：</div><div><table bordercolor="#000000" cellspacing="0" cellpadding="4" width="90%" border="0"><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>Servlet Sample\src\javamxj\servlet\HelloServlet.java</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><pre>package javamxj.servlet;</pre><pre>import java.io.IOException;<br />import java.io.PrintWriter;</pre><pre>import javax.servlet.ServletConfig;<br />import javax.servlet.ServletException;<br />import javax.servlet.http.HttpServlet;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;</pre><pre>/**<br /> * @author javamxj<br /> *<br /> * 使用初始化参数在输出窗口显示两个字符串<br /> * （”Hello javamxj blog“），<br /> * 如果初始化参数没定义，使用缺省字符串<br /> * （“Welcome Servlet！”）。<br /> * 初始化参数定义在web.xml文件中。<br /> * <br /> */<br />public class HelloServlet extends HttpServlet {</pre><pre> private String defaultGreeting;<br /> private String defaultName;</pre><pre> public void init(ServletConfig config) throws ServletException {<br />  //从web.xml中获得初始化参数<br />  super.init(config);<br />  <br />  //获取初始化参数，如无，使用缺省字符串<br />  if ((defaultGreeting = getInitParameter("greeting")) == null)<br />   defaultGreeting = "Welcome";<br />  if ((defaultName = getInitParameter("name")) == null)<br />   defaultName = "Servlet!";  <br /> }</pre><pre> protected void doGet(HttpServletRequest request,<br />   HttpServletResponse response) throws ServletException, IOException {<br />        <br />  // 首先设置文档类型<br />        response.setContentType("text/html; charset=GBK");</pre><pre>        // 获取输出流<br />        PrintWriter out = response.getWriter();<br />        <br />        out.println("&lt;html&gt;&lt;head&gt;&lt;title&gt;Welcome javamxj Blog!&lt;/title&gt;&lt;/head&gt;");<br />        out.println("&lt;body&gt;&lt;h1&gt;");<br />        out.println(defaultGreeting +  "    " + defaultName);<br />        out.println("&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;");</pre><pre> }<br />}</pre></td></tr></tbody></table></div><div> </div><div>5.保存，启动服务器，部署servletWeb模块，打开浏览器窗口，输入地址：</div><div>  <a href="http://localhost:8080/servletWeb/hello"><font color="#3f68a6">http://localhost:8080/servletWeb/hello</font></a></div><div>  如图：</div><div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz45.jpg" /></div><div> </div><div> </div><div>6.下面不使用初始化参数。</div><div>    打开web.xml文件，如下修改，保存。</div><div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz46.jpg" /></div><div> </div><div>7.  重新部署servletWeb模块，刷新浏览器窗口。</div><div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz47.jpg" /></div><div>   OK！成功调用默认字符串。</div><div> </div><img src ="http://www.blogjava.net/seaairland/aggbug/41718.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 19:21 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41718.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图解利用Eclipse3+Lomboz3+Tomcat开发JSP －－3.一个JSTL实例 </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41717.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 11:05:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41717.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41717.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41717.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41717.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41717.html</trackback:ping><description><![CDATA[这篇文章主要介绍如何利用Lomboz开发JSTL和EL，最好先参考我的上一篇文章<a href="http://blog.csdn.net/javamxj/archive/2004/10/13/134830.aspx"><font color="#3f68a6">《图解利用Eclipse3.0.1 + Lomboz3.0.1 + Tomcat5.0.28开发JSP》</font></a>，环境配置与它类似，这里从略。 
<div><strong><font size="4"></font></strong> </div><div><strong><font size="4">1. 需要的软件</font></strong></div><div>   <strong>JSTL 1.1.1</strong></div><div>       主页       <a href="http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html"><font color="#3f68a6">http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html</font></a></div><div>       下载       <a href="http://www.apache.org/dist/jakarta/taglibs/standard/binaries/jakarta-taglibs-standard-1.1.1.zip"><font color="#3f68a6">http://www.apache.org/dist/jakarta/taglibs/standard/binaries/jakarta-taglibs-standard-1.1.1.zip</font></a></div><div><font color="#3f68a6"></font> </div><div><font color="#3f68a6"></font> </div><div>   <strong>XML Buddy</strong>   </div><div>   主页        <a href="http://xmlbuddy.com/"><font color="#3f68a6">http://xmlbuddy.com</font></a>          <a href="http://xmlbuddy.com/2.0/58904908428240984589/409502405985075764578/3.0M9/xmlbuddy_2.0.10.zip"><font color="#3f68a6">下载</font></a></div><div>   </div><div>   这是一个eclipse插件，可以帮助编辑xml文件（可选安装）。</div><div>   安装插件，参考<a id="_e1302d344fa3d857_HomePageDays_DaysList__ctl3_DayItem_DayList__ctl0_TitleUrl" href="http://blog.csdn.net/javamxj/archive/2004/10/11/132311.aspx"><font color="#3f68a6">Eclipse基础－－使用links方式安装Eclipse插件</font></a></div><div><font color="#3f68a6"></font> </div><div><font color="#3f68a6"></font> </div><div><font size="4"><strong>2.环境配置</strong></font></div><div> </div><div>新建一个Lomboz J2EE Project，</div><div>  工程名称：“JSTL Sample”；</div><div>  填写Web Modules：“demoWeb2”；</div><div>  添加的Servers：“Tomcat 5.0.28”，</div><div> 由于我的上篇文章对eclipse新建工程介绍的比较详细，这里从简。</div><div> </div><div> </div><div>目录结构</div><div>   F:\j2sdk                    JDK目录  
<div>   D:\eclipse                  Eclipse 目录</div><div>   F:\java\jakarta-tomcat      Tomcat 5.0.28 目录</div><div>   D:\plug-in\lomboz.301       Lomboz目录（我这里是采用links方式<font color="#000000">安装的，</font></div><div>   D:\java\jstl                jakarta-taglibs-standard-1.1.1.zip的解压目录</div><div>   D:\eclipse\workspace\JSTL Sample     刚建立的JSTL Sample工程目录</div></div><div>    <strong>根据安装的软件，自己作个合适的配置。</strong></div><div><strong></strong> </div><div> </div><div><strong><font size="4">3. 加入库文件</font></strong></div><div> </div><div>   找到jslt\lib目录，复制其中的jstl.jar、standard.jar文件到刚建立的“JSTL Sample”工程目录中的lib目录（这里为“D:\eclipse\workspace\JSTL Sample\demoWeb2\WEB-INF\lib”）。</div><div> </div><div>   找到jstl\tld目录，复制其中的c.tld文件到“JSTL Sample”目录中的“\demoWeb2\WEB-INF”目录。</div><div> </div><div>  刷新demoWeb2目录，展开如图，可以看到加入的三个文件已经显示出来了：</div><div> <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz30.jpg" /></div><div> </div><div> </div><div><strong><font size="4">4.修改程序</font></strong></div><div> </div><div><table style="BORDER-LEFT-COLOR: rgb(204,204,204); BORDER-BOTTOM-COLOR: rgb(204,204,204); BORDER-TOP-COLOR: rgb(204,204,204); BORDER-RIGHT-COLOR: rgb(204,204,204)" cellspacing="0" bordercolordark="white" width="90%" bordercolorlight="black" border="1"><tbody><tr><td valign="top" width="100%" bgcolor="#cdcdcd"><p><strong><font color="#000000">注意</font></strong></p></td></tr><tr><td valign="top" width="100%" bgcolor="white"><div><font color="#000000">由于Lomboz只支持JSTL1.1以上版本，EL 是在JSP 2.0 中正式纳入规范的，所以web.xml 应该使用2.4的Schema， 而不是2.3的DTD。<font size="2"><font size="3"> </font>   </font></font></div></td></tr></tbody></table><font style="BACKGROUND-COLOR: #c0c0c0"><div style="MARGIN-BOTTOM: 0in"><font color="#000000"></font> </div></font></div><div>   </div><div>打开WEB-INF目录下的web.xml文件，修改如下：  
<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="90%" border="0"><colgroup><col width="256" /></colgroup><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>WEB-INF/web.xml</p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><pre><font size="4">&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;</font></pre><pre><font size="4">&lt;web-app xmlns="</font><font size="4">http://java.sun.com/xml/ns/j2ee</font><font size="4">"<br />    xmlns:xsi="</font><font size="4">http://www.w3.org/2001/XMLSchema-instance</font><font size="4">"<br />    xsi:schemaLocation="</font><font color="#000000" size="4">http://java.sun.com/xml/ns/j2ee</font><font color="#000000" size="4"> web-app_2_4.xsd"<br />    version="2.4"&gt;</font></pre><pre><font size="4"> &lt;welcome-file-list&gt;<br />  &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;<br /> &lt;/welcome-file-list&gt;</font></pre><pre><font size="4"> &lt;error-page&gt;<br />  &lt;error-code&gt;404&lt;/error-code&gt;<br />  &lt;location&gt;/error.jsp&lt;/location&gt;<br /> &lt;/error-page&gt;</font></pre><pre><font size="4">&lt;/web-app&gt;</font></pre></td></tr></tbody></table></div><div><font size="4"></font> </div><div><font style="BACKGROUND-COLOR: #c0c0c0"><table style="BORDER-LEFT-COLOR: rgb(204,204,204); BORDER-BOTTOM-COLOR: rgb(204,204,204); BORDER-TOP-COLOR: rgb(204,204,204); BORDER-RIGHT-COLOR: rgb(204,204,204)" cellspacing="0" bordercolordark="white" width="90%" bordercolorlight="black" border="1"><tbody><tr><td valign="top" width="100%" bgcolor="#cdcdcd"><p><strong><font color="#000000">注意</font></strong></p></td></tr><tr><td valign="top" width="100%" bgcolor="white"><div><font color="#000000">如果你安装了XMLBuddy插件，并且是用它来打开“web.xml”文件，有可能会出现以下的错误“Cannot find the declaration of the element 'web-app'”，<font size="2"><font size="3">关闭“web.xml”文件，错误消失。它不妨碍程序的运行。 </font>   </font></font></div></td></tr></tbody></table></font></div><font style="BACKGROUND-COLOR: #c0c0c0"><div style="MARGIN-BOTTOM: 0in"><font color="#000000"></font> </div><div style="MARGIN-BOTTOM: 0in"> </div></font><div style="MARGIN-BOTTOM: 0in">下面修改index.jsp文件</div><div><table bordercolor="#000000" cellspacing="0" cellpadding="4" width="90%" border="0"><colgroup><col width="256" /></colgroup><tbody><tr><td style="BORDER-BOTTOM: rgb(51,51,204) thin inset" valign="top" width="100%" bgcolor="#d9eaf2" height="33"><p>demoWeb2/index.j<font color="#000000">sp </font></p></td></tr><tr><td style="BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216)" valign="top" width="100%" bgcolor="#edf2b8"><div>&lt;%@page contentType="text/html;charset=gbk" %&gt;<br />&lt;%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %&gt;</div><div> </div><div>&lt;html&gt;<br />  &lt;head&gt;<br />    &lt;title&gt;Count to 10 Example (using JSTL and scriptlet)&lt;/title&gt;<br />  &lt;/head&gt;<br />  &lt;body&gt;<br />  <br />    &lt;%-- 这是利用JSTL 打印1到10 --%&gt;<br />      利用JSTL 打印1到10 &lt;p&gt;<br />    &lt;c:forEach var="i" begin="1" end="10" step="1"&gt;<br />      &lt;c:out value="${i}" /&gt;<br />      &lt;br/&gt;<br />    &lt;/c:forEach&gt;<br />    <br />    &lt;%-- 这是利用JSP的scriptlet 打印1到10 --%&gt;<br />    &lt;p&gt;    利用JSP的scriptlet 打印1到10   &lt;p&gt;<br />    &lt;%  for(int i=1;i&lt;=10;i++)  {%&gt;<br />      &lt;%=i%&gt;&lt;br/&gt;<br />    &lt;%  } %&gt;<br />   <br /> &lt;/body&gt;<br />&lt;/html&gt;</div></td></tr></tbody></table></div><div><font size="2"></font> </div><div><font size="2"></font>  
<table style="BORDER-LEFT-COLOR: rgb(204,204,204); BORDER-BOTTOM-COLOR: rgb(204,204,204); BORDER-TOP-COLOR: rgb(204,204,204); BORDER-RIGHT-COLOR: rgb(204,204,204)" cellspacing="0" bordercolordark="white" width="90%" bordercolorlight="black" border="1"><tbody><tr><td valign="top" width="100%" bgcolor="#cdcdcd"><div><strong>注意</strong></div></td></tr><tr><td valign="top" width="100%" bgcolor="white"><div>在Lomboz中，只支持JSTL 1.1版本，所以其核心标签库的uri默认为http://java.sun.com/jsp/jstl/core。 </div><div>因为JSTL 1.1同时支持JSTL 1.0和1.1，所以假若核心标签库的uri为http://java.sun.com/jstl/core，则将会使用到JSTL 1.0的核心标签库，此时Lomboz将出现错误。</div></td></tr></tbody></table></div><div> </div><div><font size="4"><strong></strong></font> </div><div><font size="4"><strong>5.运行程序</strong></font></div><div><font size="4"><strong>   </strong>保存文件后，部署demoWeb2模块，运行服务器，然后在浏览器窗口输入地址：</font></div><div><font size="4"> <a href="http://localhost:8080/demoWeb2"><font color="#3f68a6">http://localhost:8080/demoWeb2</font></a> </font></div><div><font size="4"></font> </div><div><font size="4"> OK! 应该可以看到如下界面：</font></div><div><font size="4"><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz31.jpg" /><br /></font></div><img src ="http://www.blogjava.net/seaairland/aggbug/41717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 19:05 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图解利用Eclipse3+Lomboz3+Tomcat开发JSP －－2.编辑一个JSP实例 </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41716.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 11:02:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41716.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41716.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41716.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41716.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41716.html</trackback:ping><description><![CDATA[
		<h4>三. 编辑一个JSP实例 </h4>
		<p>上一节内容（环境设置）：<a id="_e1302d344fa3d857_HomePageDays_DaysList__ctl1_DayItem_DayList__ctl1_TitleUrl" href="http://blog.csdn.net/javamxj/archive/2004/10/13/134830.aspx">图解利用Eclipse3+Lomboz3+Tomcat开发JSP －－1.环境</a></p>
		<div> 1.新建一个“Lomboz J2EE Project”。 在“项目名称”中填入“JspSample”，点击“下一步”，再点击“下一步”。</div>
		<div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz11.jpg" /></div>
		<div> </div>
		<div>  </div>
		<div>  2.填写Web模块</div>
		<div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz12.jpg" /></div>
		<div> </div>
		<div>  3.增加一个服务器（可以增加多个服务器，其中有一个是默认的）</div>
		<div>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz13.jpg" /></div>
		<div> </div>
		<div>  4. 效果如下：</div>
		<div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz14.jpg" /></div>
		<div>   </div>
		<div>
		</div>
		<div>  5.双击打开index.jsp，点击“Lomboz View”按钮，如下图：</div>
		<div>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz15.jpg" /></div>
		<div>  </div>
		<div>  先点击“启动服务器”按钮（或在“Apache Tomcat v5.0.28”右击，选择“Run Server”），如果一切正常，在“控制台窗口”会输出“信息：Server startup in ... ms”。</div>
		<div> </div>
		<div>  然后切换到“Lomboz J2EE View”栏，选中“demoWeb”，点击“部署模块”按钮，可以看到输出信息，</div>
		<div>大致内容是生成了一个“demoWeb.war”文件，并且部署到“F:\java\jakarta-tomcat\webapps”（这是我的电脑上的Tomcat目录）的目录中，接着，Tomcat服务器自动解压并初始化“demoWeb.war”。</div>
		<div> </div>
		<div>   打开浏览器，在地址栏中输入“http://127.0.0.1:8080/demoWeb/index.jsp”</div>
		<div>   OK！ 你应该可以看到以下界面：</div>
		<div>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz16.jpg" /></div>
		<div> </div>
		<div> 也可以右击“包资源管理器”中的“demoWeb”文件夹，然后采用以下步骤，如图：</div>
		<div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz17.jpg" /></div>
		<div> </div>
		<div> </div>
		<div>   6.在“index.jsp”中增加一条语句“&lt;%   out.println("Use JSP!");  %&gt;”,然后保存，点击“部署模块”，刷新浏览器，应该可以看到以下界面：</div>
		<div> </div>
		<div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz18.jpg" /></div>
		<div> </div>
		<div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz19.jpg" /></div>
		<div> </div>
		<div>  7. 再增加以下语句，保存，部署模块，刷新浏览器。</div>
		<div>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz20.jpg" /></div>
		<div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz21.jpg" /></div>
		<div>   </div>
<img src ="http://www.blogjava.net/seaairland/aggbug/41716.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 19:02 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41716.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图解利用Eclipse3+Lomboz3+Tomcat开发JSP －－1.环境 </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41715.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 10:40:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41715.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41715.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41715.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41715.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41715.html</trackback:ping><description><![CDATA[我最近看了不少有关Lomboz的资料，发现有不少网友都对这个eclipse插件感兴趣，但苦于入门。感觉有必要把自己学习Lomboz的心得写下来，以便后来人不至于走太多的弯路。 
<div> </div><h3>一.环境需求：</h3><div><strong>1. Lomboz的相关资源</strong></div><div>   由于这篇文章重点是放在Lomboz上，所以有必要强调一下。lomboz是Eclipse的一个J2EE的插件，它将很多Java应用服务器、J2EE组件和Web应用开发集成到Eclipse中，可以帮助Java开发者使用Eclipse建立、测试、部署J2EE应用。</div><div>    </div><div>下载：<a href="http://forge.objectweb.org/project/showfiles.php?group_id=97"><font color="#3f68a6">http://forge.objectweb.org/project/showfiles.php?group_id=97</font></a><a href="http://forge.objectweb.org/project/showfiles.php?group_id=97&amp;release_id=603"></a></div><div><font color="#3f68a6"></font> </div><div>论坛：<a href="http://forge.objectweb.org/forum/forum.php?forum_id=360"><font color="#3f68a6">http://forge.objectweb.org/forum/forum.php?forum_id=360</font></a></div><div><font color="#3f68a6"></font> </div><div>教程：<a href="http://www.objectlearn.com/support/docs/index.jsp"><font color="#3f68a6">http://www.objectlearn.com/support/docs/index.jsp</font></a></div><div>   </div><div>  <font color="#000000"><strong>注意 </strong>下载的时候需要下载两个文件，一个是Lomboz3.0.1 一个是emf-sdo-runtime-2.0.0.zip（这个程序也可以从eclipe官方网站上下载最新版本</font><a href="http://www.eclipse.org/emf/"><font color="#000000">http://www.eclipse.org/emf/</font></a><font color="#000000">）</font></div><div> </div><div>   教程和论坛都是属于Lomboz官方网站的，虽然都是英文资料，但是对于学习Lomboz有很大的帮助。对于想真正了解Lomboz的话（当然最好是直接看源码了），英文又过得去，还是应该看看教程和论坛上的资料。</div><div> </div><div> </div><div><strong>2. 我的配置</strong></div><div>   Winxp SP1，</div><div>   JDK 1.4.2-04  可以从SUN官方网站下载</div><div>   Eclipse 3.0.1 和语言包 </div><div>   Tomcat 5.0.28</div><div>   Lomboz 3.0.1</div><div> </div><div><strong>3. 目录结构</strong></div><div>   F:\j2sdk                    JDK目录 </div><div>   D:\eclipse                  Eclipse 目录</div><div>   F:\java\jakarta-tomcat      Tomcat 5.0.28 目录</div><div>   D:\plug-in\lomboz.301       Lomboz目录（我这里是采用links方式<font color="#000000">安装的，</font></div><div><font color="#000000">    参考   <a id="_e1302d344fa3d857_HomePageDays_DaysList__ctl3_DayItem_DayList__ctl0_TitleUrl" href="http://blog.csdn.net/javamxj/archive/2004/10/11/132311.aspx"><font color="#3f68a6">Eclipse基础－－使用links方式安装Eclipse插件</font></a></font>）</div><div>   </div><div><font color="#000000">设置环境变量  参考  <a id="_e1302d344fa3d857_HomePageDays_DaysList__ctl3_DayItem_DayList__ctl2_TitleUrl" href="http://blog.csdn.net/javamxj/archive/2004/10/11/131935.aspx"><font color="#3f68a6">Eclipse基础－－java环境变量设置</font></a></font></div><div><font color="#3f68a6"></font> </div><div><font color="#000000">安装elcipse及语言包  </font>  参考  <a id="_e1302d344fa3d857_HomePageDays_DaysList__ctl3_DayItem_DayList__ctl1_TitleUrl" href="http://blog.csdn.net/javamxj/archive/2004/10/11/131952.aspx"><font color="#3f68a6">Eclipse基础－－安装eclipse及语言包</font></a></div><div><font color="#3f68a6"></font> </div><div><font color="#3f68a6"></font> </div><h4> 二. 配置开发环境</h4><div>  打开Eclipse，点击菜单“窗口”-&gt;首选项，以下都在“首选项”中配置：</div><div>  1. Java-&gt;构建路径</div><div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz4.jpg" /></div><div> </div><div>   2. Lomboz</div><div>     <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz1.jpg" /></div><div> </div><div>   3.Lomboz-&gt;Server Definitions-&gt;Properties<br />   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz2.jpg" /></div><div> </div><div>   </div><div></div><div>4. 切换到主界面，点击“窗口”菜单-&gt;定制透视图</div><div>   <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz5.jpg" /></div><div> </div><div>  切换到“命令”菜单</div><div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz6.jpg" /></div><div> </div><div> 5. 配置后的效果</div><div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz7.jpg" /></div><div> </div><div>注意：</div><div>    由于Tomcat 5.0.27、5.0.28版本在Lomboz中无法启动，故需要一些修改。</div><div>    找到“D:\plug-in\lomboz.301\eclipse\plugins\com.objectlearn.jdt.j2ee_3.0.1\servers”目录（我采用的是links安装方式）；如果采用的是直接把Lomboz解压到Eclipse来安装的，那么要找到“eclipse的安装目录\plugins\com.objectlearn.jdt.j2ee_3.0.1\servers”目录。</div><div>    这个目录里面都是相关服务器的配置文件，如果有些配置文件用不到，尽管删除，避免造成视觉疲劳。</div><div>如，我只留下了几个文件。</div><div>    <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz8.jpg" /></div><div> </div><div></div><div> </div><div>  先把“tomcat50x.server”文件改名为“tomcat5028.server”（我用的是5.0.28版本），看起来方便。</div><div>打开这个文件，做如下修改：</div><div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz9.jpg" /></div><div> </div><div>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/55036/o_lomboz10.jpg" /></div><div>   最后保存即可。<br /></div><img src ="http://www.blogjava.net/seaairland/aggbug/41715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 18:40 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用CVSNT在Eclipse中使用CVS－－4.实践CVS </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41713.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 10:32:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41713.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41713.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41713.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41713.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41713.html</trackback:ping><description><![CDATA[
		<strong>第四节 实践CVS</strong>
		<p>1.提交代码</p>
		<p>  现在我增加一条输出语句“System.out.println("第一次修改");”，保存。然后选择右侧“包资源管理器”中的HelloWorld.java文件，右击，在弹出菜单中选择“小组”-&gt;“提交”。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d5.jpg" />
		</p>
		<p> </p>
		<p>提交后显示如下，可以看到CVS资源库已经反映了提交后文件的改变。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d6.jpg" />
		</p>
		<p>2.从资源库中更新代码</p>
		<p>   现在删除掉HelloWorld.java中的语句“System.out.println("第一次修改");”，然后保存。</p>
		<p>   右击HelloWorld.java文件-&gt;替换为-&gt;HEAD的最新内容，可以看到删除的代码已经还原了。</p>
		<p>   或者，右击HelloWorld.java文件-&gt;小组-&gt;与资源库同步，选择“将当前更改从右边复制到左边”按钮，然后保存，可以看到删除的代码已经还原了。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d7.jpg" />
		</p>
		<p> </p>
		<p>3. 检出项目</p>
		<p>   右击“CVS资源库”中的“Hello World CVS”,选择“检出为...”</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d8.jpg" />
		</p>
		<p>  在“检出为”对话框中的“项目名称”填写：Hello World CVS Two，然后点击“完成”。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d9.jpg" />
		</p>
		<p>  这样，这两个项目同时指向一个CVS资源库，就有可能产生提交冲突。</p>
		<p>4. 发生冲突</p>
		<p>    简化一下，把Hello World CVS项目称为项目1，Hello World CVS Two称为项目2。注意当前这两个项目的版本都是1.2。</p>
		<p>    在项目1中增加一条语句“System.out.println("项目1第1次修改");” ；项目2增加一条</p>
		<p>语句“ System.out.println("项目2第1次修改");”。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d10.jpg" />
		</p>
		<p> 提交项目1的HelloWorld.java,注意这时版本变成了1.3。</p>
		<p> 这时提交项目2的HelloWorld.java,会出现一个错误，如下：</p>
		<p>  <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d11.jpg" /></p>
		<p>这是由于资源库中已经具有该资源的更新修订版（版本是1.3），而版本是1.2的项目2提交时就会发生冲突。</p>
		<p>5. 解决冲突</p>
		<p>  将项目2的工作与资源库资源合并，并以本地方式保存合并的资源。然后可以选择提交此合并的结果。</p>
		<p>   右击项目2的HelloWorld.java 1.2-&gt;小组-&gt;更新...   如图：</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d22.jpg" />
		</p>
		<p>注意此时项目2的版本已经变成了1.3，更新后冲突已标记出来，你可以选择是否合并资源库中的内容，然后保存，这时项目2可以提交合并后的版本了。提交后，项目2和资源库的版本变成了1.4。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d23.jpg" />
		</p>
		<br />
<img src ="http://www.blogjava.net/seaairland/aggbug/41713.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 18:32 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41713.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 利用CVSNT在Eclipse中使用CVS－－3.创建一个CVS实例 </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41711.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 10:30:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41711.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41711.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41711.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41711.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41711.html</trackback:ping><description><![CDATA[
		<p>
				<strong>
						<font size="4">
								<font size="3">第三节 </font>创建一个CVS实例</font>
				</strong>
		</p>
		<p>1.先在eclipse中建立一个新的项目“Hello World CVS”，再建立一个“HelloWorld”类（注1），只是简单地输出语句“HelloWorld！”。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d1.jpg" />
		</p>
		<p>2.把这个本地项目共享到repository里。打开java视图，选中这个项目，右键单击－&gt;小组-&gt;共享项目：<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d2.jpg" /></p>
		<p>出现提示窗口后，一路按“Next”即可，直至出现一个“添加至CVS版本控制”的对话框，点击“详细信息”，可以选择哪些资源添加到CVS资源库，这里没有选择“/Hello World CVS/bin”目录（它不是源代码），然后点击“是”即可。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d3.jpg" />
		</p>
		<p>出现“提交”对话框，可以选择不添加注释，但最好是添加。（注意，每次提交时都会提示输入注释，这是很重要的，作为每一个状态的说明和提示。）</p>
		<p>完成后commit所有本地文件，然后你就可以使用CVS强大的版本控制功能了。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_d4.jpg" />
		</p>
		<p>
				<strong>
				</strong> </p>
		<p>
				<strong>注1：</strong>刚开始时我给“HelloWorld”类用的包名是“cvs.test”，后来共享项目时出现问题，出在cvs这个词上，把包名改为“cvs1.test”后问题消失。原因是采用“cvs.test”包名时会就建立一个cvs目录，而共享到repository时也要创建cvs目录，结果目录名冲突。所以包名不要单独用cvs这个词。</p>
		<br />
<img src ="http://www.blogjava.net/seaairland/aggbug/41711.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 18:30 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用CVSNT在Eclipse中使用CVS－－2.在eclipse中配置CVS client </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41707.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 10:25:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41707.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41707.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41707.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41707.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41707.html</trackback:ping><description><![CDATA[
		<p>
				<strong>第二节: 在eclipse中配置CVS client</strong>
		</p>
		<p>1.运行eclipse 3后，执行下图所示的功能：</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_cvsnt4.jpg" />
		</p>
		<p>或者,打开"窗口"菜单-&gt;"打开透视图"-&gt;"CVS资源库研究"</p>
		<p>2.在"CVS资源库"窗口的空白处点击右键,选择"新建"-&gt;"资源库位置"</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_cvsnt5.jpg" />
		</p>
		<p> </p>
		<p>3.如下配置CVS资源库</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_cvsnt7.jpg" />
		</p>
		<p>主机: cvs服务器的主机名，也可以是它的IP地址,因为是本地主机,所以填写"localhost"</p>
		<p>资源库路径: 在上一节"<strong>安装与配置cvsnt</strong>" 步骤2 "切换倒repositories页" 中的"Name"项；</p>
		<p>             在此例中就是"/cvsfile"。</p>
		<p>认证: "控制面板"-&gt;"用户帐户":选择已经存在的一个用户名和密码填入,或者创建一个新帐户。</p>
		<p>      还可以右击“我的电脑”图标－&gt;管理－&gt;计算机管理－&gt;本地用户和组－&gt;用户：创建一个新的帐户，如此例中我创建了一个“mmm”的帐户。</p>
		<p>     <img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_cvsnt6.jpg" /></p>
		<p>连接类型： 选择“pserver” 是最常用的一直cvs远程访问方式 。</p>
		<p>4. 完成配置后窗口如下。</p>
		<p>
				<img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54374/o_cvsnt8.jpg" />
		</p>
<img src ="http://www.blogjava.net/seaairland/aggbug/41707.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 18:25 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41707.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse启动过程 </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41694.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41694.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41694.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41694.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41694.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41694.html</trackback:ping><description><![CDATA[当前配置：Windows XP SP1，JDK1.4.2_04，Eclipse3.0.1 
<div> </div><div>   一般安装JDK的时候，会同时在系统目录下也安装一个JRE环境。开始我把安装在系统目录下的JRE环境卸载了，在环境变量中添加一个变量JAVA_HOME，并设定值为“F:\j2sdk”（JDK的安装目录）,在Path变量中添加“%JAVA_HOME%\bin;”。</div><div>   启动eclipse，可以发现一切正常，点击菜单“窗口”-&gt;首选项-&gt;Java-&gt;已安装的JRE，可以发现存在一个名称为“j2sdk”的JRE。</div><div> </div><div>   首先把 JDK的安装目录名“F:\j2sdk”改为“F:\noj2sdk”（随便一个文件名都可以，或者去掉Path变量中的“%JAVA_HOME%\bin;”）,再启动eclipse，可以发现eclipse无法启动，并出现如下提示：</div><div> </div><div><img src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54070/o_ecboot.jpg" /></div><div> </div><div>主要是说没有找到 Java 运行期环境（JRE）。 </div><div> </div><div>由于eclipse目录中没有jre目录，同时在Path变量中找不到正确的javaw执行路径。所以eclipse无法启动。</div><div> </div><div> </div><div><strong>解决问题的3个方法：</strong></div><div><strong></strong> </div><div>   1.在Ms-Dos窗口中，切换到eclipse目录，执行 eclipse -vm F:\noj2sdk\bin\javaw，可以启动eclipse（eclipse -vm dir-location 参数可以用到指定其他的 JRE。）。</div><div>   2.复制 F:\noj2sdk目录下的 jre目录到eclipse目录中， 可以启动eclipse。</div><div>   3.把“F:\noj2sdk”目录名重新改为“F:\j2sdk”，可以启动eclipse。</div><div>   </div><div>   以上3个方法可以分别执行，如果同时执行，默认情况下，Eclipse 首先执行 -vm 参数；如果没有-vm参数，则查找 eclipse\jre 子目录；如果没有找到，Eclipse 将查找在系统中注册的 Java 运行期环境。</div><img src ="http://www.blogjava.net/seaairland/aggbug/41694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 17:29 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>安装eclipse及语言包</title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41691.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 09:25:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41691.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41691.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41691.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41691.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41691.html</trackback:ping><description><![CDATA[
		<br />这里主要介绍当前最新的eclipse3.0.1版本及其语言包的下载与安装。<br /><br />一.下载eclipse和其语言包<br /><br />eclipse需要是3.0.1版本的，不要是3.0版本的，因为它和语言包不匹配。可以从eclipse的官方网站选择一个镜像站<img src="http://bbs.onsouth.com/images/url.gif" align="absMiddle" /><a href="http://www.eclipse.org/downloads/index.php" target="_blank">http://www.eclipse.org/downloads/index.php</a>下载，下面我发现下载速度比较快的站点。<br /><br />eclipse<br /><br />http://mirror.tiscali.dk/eclipse/downloads/drops/R-3.0.1-200409161125/eclipse-SDK-3.0.1-win32.zip<br /><br />ftp://mirror.tiscali.dk/R-3.0.1-200409161125/eclipse-SDK-3.0.1-win32.zip<br /><br />ftp://sunsite.informatik.rwth-aachen.de/pub/mirror/eclipse/R-3.0.1-200409161125/eclipse-SDK-3.0.1-win32.zip<br /><br />http://sunsite.informatik.rwth-aachen.de/eclipse/downloads/drops/R-3.0.1-200409161125/eclipse-SDK-3.0.1-win32.zip<br /><br />ftp://eclipse.openwebeng.com/R-3.0.1-200409161125/eclipse-SDK-3.0.1-win32.zip<br /><br />http://eclipse.openwebeng.com/downloads/drops/R-3.0.1-200409161125/eclipse-SDK-3.0.1-win32.zip<br /><br /><br /><br />语言包<br />http://sunsite.informatik.rwth-aachen.de/eclipse/downloads/drops/L-3.0.1_Translations-200409161125/NLpack-eclipse-SDK-3.0.x-win32.zip<br /><br />http://eclipse.cis.sinica.edu.tw/downloads/drops/L-3.0.1_Translations-200409161125/NLpack-eclipse-SDK-3.0.x-win32.zip<br /><br />http://eclipse.openwebeng.com/downloads/drops/L-3.0.1_Translations-200409161125/NLpack-eclipse-SDK-3.0.x-win32.zip<br /><br /><br />二.安装eclipse和其语言包<br /><br />环境要求：Java(TM)<i></i> 2<i></i> SDK，建议使用使用比较新的版本，如1.4.2版本（我的计算机的环境是<i></i> Windows<i></i> XP<i></i> SP1，Java(TM)<i></i> 2<i></i> SDK<i></i> v1.4.2_04）。<br /><br />首先解压Eclipse3.0.1到一个目录（这里我解压到I:eclipse），然后把语言包NLpack-eclipse-SDK-3.0.x-win32.zip也解压到I:eclipse目录。然后双击此目录中的eclipse.exe文件即可打开eclipe。效果如下：<br /><br /><br />注意：<br />最好使用一个从未被启动过的Eclipse3.0.1，这样可以完全中文化。<br />如果在安装中文包时Eclipse已经被使用过，则可能会出现有部分内容不能被汉化，比如“搜索”、“运行”等菜单。如果中文化的不完全，把eclipse<i></i> 目录下的configuration目录删除，重启即可。<br />也可以采用links方式安装这个语言包。<br /><br />对于e文不好的人或者初学者来说，中文版本的eclipse可以显著提高学习效率，便于接受和使用eclipse。但是，毕竟当前先进的技术是英文一统天下，所以，在对eclipse有了初步的认识之后，还是建议大家多使用英文版的eclipse，这样，对以后的进一步学习和使用有好处。<br /><img src ="http://www.blogjava.net/seaairland/aggbug/41691.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 17:25 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41691.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse基础</title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41690.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41690.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41690.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41690.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41690.html</trackback:ping><description><![CDATA[关键词：Eclipse  基础 资源 java chenhui seaairland<br /><br /><div class="postTitle"><a href="http://blog.csdn.net/javamxj/archive/2004/10/10/130377.aspx"><font color="#3f68a6">Eclipse基础－－Eclipse 资源</font></a><script language="javascript"><![CDATA[ocument.title="Eclipse基础－－Eclipse 资源 - "+document.title]]&gt;</script></div><div class="postText"><div><span class="javascript" id="text101652"><font size="4"><strong>一.介绍</strong></font></span></div><div><span class="javascript">1.eclipse官方网站：  </span></div><div><span class="javascript">   <a href="http://www.eclipse.org/"><font color="#3f68a6">http://www.eclipse.org</font></a></span></div><div><span class="javascript">2.赛迪网   </span></div><div><span class="javascript">   <a href="http://tech.ccidnet.com/pub/series/s102.html"><font color="#3f68a6">http://tech.ccidnet.com/pub/series/s102.html</font></a></span></div><div><span class="javascript">3.<span class="atitle">Eclipse平台入门 </span></span></div><div><span class="javascript"><span class="atitle">  </span> <a href="http://www-900.ibm.com/developerWorks/cn/linux/opensource/os-ecov/index.shtml"><font color="#3f68a6">http://www-900.ibm.com/developerWorks/cn/linux/opensource/os-ecov/index.shtml</font></a></span></div><div><span class="javascript"><font style="BACKGROUND-COLOR: #ffffff" color="#3f68a6"></font></span> </div><div><span class="javascript"><font style="BACKGROUND-COLOR: #ff0000" color="#3f68a6"></font></span> </div><div><span class="javascript"><font color="#3f68a6"><hr /></font></span></div><div><span class="javascript"><strong><font size="4">二.教程</font></strong></span></div><div><span class="javascript"><font color="#000000"></font></span><span class="javascript"></span> </div><div><span class="javascript"></span> 3Plus4 Software</div><div><span class="javascript"></span>    <a href="http://www.3plus4software.de/eclipse/index_en.html"><font color="#3f68a6">http://www.3plus4software.de/eclipse/index_en.html</font></a></div><div><font color="#3f68a6"></font> </div><div>Omondo</div><div><span class="javascript"></span>    <a href="http://www.tutorial-omondo.com/"><font color="#3f68a6">http://www.tutorial-omondo.com/</font></a></div><div><font color="#3f68a6"></font> </div><div>Tutorial for building J2EE Applications using JBOSS and ECLIPSE </div><div>    <a href="http://www.tusc.com.au/tutorial/html/index.html"><font color="#3f68a6">http://www.tusc.com.au/tutorial/html/index.html</font></a></div><div><font color="#3f68a6"></font> </div><div>Getting Started with Eclipse and the SWT    
<div><span class="javascript">    <a href="http://www.cs.umanitoba.ca/~eclipse/"><font color="#3f68a6">http://www.cs.umanitoba.ca/~eclipse/</font></a></span></div><div><span class="javascript"><font color="#3f68a6"></font></span> </div><div><span class="javascript">我认为最好的教程还是eclipse软件自带的帮助文件(现在有了中文帮助)。</span></div></div><div>   </div><span class="javascript"><div><hr /></div><div></div></span><span class="javascript"><strong><font size="4">三.插件</font></strong></span></div><div><span class="javascript"> </span></div><div><span class="javascript">Eclipse Plugin Resource Center and Marketplace    </span></div><div><span class="javascript">   <a href="http://www.eclipseplugincentral.com/"><font color="#3f68a6">http://www.eclipseplugincentral.com/</font></a></span></div><span class="javascript"><div><br />eclipse-plugins   </div><div>   <a href="http://www.eclipse-plugins.info/eclipse/index.jsp"><font color="#3f68a6">http://www.eclipse-plugins.info/eclipse/index.jsp</font></a></div></span><div><span class="javascript"><font color="#3f68a6"></font></span> </div><div><span class="javascript">eclipse-workbench    </span></div><div><span class="javascript">   <a href="http://www.eclipse-workbench.com/jsp/index.jsp"><font color="#3f68a6">http://www.eclipse-workbench.com/jsp/index.jsp</font></a></span></div><div><span class="javascript"><font color="#3f68a6"></font></span> </div><div><span class="javascript">以上3个网站都是综合性插件网站，你可以查询自己所需的插件，而且还有各种排名。</span></div><div><span class="javascript"> </span></div><div><span class="javascript"></span> </div><div><span class="javascript"><font face="Arial">Jigloo SWT/Swing GUI Builder       </font></span></div><div><span class="javascript"><font face="Arial">      <a href="http://cloudgarden.com/jigloo/"><font color="#3f68a6">http://cloudgarden.com/jigloo/</font></a></font></span></div><div><span class="javascript"><font face="Arial" color="#3f68a6"></font></span> </div><div><span class="javascript"><a class="interwiki" href="http://forge.objectweb.org/projects/lomboz" target="_blank"><font color="#3f68a6"></font></a></span> </div><div><span class="javascript">Lomboz   </span></div><div><span class="javascript">    <a href="http://forge.objectweb.org/project/showfiles.php?group_id=97"><font color="#3f68a6">http://forge.objectweb.org/project/showfiles.php?group_id=97</font></a></span> </div><div><span class="javascript"><font color="#800080"><u></u></font></span> </div><div><span class="javascript">Matrix网站介绍eclipse plugins  </span></div><div><span class="javascript">    <a href="http://www.matrix.org.cn/subjects/Wiki.jsp?page=EclipsePlugins"><font color="#3f68a6">http://www.matrix.org.cn/subjects/Wiki.jsp?page=EclipsePlugins</font></a></span></div><div><span class="javascript"><font color="#3f68a6"></font></span> </div><div><span class="javascript">TomcatPlugin<br />　  <a class="ilink" href="http://www.sysdeo.com/eclipse/tomcatPlugin.html" target="_blank"><font color="#3f68a6">http://www.sysdeo.com/eclipse/tomcatPlugin.html</font></a><br /><br />EasyStruts<br />　   <a class="ilink" href="http://easystruts.sourceforge.net/" target="_blank"><font color="#3f68a6">http://easystruts.sourceforge.net</font></a><br /><br />EclipseColorer　plugin　<br />　  <a class="ilink" href="http://colorer.sf.net/" target="_blank"><font color="#3f68a6">http://colorer.sf.net</font></a>　<br />    <br />CVS-SSH2　Plug-in　for　Eclipse　<br />  　<a class="ilink" href="http://www.jcraft.com/eclipse-cvsssh2/" target="_blank"><font color="#3f68a6">http://www.jcraft.com/eclipse-cvsssh2/</font></a><div><span class="javascript"><br />JadClipse<br />  　<a class="ilink" href="http://jadclipse.sourceforge.net/" target="_blank"><font color="#3f68a6">http://jadclipse.sourceforge.net/</font></a><br /><br />SWT　Designer<br />　  <a class="ilink" href="http://www.swt-designer.com/" target="_blank"><font color="#3f68a6">http://www.swt-designer.com/</font></a><br /><br />Hibernator<br />　  <a class="ilink" href="http://hibernator.sourceforge.net/" target="_blank"><font color="#3f68a6">http://hibernator.sourceforge.net</font></a></span></div></span></div><img src ="http://www.blogjava.net/seaairland/aggbug/41690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 17:24 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate实践 </title><link>http://www.blogjava.net/seaairland/archive/2006/04/18/41682.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 18 Apr 2006 09:07:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/18/41682.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41682.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/18/41682.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41682.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41682.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一.										             																												序																				在实际项目中使用Hibernate有两年多了，在两年多的实践过程中既体验到了Hibernate带来的N多好处，同时也碰到不少的问题，特写此篇文章做个总结，记录自己在Hibernate实践中的一些经验，希望对于新使用H...&nbsp;&nbsp;<a href='http://www.blogjava.net/seaairland/archive/2006/04/18/41682.html'>阅读全文</a><img src ="http://www.blogjava.net/seaairland/aggbug/41682.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-18 17:07 <a href="http://www.blogjava.net/seaairland/archive/2006/04/18/41682.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>swt designer 破解</title><link>http://www.blogjava.net/seaairland/archive/2006/04/17/41490.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Mon, 17 Apr 2006 09:57:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/17/41490.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/41490.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/17/41490.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/41490.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/41490.html</trackback:ping><description><![CDATA[步骤如下：<br /><br />step0:正常下载安装swt-designer，关闭eclipse<br />step1:到eclipse官方网站下载swt的压缩包<br />step2:下载swt.designer.pro.keygen.rar并解压<br />step4:运行swt.ui.bat<br />step5:填写信息，注意：Designer Type要选WindowBuilder,Designer Mode选Professional,Version一定要与你下载的designer完全相同（如:4.3.1这里需要手工输入)，然后generate<br />step6:按照产生的sn和activate key注册，搞定！<img src ="http://www.blogjava.net/seaairland/aggbug/41490.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-17 17:57 <a href="http://www.blogjava.net/seaairland/archive/2006/04/17/41490.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate 2 升级为Hibernate 3 的注意事项</title><link>http://www.blogjava.net/seaairland/archive/2006/04/06/39658.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Thu, 06 Apr 2006 11:02:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/06/39658.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/39658.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/06/39658.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/39658.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/39658.html</trackback:ping><description><![CDATA[
		<p>Hibernate 2 升级为Hibernate 3 的注意事项 <br />Posted on 2005-11-12 19:29 Flyingis 阅读(61) 评论(0) 编辑 收藏 收藏至365Key 所属分类: Hibernate <br />目的，主要是那当前的项目练手，熟悉一下hibernate2和hibernate3的差别，给当前项目一点扩展的空间。</p>
		<p>1.首先将hibernate2.jar替换为hibernate3.jar(hibernate-3.0.5)<br />hibernate-tools.jar也替换成新的(从hibernate-tools-3.0.0.alpha4a找出来的)</p>
		<p>2.将所有程序中的net.sf.hibernate替换为org.hibernate.<br /><br />3.但是有例外<br />net.sf.hibernate.expression.Expression换为org.hibernate.criterion.Expression<br />如果用eclipse,用ctrl+shift+o快捷键可以加快速度 <br /><br />4.在使用hql查询时将<br />createSQLQuery(hql,"c",EZCampaignDTO.class);改为createSQLQuery(hql).addEntity("c",EZCampaignDTO.class);<br /><br />5.在批量插入时<br />将原来的int size = ((SessionFactoryImpl)(session.getSessionFactory())).getJdbcBatchSize()<br />改为int size = ((SessionFactoryImpl)(session.getSessionFactory())).getSettings().getJdbcBatchSize();<br /><br />6.在计算count时<br />将原来的int size = ((Integer) session.iterate(hql).next()).intValue();<br />改为int size = ((Integer) session.createQuery(hql).iterate().next()).intValue();<br />其中hql="select count(*) from " + DAOVar.contactClass;<br /><br />7.还有就是把.hbm中的hibernate-mapping-2.0.dtd替换为hibernate-mapping-3.0.dtd<br />Hibernate Mapping DTD 2.0替换为Hibernate Mapping DTD 3.0<br /><br />8.hibernate.cfg.xml中<br />Hibernate Mapping DTD 2.0替换为Hibernate Mapping DTD 3.0<br /><property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property><br /><br />9.hibernate.properties中类似<br /><br />10.cache-config.xml中<br /><provider />替换为<br /><provider /><br /><br />11.classeshibernate.properties中<br />hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider<br />hibernate.dialect=org.hibernate.dialect.SQLServerDialect<br /><br />12.在自动外部模块部分有一个功能是根据模版自动生成.hbm文件在load,结果出来的.hbm中有问题:<br />生成的 <composite unsaved-value="any" mapped="false" -id="" />其中mapped="false" 出错。找了半天才发现在网上的hibernate-mapping-3.0.dtd文件有支持mapped="false"这个属性。而本地的hebernate3.0.5中的hibernate-mapping-3.0.dtd文件没有这个属性。晕，hibernate也太不负责了吧。解决办法把hibernate-mapping-3.0.dtd copy到jbossbin目录下然后，在template文件中，然后他会在jbossbin目录下读取该文件。<br /><br />13.重新测试,还是咣铛，发现子类读父类数据时抛出异常：<br />"org.hibernate.LazyInitializationException: could not initialize proxy"<br />延迟抓取出的错，hb3对many-to-one的默认处理是lazy = "proxy"，没有搞懂到底怎么回事，把所有many-to-one,one-to-one都加上lazy="false"，再测试终于大功告成。</p>
		<p>文章原作者Blog： <a href="http://blog.csdn.net/chinaewolf/">http://blog.csdn.net/chinaewolf/</a></p>
		<div class="footer"> </div>
<img src ="http://www.blogjava.net/seaairland/aggbug/39658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-06 19:02 <a href="http://www.blogjava.net/seaairland/archive/2006/04/06/39658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse实用快捷键大全</title><link>http://www.blogjava.net/seaairland/archive/2006/04/06/39600.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Thu, 06 Apr 2006 07:40:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/06/39600.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/39600.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/06/39600.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/39600.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/39600.html</trackback:ping><description><![CDATA[创建：2005-10-27 22:52:38<br />作者：Unlinux<br />来自: http://www.Unlinux.com<br /><br /><font class="f14" id="zoom"><font color="#000000">俗话说,工欲善其事，必先利其器,如果大家对开发程序稍微有点发烧的话,都知道快捷键对编程中有多大的作用了(当然当年Dos用natepad开发程序的除外了),我就是这样一个发烧友了, 对各种IDE中的快捷功能颇感兴趣,尤其是对快捷键这一部分乐此不彼了.再加上Eclipse又是本人的最爱,因此Eclipse中的快捷键就是本人重视的重点了,当然,Eclipse的快捷键暂时不是最强的,本人见过快捷键最优秀的IDE还是当属IDEA了,里面的快捷键为程序员考虑的面面俱到,几乎到了只要你想不到,没有按不到的地步了(嘻,好像给它做广告了).不过说实话很多功能都是Eclipse借鉴Idea过来的了.但至今我发现在快捷键这方面和别的智能开发方面Eclipse还是稍逊一筹了(这仅仅是从Java IDE的角度),废话少说,直接就切入正题了.<br /><br />今天写的这些快捷键都是本人在实际运用中总结出来的,自己感觉很实用,都是以自己的喜好程度来排列了,对于的Eclipse如果没有特别说明都使用有 Eclipse3.0.X以上了,个别如果出现不符合的话要么是版本的问题,要么是和别的系统级的快捷键有冲突,譬如输入法的冲突了,这时就需要修改输入法了.下面的快捷键都是Eclipse特有的,尤其是针对Java Editer的,但有些对Eclipse里面的Text也是实用的了,下面就是这些快捷键了(住:这些快捷键随着自己学习不断的深入和Eclipse版本不断的提高会慢慢的完善的,有些太普通的就没有列出来,如Ctrl+A一类):<br /><br />Ctrl+1 快速修复(最经典的快捷键,就不用多说了)<br /><br />Ctrl+D: 删除当前行 <br /><br />Ctrl+Alt+↓ 复制当前行到下一行(复制增加)<br /><br />Ctrl+Alt+↑ 复制当前行到上一行(复制增加)<br /><br />Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)<br /><br />Alt+↑ 当前行和上面一行交互位置(同上)<br /><br />Alt+← 前一个编辑的页面<br /><br />Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)<br /><br />Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性<br /><br />Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)<br /><br />Shift+Ctrl+Enter 在当前行插入空行(原理同上条)<br /><br />Ctrl+Q 定位到最后编辑的地方<br /><br />Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)<br /><br />Ctrl+M 最大化当前的Edit或View (再按则反之)<br /><br />Ctrl+/ 注释当前行,再按则取消注释<br /><br />Ctrl+O 快速显示 OutLine<br /><br />Ctrl+T 快速显示当前类的继承结构<br /><br />Ctrl+W 关闭当前Editer<br /><br />Ctrl+K 参照选中的Word快速定位到下一个<br /><br />Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)<br /><br />Ctrl+/(小键盘) 折叠当前类中的所有代码<br /><br />Ctrl+×(小键盘) 展开当前类中的所有代码<br /><br />Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)<br /><br />Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)<br /><br />Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)<br /><br />Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)<br /><br />Ctrl+Shift+F4 关闭所有打开的Editer<br /><br />Ctrl+Shift+X 把当前选中的文本全部变味小写<br /><br />Ctrl+Shift+Y 把当前选中的文本全部变为小写<br /><br />Ctrl+Shift+F 格式化当前代码<br /><br />Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)<br /><br />下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)<br /><br />Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)<br /><br />Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)<br /><br />Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)<br /><br />Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)<br /><br />Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)<br /><br />Alt+Shift+I 合并变量(可能这样说有点不妥Inline)<br /><br />Alt+Shift+V 移动函数和变量(不怎么常用)<br /><br />Alt+Shift+Z 重构的后悔药(Undo)</font></font><img src ="http://www.blogjava.net/seaairland/aggbug/39600.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-06 15:40 <a href="http://www.blogjava.net/seaairland/archive/2006/04/06/39600.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个简单的ajax实例</title><link>http://www.blogjava.net/seaairland/archive/2006/04/05/39461.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Wed, 05 Apr 2006 12:02:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/05/39461.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/39461.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/05/39461.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/39461.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/39461.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<a class="postTitle2" id="viewpost1_TitleUrl" href="/kingwell/articles/39091.html">
						<font color="#646464">一个简单的ajax实例</font>
				</a>
		</div>
		<div>去年开始看AJAX时候所写的第一个小程序，整理了下。应该算AJAX最简单的应用了。</div>
		<div> </div>
		<div>首先，演示一下实际运行的<a href="http://www.jsfchina.org/pages/ajax/ajax.html"><font color="#6fbc4c">效果</font></a>。点击弹出新页面中的“See Author”链接，你将会看到该页面作者。从页面提交到显示从服务器获得的结果，这段过程你将不会发现页面的重刷新。</div>
		<div>下面给出该示例的代码：</div>
		<div>1. ajax.html</div>
		<div style="FONT-SIZE: 80%; OVERFLOW: auto; WIDTH: 80%; COLOR: #ffffff; BACKGROUND-COLOR: #999999">&lt;html&gt;<br />&lt;head&gt;<br />&lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"&gt;<br />&lt;title&gt;A simple AJAX example&lt;/title&gt;<br />&lt;script type="text/javascript"&gt;&lt;!--<br />  function findAuthor(file){<br />     var xmlObj = null;<br />     if(window.XMLHttpRequest){<br />        xmlObj = new XMLHttpRequest();<br />     } else if(window.ActiveXObject){<br />         xmlObj = new ActiveXObject("Microsoft.XMLHTTP");<br />     } else {<br />      return;<br />    }<br />    xmlObj.onreadystatechange = function(){<br />       if(xmlObj.readyState == 4){<br />           updateObj('author', <br />        xmlObj.responseXML.getElementsByTagName('name')[0].firstChild.data);<br />       }<br />     }<br />    xmlObj.open ('GET', file, true);<br />    xmlObj.send ('');<br />  }<br />  function updateObj(obj, data){<br />   var textNode = document.createTextNode(data);<br />   document.getElementById(obj).appendChild(textNode);<br />  }<br />  //--&gt;&lt;/script&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;h1&gt;A simple AJAX program&lt;/h1&gt;<br />&lt;p id="obj"&gt;This page is powered by &lt;a id='link' href="data.xml"<br /> title="View the author."<br /> onclick="findAuthor('data.xml'); this.style.display='none'; return false"&gt;See<br />Author.&lt;/a&gt;&lt;span id="author" style="color: olive; font-weight: bolder"&gt;&lt;/span&gt;&lt;/p&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</div>
		<p> </p>
		<p>2.data.xml</p>
		<div style="FONT-SIZE: 80%; OVERFLOW: auto; WIDTH: 80%; COLOR: #ffffff; BACKGROUND-COLOR: #999999">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;author&gt;<br /> &lt;name&gt;www.jsfchina.org&lt;/name&gt;<br />&lt;/author&gt;</div>
		<p> </p>
		<p>解析下。</p>
		<p>该例应该算是最简单的ajax应用了。为了尽求简单性，这里没有使用到任何服务器端技术，诸如servlet,cgi等等。这里并没有使用到任何业务方法，而是直接从服务器的一个xml文档(data.xml)中读取数据。为了简洁性，本例将JavaScript文件也集成到了ajax.html中，实际应用中完全可以独立出去使用。</p>
		<p>该例通过点击链接，激发了一个javascript的方法然后进行交互处理。</p>
		<p>AJAX的核心是XMLHttpRequest，本例通过下列代码创建这个对象</p>
		<div style="FONT-SIZE: 80%; OVERFLOW: auto; WIDTH: 80%; COLOR: #ffffff; BACKGROUND-COLOR: #999999">  var xmlObj = null;<br />  if(window.XMLHttpRequest){<br />      xmlObj = new XMLHttpRequest();<br />  } else if(window.ActiveXObject){<br />      xmlObj = new ActiveXObject("Microsoft.XMLHTTP");<br />  } else {<br />      return;<br />  }</div>
		<p>if(window.XMLHttpRequest)处理了浏览器是mozilla的情况，而if(window.ActiveXObject)则处理了浏览器为IE的情况，目的都是一个：创建了一个XMLHttpRequest对象。创建这个对象的目的就是让XMLHttpRequest对象与服务器交互，而不影响用户正在浏览的页面。这也是AJAX称谓的由来，异步javascript交互xml处理。</p>
		<p>创建好XMLHttpRequest对象之后，调用的函数将会监听该对象状态的变化，即onreadystatechange属性。XMLHttpRequest对象有5个状态，从0－4的整数，也就是说onreadystatechange调用的函数（示例中function(){...}）将会执行4次。示例中我们在该对象处于完成状态(readyState=4)时进行处理（此时服务器已经传回所有信息），为id为“author”的span对象添加了一个textNode节点，该textNode是data.xml文档中name节点的第一个子元素的值。</p>
		<p>好了，这就是完成一次异步交互所需要的步骤。</p>
		<p>以下是一些注意点。</p>
		<p>第一，本例中使用的http的GET方法，你也可以使用POST，但是要设定Content-Type值，即xmlObj.setRequestHeader("Content-Type","application/x-www-form-urlencoded")，这个方法用来设置了MIME类型。还有一点要注意，这些方法最好都大写，否则在firefox下将没有作用。</p>
		<p>第二，xmlObj.open ('GET', file, true)。该方法会建立与服务器的链接，‘GET’指明了http调用方法；file指明了调用的url；true指明了该调用是异步处理，可以省略，默认为'true'。</p>
		<p>第三，xmlObj.send(para)向服务器发出请求。是以POST向服务器发出request，其参数格式为:name=namevalue&amp;so=on。（参考注意点一）</p>
		<p> </p>转贴注明出处<a href="http://www.jsfchina.org/"><u><font color="#6fbc4c">www.jsfchina.org</font></u></a><img src ="http://www.blogjava.net/seaairland/aggbug/39461.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-05 20:02 <a href="http://www.blogjava.net/seaairland/archive/2006/04/05/39461.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java基础</title><link>http://www.blogjava.net/seaairland/archive/2006/04/05/39457.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Wed, 05 Apr 2006 11:56:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/05/39457.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/39457.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/05/39457.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/39457.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/39457.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JAVA相关基础知识1、面向对象的特征有哪些方面   1.抽象：抽象就是忽略一个主题中与当前目标无关的那些方面，以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题，而只是选择其中的一部分，暂时不用部分细节。抽象包括两个方面，一是过程抽象，二是数据抽象。2.继承：继承是一种联结类的层次模型，并且允许和鼓励类的重用，它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生，这个过...&nbsp;&nbsp;<a href='http://www.blogjava.net/seaairland/archive/2006/04/05/39457.html'>阅读全文</a><img src ="http://www.blogjava.net/seaairland/aggbug/39457.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-05 19:56 <a href="http://www.blogjava.net/seaairland/archive/2006/04/05/39457.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IoC 容器和Dependency Injection 模式</title><link>http://www.blogjava.net/seaairland/archive/2006/04/04/39112.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 04 Apr 2006 03:26:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/04/39112.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/39112.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/04/39112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/39112.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/39112.html</trackback:ping><description><![CDATA[IoC 容器和Dependency Injection 模式<br />撰文/Martin Fowler 编译/透明<br />Java 社群近来掀起了一阵轻量级容器的热潮，这些容器能够帮助开发者将来自不同项目的组件<br />组装成为一个内聚的应用程序。在它们的背后有着同一个模式，这个模式决定了这些容器进行组<br />件装配的方式。人们用一个大而化之的名字来称呼这个模式：“控制反转”（ Inversion of<br />Control，IoC）。在本文中，我将深入探索这个模式的工作原理，给它一个更能描述其特点的名<br />字——“依赖注入”（Dependency Injection），并将其与“服务定位器”（Service Locator）<br />模式作一个比较。不过，这两者之间的差异并不太重要，更重要的是：应该将组件的配置与使用<br />分离开——两个模式的目标都是这个。<br />在企业级Java 的世界里存在一个有趣的现象：有很多人投入很多精力来研究主流J2EE 技术的<br />替代品——自然，这大多发生在open source 社群。在很大程度上，这可以看作是开发者对主<br />流J2EE 技术的笨重和复杂作出的回应，但其中的确有很多极富创意的想法，的确提供了一些可<br />供选择的方案。J2EE 开发者常遇到的一个问题就是如何组装不同的程序元素：如果web 控制<br />器体系结构和数据库接口是由不同的团队所开发的，彼此几乎一无所知，你应该如何让它们配合<br />工作？很多框架尝试过解决这个问题，有几个框架索性朝这个方向发展，提供了更通用的“组装<br />各层组件”的方案。这样的框架通常被称为“轻量级容器”，PicoContainer 和Spring 都在此<br />列中。<br />在这些容器背后，一些有趣的设计原则发挥着作用。这些原则已经超越了特定容器的范畴，甚至<br />已经超越了Java 平台的范畴。在本文中，我就要初步揭示这些原则。我使用的范例是Java 代<br />码，但正如我的大多数文章一样，这些原则也同样适用于别的OO 环境，特别是.NET。<br />组件和服务<br />“装配程序元素”，这样的话题立即将我拖进了一个棘手的术语问题：如何区分“服务”（service）<br />和“组件”（component）？你可以毫不费力地找出关于这两个词定义的长篇大论，各种彼此<br />矛盾的定义会让你感受到我所处的窘境。有鉴于此，对于这两个遭到了严重滥用的词汇，我将首<br />先说明它们在本文中的用法。<br />所谓“组件”是指这样一个软件单元：它将被作者无法控制的其他应用程序使用，但后者不能对<br />组件进行修改。也就是说，使用一个组件的应用程序不能修改组件的源代码，但可以通过作者预<br />留的某种途径对其进行扩展，以改变组件的行为。<br />服务和组件有某种相似之处：它们都将被外部的应用程序使用。在我看来，两者之间最大的差异<br />在于：组件是在本地使用的（例如JAR 文件、程序集、DLL、或者源码导入）；而服务是要通过<br />——同步或异步的——远程接口来远程使用的（例如web service、消息系统、RPC，或者<br />socket）。<br />在本文中，我将主要使用“服务”这个词，但文中的大多数逻辑也同样适用于本地组件。实际上，<br />为了方便地访问远程服务，你往往需要某种本地组件框架。不过，“组件或者服务”这样一个词<br />组实在太麻烦了，而且“服务”这个词当下也很流行，所以本文将用“服务”指代这两者。<br />一个简单的例子<br />为了更好地说明问题，我要引入一个例子。和我以前用的所有例子一样，这是一个超级简单的例<br />子：它非常小，小得有点不够真实，但足以帮助你看清其中的道理，而不至于陷入真实例子的泥<br />潭中无法自拔。<br />在这个例子中，我编写了一个组件，用于提供一份电影清单，清单上列出的影片都是由一位特定<br />的导演执导的。实现这个伟大的功能只需要一个方法：<br />class MovieLister...<br />public Movie[] moviesDirectedBy(String arg) {<br />List allMovies = finder.findAll();<br />for (Iterator it = allMovies.iterator(); it.hasNext();) {<br />Movie movie = (Movie) it.next();<br />if (!movie.getDirector().equals(arg)) it.remove();<br />}<br />return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);<br />}<br />你可以看到，这个功能的实现极其简单：moviesDirectedBy 方法首先请求finder（影片搜寻<br />者）对象（我们稍后会谈到这个对象）返回后者所知道的所有影片，然后遍历finder 对象返回<br />的清单，并返回其中由特定的某个导演执导的影片。非常简单，不过不必担心，这只是整个例子<br />的脚手架罢了。<br />我们真正想要考察的是finder对象，或者说，如何将MovieLister对象与特定的finder对象连<br />接起来。为什么我们对这个问题特别感兴趣？因为我希望上面这个漂亮的moviesDirectedBy<br />方法完全不依赖于影片的实际存储方式。所以，这个方法只能引用一个finder对象，而finder<br />对象则必须知道如何对findAll 方法作出回应。为了帮助读者更清楚地理解，我给finder定义了<br />一个接口：<br />public interface MovieFinder {<br />List findAll();<br />}<br />现在，两个对象之间没有什么耦合关系。但是，当我要实际寻找影片时，就必须涉及到<br />MovieFinder 的某个具体子类。在这里，我把“涉及具体子类”的代码放在MovieLister 类的<br />构造子中。<br />class MovieLister...<br />private MovieFinder finder;<br />public MovieLister() {<br />finder = new ColonDelimitedMovieFinder("movies1.txt");<br />}<br />这个实现类的名字就说明：我将要从一个逗号分隔的文本文件中获得影片列表。你不必操心具体<br />的实现细节，只要设想这样一个实现类就可以了。<br />如果这个类只由我自己使用，一切都没问题。但是，如果我的朋友叹服于这个精彩的功能，也想<br />使用我的程序，那又会怎么样呢？如果他们也把影片清单保存在一个逗号分隔的文本文件中，并<br />且也把这个文件命名为“ movie1.txt ”，那么一切还是没问题。如果他们只是给这个文件改改名，<br />我也可以从一个配置文件获得文件名，这也很容易。但是，如果他们用完全不同的方式——例如<br />SQL 数据库、XML 文件、web service，或者另一种格式的文本文件——来存储影片清单呢？<br />在这种情况下，我们需要用另一个类来获取数据。由于已经定义了MovieFinder接口，我可以<br />不用修改moviesDirectedBy 方法。但是，我仍然需要通过某种途径获得合适的MovieFinder<br />实现类的实例。<br />图1：“在MovieLister 类中直接创建MovieFinder 实例”时的依赖关系<br />图1 展现了这种情况下的依赖关系：MovieLister 类既依赖于MovieFinder接口，也依赖于具<br />体的实现类。我们当然希望MovieLister 类只依赖于接口，但我们要如何获得一个MovieFinder<br />子类的实例呢？<br />在Patterns of Enterprise Application Architecture 一书中，我们把这种情况称为“插件”<br />（plugin）：MovieFinder的实现类不是在编译期连入程序之中的，因为我并不知道我的朋友会<br />使用哪个实现类。我们希望MovieLister 类能够与MovieFinder的任何实现类配合工作，并且<br />允许在运行期插入具体的实现类，插入动作完全脱离我（原作者）的控制。这里的问题就是：如<br />何设计这个连接过程，使MovieLister 类在不知道实现类细节的前提下与其实例协同工作。<br />将这个例子推而广之，在一个真实的系统中，我们可能有数十个服务和组件。在任何时候，我们<br />总可以对使用组件的情形加以抽象，通过接口与具体的组件交流（如果组件并没有设计一个接口，<br />也可以通过适配器与之交流）。但是，如果我们希望以不同的方式部署这个系统，就需要用插件<br />机制来处理服务之间的交互过程，这样我们才可能在不同的部署方案中使用不同的实现。<br />所以，现在的核心问题就是：如何将这些插件组合成一个应用程序？这正是新生的轻量级容器所<br />面临的主要问题，而它们解决这个问题的手段无一例外地是控制反转（Inversion of Control）<br />模式。<br />控制反转<br />几位轻量级容器的作者曾骄傲地对我说：这些容器非常有用，因为它们实现了“控制反转”。这<br />样的说辞让我深感迷惑：控制反转是框架所共有的特征，如果仅仅因为使用了控制反转就认为这<br />些轻量级容器与众不同，就好象在说“我的轿车是与众不同的，因为它有四个轮子”。<br />问题的关键在于：它们反转了哪方面的控制？我第一次接触到的控制反转针对的是用户界面的主<br />控权。早期的用户界面是完全由应用程序来控制的，你预先设计一系列命令，例如“输入姓名”、<br />“输入地址”等，应用程序逐条输出提示信息，并取回用户的响应。而在图形用户界面环境下，<br />UI 框架将负责执行一个主循环，你的应用程序只需为屏幕的各个区域提供事件处理函数即可。<br />在这里，程序的主控权发生了反转：从应用程序移到了框架。<br />对于这些新生的容器，它们反转的是“如何定位插件的具体实现”。在前面那个简单的例子中，<br />MovieLister 类负责定位MovieFinder 的具体实现——它直接实例化后者的一个子类。这样一<br />来，MovieFinder 也就不成其为一个插件了，因为它并不是在运行期插入应用程序中的。而这<br />些轻量级容器则使用了更为灵活的办法，只要插件遵循一定的规则，一个独立的组装模块就能够<br />将插件的具体实现“注射”到应用程序中。<br />因此，我想我们需要给这个模式起一个更能说明其特点的名字——“控制反转”这个名字太泛了，<br />常常让人有些迷惑。与多位IoC 爱好者讨论之后，我们决定将这个模式叫做“依赖注入”<br />（Dependency Injection）。<br />下面，我将开始介绍Dependency Injection 模式的几种不同形式。不过，在此之前，我要首<br />先指出：要消除应用程序对插件实现的依赖，依赖注入并不是唯一的选择，你也可以用Service<br />Locator 模式获得同样的效果。介绍完Dependency Injection 模式之后，我也会谈到Service<br />Locator 模式。<br />依赖注入的几种形式<br />Dependency Injection 模式的基本思想是：用一个单独的对象（装配器）来获得MovieFinder<br />的一个合适的实现，并将其实例赋给MovieLister 类的一个字段。这样一来，我们就得到了图2<br />所示的依赖图：<br />图2：引入依赖注入器之后的依赖关系<br />依赖注入的形式主要有三种，我分别将它们叫做构造子注入（Constructor Injection）、设值<br />方法注入（Setter Injection）和接口注入（Interface Injection）。如果读过最近关于IoC 的<br />一些讨论材料，你不难看出：这三种注入形式分别就是type 1 IoC（接口注入）、type 2 IoC<br />（设值方法注入）和type 3 IoC（构造子注入）。我发现数字编号往往比较难记，所以我使用了<br />这里的命名方式。<br />使用PicoContainer 进行构造子注入<br />首先，我要向读者展示如何用一个名为PicoContainer 的轻量级容器完成依赖注入。之所以从<br />这里开始，主要是因为我在ThoughtWorks 公司的几个同事在PicoContainer 的开发社群中<br />非常活跃——没错，也可以说是某种偏袒吧。<br />PicoContainer 通过构造子来判断“如何将MovieFinder 实例注入MovieLister 类”。因此，<br />MovieLister 类必须声明一个构造子，并在其中包含所有需要注入的元素：<br />class MovieLister...<br />public MovieLister(MovieFinder finder) {<br />this.finder = finder;<br />}<br />MovieFinder 实例本身也将由PicoContainer来管理，因此文本文件的名字也可以由容器注入：<br />class ColonMovieFinder...<br />public ColonMovieFinder(String filename) {<br />this.filename = filename;<br />}<br />随后，需要告诉PicoContainer：各个接口分别与哪个实现类关联、将哪个字符串注入<br />MovieFinder组件。<br />private MutablePicoContainer configureContainer() {<br />MutablePicoContainer pico = new DefaultPicoContainer();<br />Parameter[] finderParams = {new<br />ConstantParameter("movies1.txt")};<br />pico.registerComponentImplementation(MovieFinder.class,<br />ColonMovieFinder.class, finderParams);<br />pico.registerComponentImplementation(MovieLister.class);<br />return pico;<br />}<br />这段配置代码通常位于另一个类。对于我们这个例子，使用我的MovieLister 类的朋友需要在<br />自己的设置类中编写合适的配置代码。当然，还可以将这些配置信息放在一个单独的配置文件中，<br />这也是一种常见的做法。你可以编写一个类来读取配置文件，然后对容器进行合适的设置。尽管<br />PicoContainer 本身并不包含这项功能，但另一个与它关系紧密的项目NanoContainer 提供<br />了一些包装，允许开发者使用XML 配置文件保存配置信息。NanoContainer能够解析XML 文<br />件，并对底下的PicoContainer 进行配置。这个项目的哲学观念就是：将配置文件的格式与底<br />下的配置机制分离开。<br />使用这个容器，你写出的代码大概会是这样：<br />public void testWithPico() {<br />MutablePicoContainer pico = configureContainer();<br />MovieLister lister = (MovieLister)<br />pico.getComponentInstance(MovieLister.class);<br />Movie[] movies = lister.moviesDirectedBy("Sergio Leone");<br />assertEquals("Once Upon a Time in the West",<br />movies[0].getTitle());<br />}<br />尽管在这里我使用了构造子注入，实际上PicoContainer 也支持设值方法注入，不过该项目的<br />开发者更推荐使用构造子注入。<br />使用Spring 进行设值方法注入<br />Spring 框架是一个用途广泛的企业级Java 开发框架，其中包括了针对事务、持久化框架、web<br />应用开发和JDBC 等常用功能的抽象。和PicoContainer 一样，它也同时支持构造子注入和设<br />值方法注入，但该项目的开发者更推荐使用设值方法注入——恰好适合这个例子。<br />为了让MovieLister 类接受注入， 我需要为它定义一个设值方法， 该方法接受类型为<br />MovieFinder的参数：<br />class MovieLister...<br />private MovieFinder finder;<br />public void setFinder(MovieFinder finder) {<br />this.finder = finder;<br />}<br />类似地，在MovieFinder的实现类中，我也定义了一个设值方法，接受类型为String 的参数：<br />class ColonMovieFinder...<br />public void setFilename(String filename) {<br />this.filename = filename;<br />}<br />第三步是设定配置文件。Spring 支持多种配置方式，你可以通过XML 文件进行配置，也可以<br />直接在代码中配置。不过，XML 文件是比较理想的配置方式。<br />&lt;beans&gt;<br />&lt;bean id="MovieLister" class="spring.MovieLister"&gt;<br />&lt;property name="finder"&gt;<br />&lt;ref local="MovieFinder"/&gt;<br />&lt;/property&gt;<br />&lt;/bean&gt;<br />&lt;bean id="MovieFinder" class="spring.ColonMovieFinder"&gt;<br />&lt;property name="filename"&gt;<br />&lt;value&gt;movies1.txt&lt;/value&gt;<br />&lt;/property&gt;<br />&lt;/bean&gt;<br />&lt;/beans&gt;<br />于是，测试代码大概就像下面这样：<br />public void testWithSpring() throws Exception {<br />ApplicationContext ctx = new<br />FileSystemXmlApplicationContext("spring.xml");<br />MovieLister lister = (MovieLister) ctx.getBean("MovieLister");<br />Movie[] movies = lister.moviesDirectedBy("Sergio Leone");<br />assertEquals("Once Upon a Time in the West",<br />movies[0].getTitle());<br />}<br />接口注入<br />除了前面两种注入技术，还可以在接口中定义需要注入的信息，并通过接口完成注入。Avalon<br />框架就使用了类似的技术。在这里，我首先用简单的范例代码说明它的用法，后面还会有更深入<br />的讨论。<br />首先，我需要定义一个接口，组件的注入将通过这个接口进行。在本例中，这个接口的用途是将<br />一个MovieFinder实例注入继承了该接口的对象。<br />public interface InjectFinder {<br />void injectFinder(MovieFinder finder);<br />}<br />这个接口应该由提供MovieFinder 接口的人一并提供。任何想要使用MovieFinder 实例的类<br />（例如MovieLister 类）都必须实现这个接口。<br />class MovieLister implements InjectFinder...<br />public void injectFinder(MovieFinder finder) {<br />this.finder = finder;<br />}<br />然后，我使用类似的方法将文件名注入MovieFinder的实现类：<br />public interface InjectFilename {<br />void injectFilename (String filename);<br />}<br />class ColonMovieFinder implements MovieFinder, InjectFilename......<br />public void injectFilename(String filename) {<br />this.filename = filename;<br />}<br />现在，还需要用一些配置代码将所有的组件实现装配起来。简单起见，我直接在代码中完成配置，<br />并将配置好的MovieLister 对象保存在名为lister的字段中：<br />class IfaceTester...<br />private MovieLister lister;<br />private void configureLister() {<br />ColonMovieFinder finder = new ColonMovieFinder();<br />finder.injectFilename("movies1.txt");<br />lister = new MovieLister();<br />lister.injectFinder(finder);<br />}<br />测试代码则可以直接使用这个字段：<br />class IfaceTester...<br />public void testIface() {<br />configureLister();<br />Movie[] movies = lister.moviesDirectedBy("Sergio Leone");<br />assertEquals("Once Upon a Time in the West",<br />movies[0].getTitle());<br />}<br />使用Service Locator<br />依赖注入的最大好处在于：它消除了MovieLister类对具体MovieFinder实现类的依赖。这样<br />一来， 我就可以把MovieLister 类交给朋友， 让他们根据自己的环境插入一个合适的<br />MovieFinder实现即可。不过，Dependency Injection 模式并不是打破这层依赖关系的唯一<br />手段，另一种方法是使用Service Locator 模式。<br />Service Locator 模式背后的基本思想是：有一个对象（即服务定位器）知道如何获得一个应用<br />程序所需的所有服务。也就是说，在我们的例子中，服务定位器应该有一个方法，用于获得一个<br />MovieFinder 实例。当然，这不过是把麻烦换了一个样子，我们仍然必须在MovieLister 中获<br />得服务定位器，最终得到的依赖关系如图3 所示：<br />图3：使用Service Locator 模式之后的依赖关系<br />在这里，我把ServiceLocator 类实现为一个Singleton 的注册表，于是MovieLister 就可以<br />在实例化时通过ServiceLocator 获得一个MovieFinder 实例。<br />class MovieLister...<br />MovieFinder finder = ServiceLocator.movieFinder();<br />class ServiceLocator...<br />public static MovieFinder movieFinder() {<br />return soleInstance.movieFinder;<br />}<br />private static ServiceLocator soleInstance;<br />private MovieFinder movieFinder;<br />和注入的方式一样，我们也必须对服务定位器加以配置。在这里，我直接在代码中进行配置，但<br />设计一种通过配置文件获得数据的机制也并非难事。<br />class Tester...<br />private void configure() {<br />ServiceLocator.load(new ServiceLocator(new<br />ColonMovieFinder("movies1.txt")));<br />}<br />class ServiceLocator...<br />public static void load(ServiceLocator arg) {<br />soleInstance = arg;<br />}<br />public ServiceLocator(MovieFinder movieFinder) {<br />this.movieFinder = movieFinder;<br />}<br />下面是测试代码：<br />class Tester...<br />public void testSimple() {<br />configure();<br />MovieLister lister = new MovieLister();<br />Movie[] movies = lister.moviesDirectedBy("Sergio Leone");<br />assertEquals("Once Upon a Time in the West",<br />movies[0].getTitle());<br />}<br />我时常听到这样的论调：这样的服务定位器不是什么好东西，因为你无法替换它返回的服务实现，<br />从而导致无法对它们进行测试。当然，如果你的设计很糟糕，你的确会遇到这样的麻烦；但你也<br />可以选择良好的设计。在这个例子中，ServiceLocator 实例仅仅是一个简单的数据容器，只需<br />要对它做一些简单的修改，就可以让它返回用于测试的服务实现。<br />对于更复杂的情况，我可以从ServiceLocator 派生出多个子类，并将子类型的实例传递给注册<br />表的类变量。另外，我可以修改ServiceLocator 的静态方法，使其调用ServiceLocator 实例<br />的方法，而不是直接访问实例变量。我还可以使用特定于线程的存储机制，从而提供特定于线程<br />的服务定位器。所有这一切改进都无须修改ServiceLocator 的使用者。<br />一种改进的思路是：服务定位器仍然是一个注册表，但不是Singleton。Singleton 的确是实现<br />注册表的一种简单途径，但这只是一个实现时的决定，可以很轻松地改变它。<br />为定位器提供分离的接口<br />上面这种简单的实现方式有一个问题：MovieLister 类将依赖于整个ServiceLocator 类，但它<br />需要使用的却只是后者所提供的一项服务。我们可以针对这项服务提供一个单独的接口，减少<br />MovieLister 对ServiceLocator 的依赖程度。这样一来，MovieLister 就不必使用整个的<br />ServiceLocator 接口，只需声明它想要使用的那部分接口。<br />此时，MovieLister 类的提供者也应该一并提供一个定位器接口，使用者可以通过这个接口获得<br />MovieFinder实例。<br />public interface MovieFinderLocator {<br />public MovieFinder movieFinder();<br />真实的服务定位器需要实现上述接口，提供访问MovieFinder 实例的能力：<br />MovieFinderLocator locator = ServiceLocator.locator();<br />MovieFinder finder = locator.movieFinder();<br />public static ServiceLocator locator() {<br />return soleInstance;<br />}<br />public MovieFinder movieFinder() {<br />return movieFinder;<br />}<br />private static ServiceLocator soleInstance;<br />private MovieFinder movieFinder;<br />你应该已经注意到了：由于想要使用接口，我们不能再通过静态方法直接访问服务——我们必须<br />首先通过ServiceLocator 类获得定位器实例，然后使用定位器实例得到我们想要的服务。<br />动态服务定位器<br />上面是一个静态定位器的例子——对于你所需要的每项服务，ServiceLocator 类都有对应的方<br />法。这并不是实现服务定位器的唯一方式，你也可以创建一个动态服务定位器，你可以在其中注<br />册需要的任何服务，并在运行期决定获得哪一项服务。<br />在本例中，ServiceLocator 使用一个map 来保存服务信息，而不再是将这些信息保存在字段<br />中。此外，ServiceLocator 还提供了一个通用的方法，用于获取和加载服务对象。<br />class ServiceLocator...<br />private static ServiceLocator soleInstance;<br />public static void load(ServiceLocator arg) {<br />soleInstance = arg;<br />}<br />private Map services = new HashMap();<br />public static Object getService(String key){<br />return soleInstance.services.get(key);<br />}<br />public void loadService (String key, Object service) {<br />services.put(key, service);<br />}<br />同样需要对服务定位器进行配置，将服务对象与适当的关键字加载到定位器中：<br />class Tester...<br />private void configure() {<br />ServiceLocator locator = new ServiceLocator();<br />locator.loadService("MovieFinder", new<br />ColonMovieFinder("movies1.txt"));<br />ServiceLocator.load(locator);<br />}<br />我使用与服务对象类名称相同的字符串作为服务对象的关键字：<br />class MovieLister...<br />MovieFinder finder = (MovieFinder)<br />ServiceLocator.getService("MovieFinder");<br />总体而言，我不喜欢这种方式。无疑，这样实现的服务定位器具有更强的灵活性，但它的使用方<br />式不够直观明朗。我只有通过文本形式的关键字才能找到一个服务对象。相比之下，我更欣赏“通<br />过一个方法明确获得服务对象”的方式，因为这让使用者能够从接口定义中清楚地知道如何获得<br />某项服务。<br />用Avalon 兼顾服务定位器和依赖注入<br />Dependency Injection 和Service Locator 两个模式并不是互斥的，你可以同时使用它们，<br />Avalon 框架就是这样的一个例子。Avalon 使用了服务定位器，但“如何获得定位器”的信息<br />则是通过注入的方式告知组件的。<br />对于前面一直使用的例子，Berin Loritsch 发送给了我一个简单的Avalon 实现版本：<br />public class MyMovieLister implements MovieLister, Serviceable {<br />private MovieFinder finder;<br />public void service( ServiceManager manager )<br />throws ServiceException<br />{<br />finder = (MovieFinder)manager.lookup("finder");<br />}<br />service 方法就是接口注入的例子， 它使容器可以将一个ServiceManager 对象注入<br />MyMovieLister 对象。ServiceManager则是一个服务定位器。在这个例子中，MyMovieLister<br />并不把ServiceManager 对象保存在字段中，而是马上借助它找到MovieFinder 实例，并将<br />后者保存起来。<br />作出一个选择<br />到现在为止，我一直在阐述自己对这两个模式（ Dependency Injection 模式和Service<br />Locator 模式）以及它们的变化形式的看法。现在，我要开始讨论他们的优点和缺点，以便指出<br />它们各自适用的场景。<br />Service Locator vs. Dependency Injection<br />首先，我们面临Service Locator 和Dependency Injection 之间的选择。应该注意，尽管我<br />们前面那个简单的例子不足以表现出来，实际上这两个模式都提供了基本的解耦合能力——无论<br />使用哪个模式，应用程序代码都不依赖于服务接口的具体实现。两者之间最重要的区别在于：这<br />个“具体实现”以什么方式提供给应用程序代码。使用Service Locator 模式时，应用程序代<br />码直接向服务定位器发送一个消息，明确要求服务的实现；使用Dependency Injection 模式<br />时，应用程序代码不发出显式的请求，服务的实现自然会出现在应用程序代码中，这也就是所谓<br />“控制反转”<br />控制反转是框架的共同特征，但它也要求你付出一定的代价：它会增加理解的难度，并且给调试<br />带来一定的困难。所以，整体来说，除非必要，否则我会尽量避免使用它。这并不意味着控制反<br />转不好，只是我认为在很多时候使用一个更为直观的方案（例如Service Locator 模式）会比<br />较合适。<br />一个关键的区别在于：使用Service Locator 模式时，服务的使用者必须依赖于服务定位器。<br />定位器可以隐藏使用者对服务具体实现的依赖，但你必须首先看到定位器本身。所以，问题的答<br />案就很明朗了：选择Service Locator 还是Dependency Injection，取决于“对定位器的依<br />赖”是否会给你带来麻烦。<br />Dependency Injection 模式可以帮助你看清组件之间的依赖关系：你只需观察依赖注入的机<br />制（例如构造子），就可以掌握整个依赖关系。而使用Service Locator 模式时，你就必须在源<br />代码中到处搜索对服务定位器的调用。具备全文检索能力的IDE 可以略微简化这一工作，但还<br />是不如直接观察构造子或者设值方法来得轻松。<br />这个选择主要取决于服务使用者的性质。如果你的应用程序中有很多不同的类要使用一个服务，<br />那么应用程序代码对服务定位器的依赖就不是什么大问题。在前面的例子中， 我要把<br />MovieLister 类交给朋友去用，这种情况下使用服务定位器就很好：我的朋友们只需要对定位器<br />做一点配置（通过配置文件或者某些配置性的代码），使其提供合适的服务实现就可以了。在这<br />种情况下，我看不出Dependency Injection 模式提供的控制反转有什么吸引人的地方。<br />但是，如果把MovieLister 看作一个组件，要将它提供给别人写的应用程序去使用，情况就不<br />同了。在这种时候，我无法预测使用者会使用什么样的服务定位器API，每个使用者都可能有自<br />己的服务定位器，而且彼此之间无法兼容。一种解决办法是为每项服务提供单独的接口，使用者<br />可以编写一个适配器，让我的接口与他们的服务定位器相配合。但即便如此，我仍然需要到第一<br />个服务定位器中寻找我规定的接口。而且一旦用上了适配器，服务定位器所提供的简单性就被大<br />大削弱了。<br />另一方面，如果使用Dependency Injection 模式，组件与注入器之间不会有依赖关系，因此<br />组件无法从注入器那里获得更多的服务， 只能获得配置信息中所提供的那些。这也是<br />Dependency Injection 模式的局限性之一。<br />人们倾向于使用Dependency Injection 模式的一个常见理由是：它简化了测试工作。这里的<br />关键是：出于测试的需要，你必须能够轻松地在“真实的服务实现”与“供测试用的‘伪’组件”<br />之间切换。但是，如果单从这个角度来考虑，Dependency Injection 模式和Service Locator<br />模式其实并没有太大区别：两者都能够很好地支持“伪”组件的插入。之所以很多人有<br />“Dependency Injection 模式更利于测试”的印象，我猜是因为他们并没有努力保证服务定<br />位器的可替换性。这正是持续测试起作用的地方：如果你不能轻松地用一些“伪”组件将一个服<br />务架起来以便测试，这就意味着你的设计出现了严重的问题。<br />当然，如果组件环境具有非常强的侵略性（就像EJB 框架那样），测试的问题会更加严重。我的<br />观点是：应该尽量减少这类框架对应用程序代码的影响，特别是不要做任何可能使“编辑-执行”<br />的循环变慢的事情。用插件（plugin）机制取代重量级组件会对测试过程有很大帮助，这正是<br />测试驱动开发（Test Driven Development，TDD）之类实践的关键所在。<br />所以，主要的问题在于：代码的作者是否希望自己编写的组件能够脱离自己的控制、被使用在另<br />一个应用程序中。如果答案是肯定的，那么他就不能对服务定位器做任何假设——哪怕最小的假<br />设也会给使用者带来麻烦。<br />构造子注入 vs. 设值方法注入<br />在组合服务时，你总得遵循一定的约定，才可能将所有东西拼装起来。依赖注入的优点主要在于：<br />它只需要非常简单的约定——至少对于构造子注入和设值方法注入来说是这样。相比于这两者，<br />接口注入的侵略性要强得多，比起Service Locator 模式的优势也不那么明显。<br />所以，如果你想要提供一个组件给多个使用者，构造子注入和设值方法注入看起来很有吸引力：<br />你不必在组件中加入什么希奇古怪的东西，注入器可以相当轻松地把所有东西配置起来。<br />设值函数注入和构造子注入之间的选择相当有趣，因为它折射出面向对象编程的一些更普遍的问<br />题：应该在哪里填充对象的字段，构造子还是设值方法？<br />一直以来，我首选的做法是尽量在构造阶段就创建完整、合法的对象——也就是说，在构造子中<br />填充对象字段。这样做的好处可以追溯到Kent Beck 在Smalltalk Best Practice Patterns<br />一书中介绍的两个模式：Constructor Method 和Constructor Parameter Method。带有参<br />数的构造子可以明确地告诉你如何创建一个合法的对象。如果创建合法对象的方式不止一种，你<br />还可以提供多个构造子，以说明不同的组合方式。<br />构造子初始化的另一个好处是：你可以隐藏任何不可变的字段——只要不为它提供设值方法就行<br />了。我认为这很重要：如果某个字段是不应该被改变的，“没有针对该字段的设值方法”就很清<br />楚地说明了这一点。如果你通过设值方法完成初始化，暴露出来的设值方法很可能成为你心头永<br />远的痛。（实际上，在这种时候我更愿意回避通常的设值方法约定，而是使用诸如initFoo 之类<br />的方法名，以表明该方法只应该在对象创建之初调用。）<br />不过，世事总有例外。如果参数太多，构造子会显得凌乱不堪，特别是对于不支持关键字参数的<br />语言更是如此。的确，如果构造子参数列表太长，通常标志着对象太过繁忙，理应将其拆分成几<br />个对象，但有些时候也确实需要那么多的参数。<br />如果有不止一种的方式可以构造一个合法的对象，也很难通过构造子描述这一信息，因为构造子<br />之间只能通过参数的个数和类型加以区分。这就是Factory Method 模式适用的场合了，工厂<br />方法可以借助多个私有构造子和设值方法的组合来完成自己的任务。经典Factory Method 模<br />式的问题在于：它们往往以静态方法的形式出现，你无法在接口中声明它们。你可以创建一个工<br />厂类，但那又变成另一个服务实体了。“工厂服务”是一种不错的技巧，但你仍然需要以某种方<br />式实例化这个工厂对象，问题仍然没有解决。<br />如果要传入的参数是像字符串这样的简单类型，构造子注入也会带来一些麻烦。使用设值方法注<br />入时，你可以在每个设值方法的名字中说明参数的用途；而使用构造子注入时，你只能靠参数的<br />位置来决定每个参数的作用，而记住参数的正确位置显然要困难得多。<br />如果对象有多个构造子，对象之间又存在继承关系，事情就会变得特别讨厌。为了让所有东西都<br />正确地初始化，你必须将对子类构造子的调用转发给超类的构造子，然后处理自己的参数。这可<br />能造成构造子规模的进一步膨胀。<br />尽管有这些缺陷，但我仍然建议你首先考虑构造子注入。不过，一旦前面提到的问题真的成了问<br />题，你就应该准备转为使用设值方法注入。<br />在将Dependecy Injection 模式作为框架的核心部分的几支团队之间，“构造子注入还是设值<br />方法注入”引发了很多的争论。不过，现在看来，开发这些框架的大多数人都已经意识到：不管<br />更喜欢哪种注入机制，同时为两者提供支持都是有必要的。<br />代码配置 vs. 配置文件<br />另一个问题相对独立，但也经常与其他问题牵涉在一起：如何配置服务的组装，通过配置文件还<br />是直接编码组装？对于大多数需要在多处部署的应用程序来说，一个单独的配置文件会更合适。<br />配置文件几乎都是XML 文件，XML 也的确很适合这一用途。不过，有些时候直接在程序代码中<br />实现装配会更简单。譬如一个简单的应用程序，也没有很多部署上的变化，这时用几句代码来配<br />置就比XML 文件要清晰得多。<br />与之相对的，有时应用程序的组装非常复杂，涉及大量的条件步骤。一旦编程语言中的配置逻辑<br />开始变得复杂，你就应该用一种合适的语言来描述配置信息，使程序逻辑变得更清晰。然后，你<br />可以编写一个构造器（builder）类来完成装配工作。如果使用构造器的情景不止一种，你可以<br />提供多个构造器类，然后通过一个简单的配置文件在它们之间选择。<br />我常常发现，人们太急于定义配置文件。编程语言通常会提供简捷而强大的配置管理机制，现代<br />编程语言也可以将程序编译成小的模块，并将其插入大型系统中。如果编译过程会很费力，脚本<br />语言也可以在这方面提供帮助。<br />通常认为，配置文件不应该用编程语言来编写，因为它们需要能够被不懂编程的系统管理人员编<br />辑。但是，这种情况出现的几率有多大呢？我们真的希望不懂编程的系统管理人员来改变一个复<br />杂的服务器端应用程序的事务隔离等级吗？只有在非常简单的时候，非编程语言的配置文件才有<br />最好的效果。如果配置信息开始变得复杂，就应该考虑选择一种合适的编程语言来编写配置文件。<br />在Java 世界里，我们听到了来自配置文件的不和谐音——每个组件都有它自己的配置文件，而<br />且格式还各各不同。如果你要使用一打这样的组件，你就得维护一打的配置文件，那会很快让你<br />烦死。<br />在这里，我的建议是：始终提供一种标准的配置方式，使程序员能够通过同一个编程接口轻松地<br />完成配置工作。至于其他的配置文件，仅仅把它们当作一种可选的功能。借助这个编程接口，开<br />发者可以轻松地管理配置文件。如果你编写了一个组件，则可以由组件的使用者来选择如何管理<br />配置信息：使用你的编程接口、直接操作配置文件格式，或者定义他们自己的配置文件格式，并<br />将其与你的编程接口相结合。<br />分离配置与使用<br />所有这一切的关键在于：服务的配置应该与使用分开。实际上，这是一个基本的设计原则——分<br />离接口与实现。在面向对象程序里，我们在一个地方用条件逻辑来决定具体实例化哪一个类，以<br />后的条件分支都由多态来实现，而不是继续重复前面的条件逻辑，这就是“分离接口与实现”的<br />原则。<br />如果对于一段代码而言，接口与实现的分离还只是“有用”的话，那么当你需要使用外部元素（例<br />如组件和服务）时，它就是生死攸关的大事。这里的第一个问题是：你是否希望将“选择具体实<br />现类”的决策推迟到部署阶段。如果是，那么你需要使用插入技术。使用了插入技术之后，插件<br />的装配原则上是与应用程序的其余部分分开的，这样你就可以轻松地针对不同的部署替换不同的<br />配置。这种配置机制可以通过服务定位器来实现（Service Locator 模式），也可以借助依赖注<br />入直接完成（Dependency Injection 模式）。<br />更多的问题<br />在本文中，我关注的焦点是使用Dependency Injection 模式和Service Locator 模式进行服<br />务配置的基本问题。还有一些与之相关的话题值得关注，但我已经没有时间继续申发下去了。特<br />别值得注意的是生命周期行为的问题：某些组件具有特定的生命周期事件，例如“停止”、“开始”<br />等等。另一个值得注意的问题是：越来越多的人对“如何在这些容器中运用面向方面（aspect<br />oriented）的思想”产生了兴趣。尽管目前还没有认真准备过这方面的材料，但我也很希望以<br />后能在这个话题上写一些东西。<br />关于这些问题，你在专注于轻量级容器的网站上可以找到很多资料。浏览PicoContainer<br />（<a href="http://www.picocontainer.org">http://www.picocontainer.org</a>）或者Spring（<a href="http://www.springframework.org">http://www.springframework.org</a>）的<br />网站，你可以找到大量相关的讨论，并由此引申出更多的话题。<br />结论和思考<br />在时下流行的轻量级容器都使用了一个共同的模式来组装应用程序所需的服务，我把这个模式称<br />为Dependency Injection，它可以有效地替代Service Locator 模式。在开发应用程序时，<br />两者不相上下，但我认为Service Locator 模式略有优势，因为它的行为方式更为直观。但是，<br />如果你开发的组件要交给多个应用程序去使用，那么Dependency Injection 模式会是更好的<br />选择。<br />如果你决定使用Dependency Injection 模式，这里还有几种不同的风格可供选择。我建议你<br />首先考虑构造子注入；如果遇到了某些特定的问题，再改用设值方法注入。如果你要选择一个容<br />器，在其之上进行开发，我建议你选择同时支持这两种注入方式的容器。<br />Service Locator 模式和Dependency Injection 模式之间的选择并是最重要的，更重要的是：<br />应该将服务的配置和应用程序内部对服务的使用分离开。<br />致谢<br />在此，我要向帮助我理解本文中所提到的问题、并对本文提出宝贵意见的几个人表示感谢，他们<br />是Rod Johnson、Paul Hammant、Joe Walnes、Aslak Hellesoy、Jon Tirsen 和Bill Caputo。<br />另外，Berin Loritsch 和Hamilton Verissimo de Oliveira 在Avalon 方面给了我非常有用的<br />建议，一并向他们表示感谢。<br />引自：<a href="http://gigix.blogdriver.com/gigix/inc/DependencyInjection.pdf">http://gigix.blogdriver.com/gigix/inc/DependencyInjection.pdf</a><img src ="http://www.blogjava.net/seaairland/aggbug/39112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-04 11:26 <a href="http://www.blogjava.net/seaairland/archive/2006/04/04/39112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Introducing to Spring Framework </title><link>http://www.blogjava.net/seaairland/archive/2006/04/04/39111.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 04 Apr 2006 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/04/39111.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/39111.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/04/39111.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/39111.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/39111.html</trackback:ping><description><![CDATA[
		<span style="FONT-WEIGHT: bold">
				<span style="FONT-SIZE: 18px; LINE-HEIGHT: normal">Introducing to Spring Framework</span>
		</span>
		<br />作者：Rod Johnson <br />译者：yanger，taowen <br />校对：taowen <br /><br />关于Spring Framework，今年夏天你可能已经听见很多的议论。在本文中,我将试图解释Spring能完成什么，和我怎么会认为它能帮助你开发J2EE应用程序。 <br /><br /><span style="FONT-WEIGHT: bold">又来一个framework？</span><br /><br />你可能正在想“不过是另外一个的framework”。当已经有许多开放源代码(和专有) J2EE framework时，为什么你还要耐下心子读这篇文章或去下载Spring Framework？ <br /><br />我相信Spring是独特的，有几个原因： <br /><br /><ul><br />它关注的领域是其他许多流行的Framework未曾关注的。Spring要提供的是一种管理你的业务对象的方法。 <br /><br />Spring既是全面的又是模块化的。Spring有分层的体系结构，这意味着你能选择仅仅使用它任何一个独立的部分，而它的架构又是内部一致。因此你能从你的学习中，得到最大的价值。例如，你可能选择仅仅使用Spring来简单化JDBC的使用，或用来管理所有的业务对象。 <br /><br />它的设计从一开始就是要帮助你编写易于测试的代码。Spring是使用测试驱动开发的工程的理想框架。 <br /></ul><br />Spring不会给你的工程添加对其他的框架依赖。Spring也许称得上是个一站式解决方案，提供了一个典型应用所需要的大部分基础架构。它还涉及到了其他framework没有考虑到的内容。 <br /><br />尽管它仅仅是一个从2003年2月才开始的开源项目，但Spring有深厚的历史根基。这个开源工程是起源自我在2002年晚些时候出版的《Expert One-on-One J2EE设计与开发》书中的基础性代码。这本书展示了Spring背后的基础性架构思想。然而，对这个基础架构的概念可以追溯到2000年的早些时候,并且反映了我为一系列商业工程开发基础结构的成功经验。 <br /><br />2003年1月，Spring已经落户于SourceForge上了。现在有10个开发人员，其中6个是高度投入的积极分子。 <br /><br /><span style="FONT-WEIGHT: bold">Spring架构上的好处</span><br /><br />在我们进入细节之前，让我们来看看Spring能够给工程带来的种种好处： <br /><br /><ul><br />Spring能有效地组织你的中间层对象，不管你是否选择使用了EJB。如果你仅仅使用了Struts或其他为J2EE的 API特制的framework，Spring致力于解决剩下的问题。 <br /><br />Spring能消除在许多工程中常见的对Singleton的过多使用。根据我的经验，这是一个很大的问题，它降低了系统的可测试性和面向对象的程度。 <br /><br />通过一种在不同应用程序和项目间一致的方法来处理配置文件，Spring能消除各种各样自定义格式的属性文件的需要。曾经对某个类要寻找的是哪个魔法般的属性项或系统属性感到不解，为此不得不去读Javadoc甚至源编码？有了Spring，你仅仅需要看看类的JavaBean属性。Inversion of Control的使用（在下面讨论）帮助完成了这种简化。 <br /><br />通过把对接口编程而不是对类编程的代价几乎减少到没有，Spring能够促进养成好的编程习惯。 <br /><br />Spring被设计为让使用它创建的应用尽可能少的依赖于他的APIs。在Spring应用中的大多数业务对象没有依赖于Spring。 <br /><br />使用Spring构建的应用程序易于单元测试。 <br /><br />Spring能使EJB的使用成为一个实现选择,而不是应用架构的必然选择。你能选择用POJOs或local EJBs来实现业务接口，却不会影响调用代码。 <br /><br />Spring帮助你解决许多问题而无需使用EJB。Spring能提供一种EJB的替换物，它们适用于许多web应用。例如，Spring能使用AOP提供声明性事务管理而不通过EJB容器，如果你仅仅需要与单个数据库打交道，甚至不需要一个JTA实现。 <br /><br />Spring为数据存取提供了一个一致的框架,不论是使用的是JDBC还是O/R mapping产品（如Hibernate）。 <br /></ul><br />Spring确实使你能通过最简单可行的解决办法来解决你的问题。而这是有有很大价值的。 <br /><br /><span style="FONT-WEIGHT: bold">Spring做了些什么？</span><br /><br />Spring提供许多功能，在此我将依次快速地展示其各个主要方面。 <br /><br /><span style="FONT-WEIGHT: bold">任务描述</span><br /><br />首先,让我们明确Spring范围。尽管Spring覆盖了许多方面，但我们对它应该涉什么，什么不应该涉及有清楚的认识。 <br /><br />Spring的主要目的是使J2EE易用和促进好编程习惯。 <br /><br />Spring不重新轮子。因此，你发现在Spring中没有logging，没有连接池，没有分布式事务调度。所有这些东西均有开源项目提供(例如我们用于处理所有日志输出的Commons Logging以及Commons DBCP)，或由你的应用程序服务器提供了。出于同样的的原因，我们没有提供O/R mapping层。对于这个问题已经有了像Hibernate和JDO这样的优秀解决方案。 <br /><br />Spring的目标就是让已有的技术更加易用。例如，尽管我们没有底层事务协调处理，但我们提供了一个抽象层覆盖了JTA或任何其他的事务策略。 <br /><br />Spring没有直接和其他的开源项目竞争，除非我们感到我们能提供新的一些东西。例如，象许多开发人员一样，我们从来没有对Struts感到高兴过，并且觉得到在MVC web framework中还有改进的余地。在某些领域，例如轻量级的IoC容器和AOP框架，Spring确实有直接的竞争，但是在这些领域还没有已经较为流行的解决方案。(Spring在这些领域是开路先锋。) <br /><br />Spring也得益于内在的一致性。所有的开发者都在唱同样的的赞歌，基础想法依然与Expert One-on-One J2EE设计与开发中提出的差不多。 并且我们已经能够在多个领域中使用一些中心的概念，例如Inversion of Control。 <br /><br />Spring在应用服务器之间是可移植的。当然保证可移植性总是一种挑战，但是我们避免使用任何平台特有或非标准的东西，并且支持在WebLogic，Tomcat，Resin，JBoss，WebSphere和其他的应用服务器上的用户。 <br /><br /><span style="FONT-WEIGHT: bold">Inversion of Control 容器</span><br /><br />Spring设计的核心是 org.springframework.beans 包, 它是为与JavaBeans一起工作而设计的。 这个包一般不直接被用户使用，而是作为许多其他功能的基础。 <br /><br />下一个层面高一些的抽象是"Bean Factory"。一个Spring bean factory 是一个通用的Factory，它使对象能够按名称获取，并且能管理对象之间的关系。 <br /><br />Bean factories 支持两种模式的对象： <br /><br /><ul><br />Singleton：在此模式中，有一个具有特定名称的共享对象实例，它在查找时被获取。这是默认的，而且是最为经常使用的。它对于无状态对象是一种理想的模式。 <br /><br />Prototype：在此模式中，每次获取将创建一个独立的对象。例如，这可以被用于让用户拥有他们自己的对象。 <br /></ul><br /><br />由于 org.springframwork.beans.factory.BeanFactory是一个简单的接口，它能被大量底层存储方法实现。你能够方便地实现你自己的BeanFactory，尽管很少用户需要这么做。最为常用的BeanFactory定义是： <br /><br /><ul><br />XmlBeanFactory： 可解析简单直观的定义类和命名对象属性的XML结构。 我们提供了一个DTD来使编写更容易。 <br /><br />ListableBeanFactoryImpl：提供了解析存放在属性文件中的bean定义的能力，并且可通过编程创建BeanFactories。 <br /></ul><br />每个bean定义可能是一个POJO（通过类名和JavaBean初始属性定义），或是一个FactoryBean。FactoryBean接口添加了一个间接层。通常，这用于创建使用AOP或其他方法的代理对象：例如，添加声明性事务管理的代理。（这在概念上和EJB的interception相似，但实现得更简单。） <br /><br />BeanFactories能在一个层次结构中选择性地参与，继承ancestor（祖先）的定义。这使得在整个应用中公共配置的共享成为可能，虽然个别资源，如controller servlets，还拥有他们自己的独立的对象集合。 <br /><br />这种使用JavaBeans的动机在《Expert One-on-One J2EE Design and Development》的第四章中有描述，在TheServerSide网站上的有免费的PDF版本(http://www.theserverside.com/resources/article.jsp?l=RodJohnsonInterview)。 <br /><br />通过BeanFactory概念，Spring成为一个Inversion of Control的容器。(我不怎么喜欢container这个词，因为它使人联想到重量级容器，如EJB容器。Spring的BeanFactory是一个可通过一行代码创建的容器，并且不需要特殊的部署步骤。) <br /><br />Inversion of Control背后的概念经常表述为Hollywood原则的：“Don’t call me， I’ll call you。” IoC将控制创建的职责搬进了框架中，并把它从应用代码脱离开来。涉及到配置的地方，意思是说在传统的容器体系结构中，如EJB，一个组件可以调用容器并问“我需要它给我做工作的对象X在哪里?”；使用IoC容器则只需指出组件需要X对象，在运行时容器会提供给它。容器是通过查看方法的参数表（例如JavaBean的属性）做到的，也可能根据配置数据如XML。 <br /><br />IoC有几个重要的好处，例如： <br /><br /><ul><br />因为组件不需要在运行时间寻找合作者，所以他们可以更简单的编写和维护。在Spring版的IoC里，组件通过暴露JavaBean的setter方法表达他们依赖的其他组件。这相当于EJB通过JNDI来查找，EJB查找需要开发人员编写代码。 <br /><br />同样原因，应用代码更容易测试。JavaBean属性是简单的，属于Java核心的，并且是容易测试的：仅编写一个自包含的Junit测试方法用来创建对象和设置相关属性即可。 <br /><br />一个好的IoC实现保留了强类型。如果你需要使用一个通用的factory来寻找合作者，你必须通过类型转换将返回结果转变为想要的类型。这不是一个大不了的问题，但是不雅观。使用IoC，你在你的代码中表达了强类型依赖，框架将负责类型转换。这意味着在框架配置应用时，类型不匹配将导致错误；在你的代码中，你无需担心类型转换异常。 <br /><br />大部分业务对象不依赖于IoC容器的APIs。这使得很容易使用遗留下来的代码，且很容易的使用对象无论在容器内或不在容器内。例如，Spring用户经常配置Jakarta Commons DBCP数据源为一个Spring bean：不需要些任何定制代码去做这件事。我们说一个IoC容器不是侵入性的：使用它并不会使你的代码依赖于它的APIs。任何JavaBean在Spring bean factory中都能成为一个组件。 <br /></ul><br />最后应该强调的是，IoC 不同于传统的容器的体系结构，如EJB，应用代码最小程度地依靠于容器。这意味着你的业务对象可以潜在的被运行在不同的IoC 框架上——或者在任何框架之外——不需要任何代码的改动。 <br /><br />以我和其他Spring用户的经验来说，再怎么强调IoC给应用程序代码带来的好处也不为过。 <br /><br />IoC不是一个新概念，但是它在J2EE团体里面刚刚到达黄金时间。 有一些可供选择的IoC 容器: 例如 Apache Avalon, PicoContainer 和 HiveMind。Avalon 从没怎么流行，尽管它很强大而且有很长的历史。Avalon相当的重和复杂，并且看起来比新的IoC解决方案更具侵入性。 PicoContainer是一个轻量级而且更强调通过构造函数表达依赖性而不是JavaBean 属性。 与Spring不同，它的设计允许每个类型一个对象的定义(可能是因为它拒绝任何Java代码外的元数据导致的局限性)。在Spring， PicoContainer 和其他 IoC frameworks之间做比较，可参看文章Spring网站上的"The Spring Framework - A Lightweight Container"位于http://www.springframework.org/docs/lightweight_container.html。这个页面里面包含了PicoContainer站点的链接 。 <br /><br />Spring BeanFactories 是非常轻量级的。用户已经成功地将他们应用在applets和单独的Swing应用中。(它们也很好地工作在EJB容器中。) 没有特殊的部署步骤和察觉得到的启动时间。这个能力表明一个容器在应用的任何层面几乎立即可以发挥非常大的价值。 <br /><br />Spring BeanFactory 概念贯穿于Spring始终， 而且是Spring如此内在一致的关键原因。在IoC容器中，Spring也是唯一的，它使用IoC作为基础概念贯穿于整个功能丰富的框架。 <br /><br />对应用开发人员，最重要的是，一个或多个BeanFactory提供了一个定义明确的业务对象层。这类似于local session bean层，但比它更简单。与EJBs不同，在这个层中的对象可能是相关的，并且他们的关系被拥有它们的factory管理。有一个定义明确的业务对象层对于成功的体系结构是非常重要的。 <br /><br />Spring ApplicationContext 是BeanFactory的子接口，为下列东西提供支持： <br /><br /><ul><br />信息查找，支持着国际化 <br /><br />事件机制，允许发布应用对象以及可选的注册以接收到事件 <br /><br />可移植的文件和资源访问 <br /></ul><br /><span style="FONT-WEIGHT: bold">XmlBeanFactory 例子</span><br /><br />Spring用户通常在XML的“bean定义”文件中配置他们的应用。Spring的XML bean定义文档的根是&lt;beans&gt; 元素。该元素包含一个或多个 &lt;bean&gt;定义。我们一般给每个bean定义的指定类和属性。我们还必须指定ID作为标识，这将成为在代码中使用该bean的名字。 <br /><br />让我们来看一个简单的例子，它配置了三个应用程序对象，之间的关系在J2EE应用中常常能够看到： <br /><br /><ul><br />J2EE DataSource <br /><br />使用DataSource的DAO <br /><br />在处理过程中使用DAO的业务对象 <br /></ul><br />在下面的例子中，我们使用一个来自Jakarta Commons DBCP项目的BasicDataSource。这个class（和其他许多已有的class一样）可以简单地被应用在Spring bean factory中，只要它提供了JavaBean格式的配置。需要在shutdown时被调用的Close方法可通过Spring的"destroy-method"属性被注册，以避免BasicDataSource需要实现任何Spring 的接口。 <br /><br /><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="FONT-FAMILY: 'Courier New', Courier, monospace"><br />&lt;beans&gt; <br /><br />  &lt;bean id="myDataSource" <br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="org.<span style="COLOR: #000000">apache</span>.<span style="COLOR: #000000">commons</span>.<span style="COLOR: #000000">dbcp</span>.<span style="COLOR: #000000">BasicDataSource</span>" <br />destroy-method="close"&gt; <br />    &lt;property name="driverClassName"&gt;&lt;value&gt;com.<span style="COLOR: #000000">mysql</span>.<span style="COLOR: #000000">jdbc</span>.<span style="COLOR: #000000">Driver</span>&lt;/value&gt;&lt;/property&gt; <br />    &lt;property name="url"&gt;&lt;value&gt;jdbc:mysql:<span style="COLOR: #6666ff">//localhost:3306/mydb&lt;/value&gt;&lt;/property&gt;</span><br />    &lt;property name="username"&gt;&lt;value&gt;root&lt;/value&gt;&lt;/property&gt; <br />  &lt;/bean&gt;</div><br /></td></tr></tbody></table><span class="postbody"><br />BasicDataSource中我们感兴趣的所有属性都是String类型的，因此我们用&lt;value&gt;元素来指定他们的值。如果必要的话，Spring使用标准的 JavaBean属性编辑器机制来把String转换为其他的类型。 <br /><br />现在，我们定义DAO，它有一个对DataSource的bean引用。Bean间关系通过&lt;ref&gt;元素来指定： <br /><br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="FONT-FAMILY: 'Courier New', Courier, monospace"><br />&lt;bean id="exampleDataAccessObject" <br />                <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="example.<span style="COLOR: #000000">ExampleDataAccessObject</span>"&gt; <br />    &lt;property name="dataSource"&gt;&lt;ref bean="myDataSource"/&gt;&lt;/property&gt; <br />  &lt;/bean&gt; <br /><br />The business object has a reference to the DAO, and an <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">int</span> property <span style="COLOR: #000000">(</span>exampleParam<span style="COLOR: #000000">)</span>: <br />&lt;bean id="exampleBusinessObject" <br />                <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="example.<span style="COLOR: #000000">ExampleBusinessObject</span>"&gt; <br />    &lt;property name="dataAccessObject"&gt;&lt;ref bean="exampleDataAccessObject"/&gt;&lt;/property&gt; <br />    &lt;property name="exampleParam"&gt;&lt;value&gt;<span style="COLOR: #000000" ?="">10</span>&lt;/value&gt;&lt;/property&gt; <br />  &lt;/bean&gt; <br /><br />&lt;/beans&gt;</div><br /></td></tr></tbody></table><span class="postbody"><br />对象间的关系一般在配置中明确地设置，象这个例子一样。我们认为这样做是件好事情。然而Spring还提供了我们称做"autowire"的支持， 一个la PicoContainer，其中它指出了bean间的依赖关系。这样做的局限性——PicoContainer也是如此——是如果有一个特殊类型的多个Bean，要确定那个类型所依赖的是哪个实例是不可能。好的方面是，不满足的依赖可以在factory初始化后被捕获到。（Spring 也为显式的配置提供了一种可选的依赖检查，它可以完成这个目的） <br /><br />在上面的例子中，如果我们不想显式的编写他们的关系，可使用如下的autowire特性： <br /><br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="FONT-FAMILY: 'Courier New', Courier, monospace"><br />&lt;bean id="exampleBusinessObject" <br />        <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span>="example.<span style="COLOR: #000000">ExampleBusinessObject</span>" <br />        autowire="byType"&gt; <br /><br />    &lt;property name="exampleParam"&gt;&lt;value&gt;<span style="COLOR: #000000" ?="">10</span>&lt;/value&gt;&lt;/property&gt; <br />&lt;/bean&gt;</div><br /></td></tr></tbody></table><span class="postbody"><br /><br />使用这个特性，Spring会找出exampleBusinessObject的dataSource属性应该被设置为在当前BeanFactory中找到的DataSource实现。在当前的BeanFactory中，如果所需要类型的bean不存在或多于一个，将产生一个错误。我们依然要设置exampleParam属性，因为它不是一个引用。 <br /><br />Autowire支持和依赖检查刚刚加入CVS并将在Spring 1.0 M2(到10/20,2003)中提供。本文中所讨论的所有其他特性都包含在当前1.0 M1版本中。 <br /><br />把管理从Java代码中移出来比硬编码有很大的好处，因为这样可以只改变XML文件而无需改变一行Java代码。例如，我们可以简单地改变myDataSource的bean定义引用不同的bean class以使用别的连接池，或者一个用于测试的数据源。 XML节变成另一种，我们可以用Spring的JNDI location FactoryBean从应用服务器获取一个数据源。 <br /><br />现在让我们来看看例子中业务对象的java 代码。注意下面列出的代码中没有对Spring的依赖。不像EJB容器，Spring BeanFactory不具有侵入性：在应用对象里面你通常不需要对Spring的存在硬编码。 <br /><br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="FONT-FAMILY: 'Courier New', Courier, monospace"><br /><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">class</span> ExampleBusinessObject <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">implements</span> MyBusinessObject <span style="COLOR: #000000">{</span><br /><br />        <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">private</span> ExampleDataAccessObject dao; <br />        <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">private</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">int</span> exampleParam; <br /><br />        <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> setDataAccessObject<span style="COLOR: #000000">(</span>ExampleDataAccessObject dao<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />                this.<span style="COLOR: #000000">dao</span> = dao; <br />        <span style="COLOR: #000000">}</span><br /><br />        <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> setExampleParam<span style="COLOR: #000000">(</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">int</span> exampleParam<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />                this.<span style="COLOR: #000000">exampleParam</span> = exampleParam; <br />        <span style="COLOR: #000000">}</span><br /><br />        <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">public</span><span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">void</span> myBusinessMethod<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />                <span style="COLOR: #6666ff">// do stuff using dao</span><br />        <span style="COLOR: #000000">}</span><br /><span style="COLOR: #000000">}</span></div><br /></td></tr></tbody></table><span class="postbody"><br />注意那些property setter，它们对应于bean定义文档中的XML引用。这些将在对象被使用之前由Spring调用。 <br /><br />这些应用程序的bean不需要依赖于Spring：他们不需要实现任何Spring的接口或者继承Spring的类。他们只需要遵守JavaBeans的命名习惯。在Spring 应用环境之外重用它们是非常简单的，例如，在一个测试环境中。只需要用它们的缺省构造函数实例化它们，并且通过调用setDataSource()和setExampleParam()手工设置它的属性。如果你想以一行代码支持程序化的创建，只要你有一个无参数的构造器，你就可以自由定义其他需要多个属性的构造函数。 <br /><br />注意在业务接口中没有声明将会一起使用的JavaBean属性。 他们是一个实现细节。我们可以“插入”带有不同bean属性的不同的实现类而不影响连接着的对象或者调用的代码。 <br /><br />当然，Spring XML bean factories 有更多的功能没有在这里描述，但是，应当让你对基本使用有了一些感觉。以及，简单的属性，有JavaBean属性编辑器的属性，Spring可以自动处理lists，maps和java.util.Properties。 <br /><br />Bean factories 和application contexts 通常和J2EE server定义的一个范围相关联，例如： <br /><br /><ul><br />Servlet context.：在spring 的MVC 框架里, 每一个包含common objects的web 应用都定义有一个应用程序的context。Spring提供了通过listener或者servlet实例化这样的context的能力而不需要依赖于Spring 的MVC 框架，因而它也可以用于Struts，WebWork 或者其他的web框架之中。 <br /><br />A Servlet：在Spring MVC 框架里每一个servlet控制器都有它自己的应用程序context，派生于根（全应用程序范围的）应用程序context。在Struts或者其他MVC框架中实现这些也很容意。 <br /><br />EJB：Spring 为EJB提供方便的超类，它们简化了EJB的创建并且提供了一个从EJB Jar 文件中的XML文档载入的BeanFactory。 <br /></ul><br />这些J2EE规范提供的hook通常避免了使用Singleton来创造一个bean factory。 <br /><br />然而，如果我们愿意的话可以用代码创建一个BeanFactory，虽然是没有什么意义的。例如，我们在以下三行代码中可以创建bean factory并且得到一个业务对象的引用： <br /><br /></span><table cellspacing="1" cellpadding="3" width="90%" align="center" border="0"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="FONT-FAMILY: 'Courier New', Courier, monospace"><br /><span style="COLOR: #aaaadd" ?="">InputStream</span> is = getClass<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span>.<span style="COLOR: #000000">getResourceAsStream</span><span style="COLOR: #000000">(</span>"myFile.<span style="COLOR: #000000">xml</span>"<span style="COLOR: #000000">)</span>; <br />XmlBeanFactory bf = <span style="FONT-WEIGHT: bold; COLOR: #990066" ?="">new</span> XmlBeanFactory<span style="COLOR: #000000">(</span>is<span style="COLOR: #000000">)</span>; <br />MyBusinessObject mbo = <span style="COLOR: #000000">(</span>MyBusinessObject<span style="COLOR: #000000">)</span> bf.<span style="COLOR: #000000">getBean</span><span style="COLOR: #000000">(</span>"exampleBusinessObject"<span style="COLOR: #000000">)</span>;</div><br /></td></tr></tbody></table><span class="postbody"><br /><br />这段代码将能工作在一个应用服务器之外：甚至不依赖J2EE，因为Spring 的IoC容器是纯java的。</span><span class="postbody"></span><span class="gensmall"><br />引自：<a href="http://forum.javaeye.com/viewtopic.php?t=4919">http://forum.javaeye.com/viewtopic.php?t=4919</a></span><img src ="http://www.blogjava.net/seaairland/aggbug/39111.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-04 11:24 <a href="http://www.blogjava.net/seaairland/archive/2006/04/04/39111.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>快速上手Spring－－2.HelloWorld(2)</title><link>http://www.blogjava.net/seaairland/archive/2006/04/04/39109.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 04 Apr 2006 03:07:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/04/39109.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/39109.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/04/39109.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/39109.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/39109.html</trackback:ping><description><![CDATA[
		<br />
		<div>   这篇文章主要谈谈Spring的入门开发，例子很简单，就是输出一条语句。有关各种软件的配置这里就不在多说了，如有不明白的，可以参考我以前的文章。</div>
		<div> </div>
		<div>在开始看这篇文章之前，最好弄清楚IoC、DI等概念，参考《<a href="http://blog.csdn.net/javamxj/archive/2005/06/23/401113.aspx"><font color="#006699">快速上手Spring－－1.收集的一些资料</font></a>》。  </div>
		<div> </div>
		<div>
				<a name="1">
						<span class="atitle2">
								<strong>
										<font size="4">一、下载和配置</font>
								</strong>
						</span>
				</a>
		</div>
		<div> </div>
		<div>
				<strong>
						<font size="2">1. 所需软件</font>
				</strong>
		</div>
		<div>
				<strong>
				</strong>
				<font size="2">
				</font> </div>
		<div>
				<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
						<font size="2">· JDK 5.0</font>
				</span>
		</div>
		<div>
				<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
				</span>
				<font size="2">
				</font> </div>
		<div>
				<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
						<font size="2">· </font>
				</span>
				<a href="http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/S-3.1RC3-200506171618/eclipse-SDK-3.1RC3-win32.zip">
						<font color="#006699" size="2">eclipse-SDK-3.1RC3-win32.zip</font>
				</a>
		</div>
		<div>
				<font color="#006699" size="2">
				</font> </div>
		<div>
				<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
						<font size="2">· </font>
				</span>
				<a href="http://xmlbuddy.com/2.0/58904908428240984589/409502405985075764578/3.1/xmlbuddy_2.0.62.zip">
						<font color="#006699" size="2">xmlbuddy_2.0.62.zip</font>
				</a>
		</div>
		<div>
				<font color="#006699" size="2">
				</font> </div>
		<div>
				<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
						<font size="2">· <span lang="EN-US"><span lang="EN-US"><a href="http://prdownloads.sourceforge.net/springframework/spring-framework-1.2.1-with-dependencies.zip?download"><font color="#006699">spring-framework-1.2.1-with-dependencies.zip</font></a></span></span></font>
				</span>
		</div>
		<div>
				<font color="#006699">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
								<span lang="EN-US">
										<span lang="EN-US">
										</span>
								</span>
						</span>
						<font size="2">
						</font>
				</font> </div>
		<div>
				<font size="2">如果安装后在Eclipse中看不到XmlBuddy，那么在eclipse命令后加上“-clean”参数。</font>
		</div>
		<div>
				<font size="2">
				</font> </div>
		<div> </div>
		<div>
				<strong>
						<font size="2">2. 配置</font>
				</strong>
		</div>
		<div>
				<font size="2">
				</font> </div>
		<div>
				<font size="2">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
								<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">●  </span>
						</span>配置Eclipse：</font>
		</div>
		<div>
				<font size="2">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>Window-&gt;Perferences-&gt;Java-&gt;Compiler:将"Compiler compliance level"设为“5.0”</font>
		</div>
		<div>
				<font size="2">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>Window-&gt;Perferences-&gt;Java-&gt;Build Path：勾选“Folders”</font>
		</div>
		<div>
				<font size="2">
				</font> </div>
		<div>
				<font size="2">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
								<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">●  </span>
						</span>建立库文件夹</font>
		</div>
		<div>
				<font size="2">
				</font> </div>
		<div>
				<font size="2">   具体做法参考《</font>
				<a href="http://blog.csdn.net/javamxj/archive/2005/04/02/335076.aspx">
						<font color="#3f68a6" size="2">Eclipse快速上手Hibernate--1. 入门实例</font>
				</a>
				<font size="2">》一文中的“建立库文件夹”的相关部分。</font>
		</div>
		<div>
				<font size="2">
				</font> </div>
		<div>
				<font size="2">   这里先将<span lang="EN-US"><span lang="EN-US"><a href="http://prdownloads.sourceforge.net/springframework/spring-framework-1.2.1-with-dependencies.zip?download"><font color="#006699">spring-framework-1.2.1-with-dependencies.zip</font></a>解压，将其中的spring.jar（dist目录中）、commons-logging.jar（libjakarta-commons目录）、log4j-1.2.9.jar（liblog4j目录）这三个文件复制到的”D:javaSpringlib" 目录中，然后在Eclipse中建立一个“Spring”库，将那三个文件添加进“Spring”库中。</span></span></font>
		</div>
		<div>
				<span lang="EN-US">
						<span lang="EN-US">
								<img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/122978/o_spring013.jpg" width="550" />
						</span>
				</span>
		</div>
		<div>
				<span lang="EN-US">
						<span lang="EN-US">
						</span>
				</span> </div>
		<div>
				<span lang="EN-US">
						<span lang="EN-US">
						</span>
				</span> </div>
		<div>
				<span lang="EN-US">
						<span lang="EN-US">
						</span>
				</span> </div>
		<div>
				<span lang="EN-US">
						<span lang="EN-US">
						</span>
				</span> </div>
		<div>
				<span lang="EN-US">
						<span lang="EN-US">
								<div>
										<a name="1">
												<span class="atitle2">
														<strong>
																<font size="4">二、项目实践</font>
														</strong>
												</span>
										</a>
								</div>
						</span>
				</span>
		</div>
		<div>
				<span lang="EN-US">
						<span lang="EN-US">
						</span>
				</span>
				<span lang="EN-US">
						<span lang="EN-US">
						</span>
				</span>
				<span lang="EN-US">
						<span lang="EN-US">
						</span>
				</span>
				<span lang="EN-US">
						<span lang="EN-US">
						</span>
				</span> </div>
		<div>
				<div>
						<strong>
								<font size="2">1. 创建项目</font>
						</strong>
				</div>
				<div>
						<font size="2">
						</font> </div>
				<div>
						<font size="2">
								<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·</span> 新建一个Java Project：<strong>SpringHello</strong>，注意要导入用户库Spring。</font>
				</div>
				<div>
						<font size="2">
						</font> </div>
				<div>
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">
								<font size="2">· 这是完成后整个项目的结构（预览一下）：</font>
						</span>
				</div>
				<div>
						<font size="2">
								<img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/122978/o_spring012.jpg" width="550" />
						</font>
				</div>
				<div>
						<font size="2">
						</font> </div>
				<div>
						<font size="2">
								<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·</span> 项目源码下载（不包含库文件）：</font>
						<a href="http://free.ys168.com/?javamxj">
								<font color="#006699" size="2">http://free.ys168.com/?javamxj</font>
						</a>
						<font size="2">  Spring目录下面。</font>
				</div>
				<div>
						<font size="2">
						</font> </div>
				<div>
						<font size="2">
						</font> </div>
				<div>
						<strong>
								<font size="2">2. 简单的HelloWorld</font>
						</strong>
				</div>
				<div>
						<font size="2">
						</font> </div>
		</div>
		<div>
				<font size="2">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·</span>下面开始创建一个新类：<strong>HelloWorld</strong> ；包名：<strong>javamxj.spring.beginning1，</strong>代码如下：</font>
		</div>
		<div>
				<div>
						<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="50%" border="0">
								<colgroup>
										<font size="2">
												<col width="256" />
										</font>
								</colgroup>
								<tbody>
										<tr>
												<td style="FONT-WEIGHT: bold; FONT-SIZE: 14px; BORDER-BOTTOM: rgb(51,51,204) thin inset; FONT-STYLE: italic; FONT-FAMILY: Courier New" valign="top" width="90%" bgcolor="#cccccc" height="16">
														<p>
																<font size="2">HelloWorld.java</font>
														</p>
												</td>
										</tr>
										<tr>
												<td style="FONT-SIZE: 12px; BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216); FONT-FAMILY: Courier New" valign="top" width="90%" bgcolor="#f7fbff">
														<div>
																<font size="2">
																		<span style="FONT-WEIGHT: bold; COLOR: #7f0055">package</span>
																		<span style="COLOR: #7f0055"> javamxj</span>
																		<span style="COLOR: #7f0055">.</span>
																		<span style="COLOR: #7f0055">spring</span>
																		<span style="COLOR: #7f0055">.</span>
																		<span style="COLOR: #7f0055">beginning1</span>
																		<span style="COLOR: #7f0055">;</span>
																		<br />
																		<br />
																		<span style="FONT-WEIGHT: bold; COLOR: #7f0055">public</span>
																		<span style="FONT-WEIGHT: bold; COLOR: #7f0055">class</span> HelloWorld {<br />    <span style="FONT-WEIGHT: bold; COLOR: #7f0055">public</span><span style="FONT-WEIGHT: bold; COLOR: #7f0055">static</span><span style="FONT-WEIGHT: bold; COLOR: #7f0055">void</span> main(<span style="FONT-WEIGHT: bold; COLOR: #7f0055">String</span>[] args) {        </font>
														</div>
														<div>
																<font size="2">
																		<span style="FONT-WEIGHT: bold; COLOR: #7f0055">        System</span>.out.println(<span style="COLOR: #2a00ff">"Hello World!"</span>);<br />    }<br />}</font>
														</div>
												</td>
										</tr>
								</tbody>
						</table>
				</div>
		</div>
		<div>
				<font size="2">OK！非常简单，我就是要它打印出一条语句“Hello World!”。</font>
		</div>
		<div>
				<font size="2">
				</font> </div>
		<div>
				<font size="2">
				</font> </div>
		<div>
				<font size="2">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">  </span>现在我不想输出“Hello World!”,我想随心所欲的输出任何语句，很简单啊！将“Hello World!”替换成所希望输出的语句即可。不过这样有一个缺点，每次修改好了，都需要重新编译一下程序。像这样的小程序固然无所谓，可是如果是一个大项目，这样做就有些讨厌了。</font>
		</div>
		<div>
				<font size="2">  还好，只要稍微修改一下程序，通过参数输入即可。 </font>
		</div>
		<div>
				<font size="2">
				</font> </div>
		<div>
				<font size="2">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>继续在这个包下建立一个新类：HelloWorldWithCommandLine，同样非常简单：</font>
		</div>
		<div>
				<div>
						<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="50%" border="0">
								<colgroup>
										<font size="2">
												<col width="256" />
										</font>
								</colgroup>
								<tbody>
										<tr>
												<td style="FONT-WEIGHT: bold; FONT-SIZE: 14px; BORDER-BOTTOM: rgb(51,51,204) thin inset; FONT-STYLE: italic; FONT-FAMILY: Courier New" valign="top" width="90%" bgcolor="#cccccc" height="16">
														<p>
																<font size="2">HelloWorldWithCommandLine.java</font>
														</p>
												</td>
										</tr>
										<tr>
												<td style="FONT-SIZE: 12px; BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216); FONT-FAMILY: Courier New" valign="top" width="90%" bgcolor="#f7fbff">
														<div>
																<font size="2">
																		<span style="FONT-WEIGHT: bold; COLOR: #7f0055">package</span>
																		<span style="COLOR: #7f0055"> javamxj</span>
																		<span style="COLOR: #7f0055">.</span>
																		<span style="COLOR: #7f0055">spring</span>
																		<span style="COLOR: #7f0055">.</span>
																		<span style="COLOR: #7f0055">beginning1</span>
																		<span style="COLOR: #7f0055">;</span>
																		<br />
																		<br />
																		<span style="FONT-WEIGHT: bold; COLOR: #7f0055">public</span>
																		<span style="FONT-WEIGHT: bold; COLOR: #7f0055">class</span> HelloWorldWithCommandLine {<br /><br />    <span style="FONT-WEIGHT: bold; COLOR: #7f0055">public</span><span style="FONT-WEIGHT: bold; COLOR: #7f0055">static</span><span style="FONT-WEIGHT: bold; COLOR: #7f0055">void</span> main(<span style="FONT-WEIGHT: bold; COLOR: #7f0055">String</span>[] args) {<br />        <span style="FONT-WEIGHT: bold; COLOR: #7f0055">if</span> (args.length &gt; 0) {<br />            <span style="FONT-WEIGHT: bold; COLOR: #7f0055">System</span>.out.println(args[0]);<br />        } <span style="FONT-WEIGHT: bold; COLOR: #7f0055">else</span> {<br />            <span style="FONT-WEIGHT: bold; COLOR: #7f0055">System</span>.out.println(<span style="COLOR: #2a00ff">"Hello World!"</span>);<br />        }<br />    }<br />}</font>
														</div>
												</td>
										</tr>
								</tbody>
						</table>
				</div>
		</div>
		<div>
				<font size="2">
				</font> </div>
		<div>
				<font size="2">
						<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>选中HelloWorldWithCommandLine，右击-&gt;Run As-&gt;Run...，在弹出窗口切换到“Arguments”栏，在“program arguments”中填入“Hello,javamxj!”，如下图：</font>
		</div>
		<div>
				<font size="2">
						<img alt="" src="http://blog.csdn.net/images/blog_csdn_net/javamxj/122978/o_spring011.jpg" width="550" />
				</font>
		</div>
		<div>
				<font size="2">这样，就输出了我希望的语句。</font>
		</div>
		<div>
				<font size="2">
				</font>
		</div>
		<div>
				<font size="2">第一部分到此，请继续看第二部分。</font>
		</div>
		<br />
<img src ="http://www.blogjava.net/seaairland/aggbug/39109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-04 11:07 <a href="http://www.blogjava.net/seaairland/archive/2006/04/04/39109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>快速上手Spring－－1.收集的一些资料</title><link>http://www.blogjava.net/seaairland/archive/2006/04/04/39108.html</link><dc:creator>chenhui</dc:creator><author>chenhui</author><pubDate>Tue, 04 Apr 2006 03:04:00 GMT</pubDate><guid>http://www.blogjava.net/seaairland/archive/2006/04/04/39108.html</guid><wfw:comment>http://www.blogjava.net/seaairland/comments/39108.html</wfw:comment><comments>http://www.blogjava.net/seaairland/archive/2006/04/04/39108.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/seaairland/comments/commentRss/39108.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/seaairland/services/trackbacks/39108.html</trackback:ping><description><![CDATA[
		<font face="Tahoma" size="2">  “好的开始是成功的一半”，但凡一种新的技术，开始阶段一般是很苦恼的。为了不让更多的人走同样的弯路，我这里就把学习Spring的经验与大家分享， 一起快乐一下。 
<div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma" size="2">  Spring是什么？反正这里我不会谈论春天的。我要说的是Spring Framework ,它又是用来做什么的呢？一会半会我也说不清楚。还好现在是互联网的时代，google一下，会发现不少有用的东西。 </font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma" size="2">     先来到Spring的大本营：</font><a href="http://www.springframework.org/"><font face="Tahoma" color="#006699" size="2">http://www.springframework.org/</font></a><font face="Tahoma" size="2">  可以看看 </font><a href="http://www.springframework.org/about"><font face="Tahoma" color="#006699" size="2">About Spring</font></a><font face="Tahoma" size="2">，最重要的是下载一个</font></div><div><font face="Tahoma" size="2">Spring版本。</font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2">     Spring的下载包有两种,一种是带有“with-dependencies”名称的，这种包含了Spring常用到的第三方包，比如Hibernate、<span lang="EN-US">aopalliance、<span lang="EN-US">jakarta-commons等。这里就使用了这种包，可以省却查找第三方包的麻烦。</span></span></font></font></div><div><span lang="EN-US"><span lang="EN-US"></span></span><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span lang="EN-US"><span lang="EN-US">     当前版本1.2.1 ：</span></span><span lang="EN-US"><span lang="EN-US"><a href="http://prdownloads.sourceforge.net/springframework/spring-framework-1.2.1-with-dependencies.zip?download"><font color="#006699">spring-framework-1.2.1-with-dependencies.zip</font></a></span></span></font></font></div><div><span lang="EN-US"><span lang="EN-US"></span></span><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma" size="2">     解压这个包，可以在 docs<br />eference目录下找到Spring 的参考手册，有html和pdf两种格式。如果你的英文不太好，可以看看</font><a href="http://spring.jactiongroup.net/"><font face="Tahoma" color="#006699" size="2">Spring中文论坛</font></a><font face="Tahoma" size="2">翻译的</font><a href="http://gro.clinux.org/frs/download.php/986/spring-reference.pdf"><font face="Tahoma" color="#006699" size="2">1.1版本的中文版</font></a><font face="Tahoma" size="2">（pdf格式）。这个参考手册就是入门的不二法宝。</font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">●</span>     新手刚学Spring时，可能对一些概念似懂非懂，比如IoC（这里可不是国际奥委会）、DI等。这里向你推荐几篇好文章，有助于理解Spring。</font></font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>Rod Johnson：</font></font><a href="http://www.theserverside.com/articles/article.tss?l=SpringFramework"><font face="Tahoma" color="#006699" size="2">Introduction to Spring Framework</font></a><font face="Tahoma" size="2"> （Spring 1.2版本）</font></div><div><span class="maintitle"><font face="Tahoma" size="2">     Java视线论坛上翻译：</font><a href="http://forum.javaeye.com/viewtopic.php?t=4919"><font face="Tahoma" color="#006699" size="2">Introducing to Spring Framework（中文修订版 旧版本）</font></a><font face="Tahoma" size="2"></font></span></div><div><span class="maintitle"></span><font face="Tahoma" size="2"></font> </div><div><span class="maintitle"><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>Robert C Martin, Bob： The Dependency Inversion Principle</font></font></span></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>Martin Fowler：</font></font><a href="http://www.martinfowler.com/articles/injection.html"><font face="Tahoma" color="#006699" size="2">Inversion of Control Containers and the Dependency Injection pattern</font></a></div><div><font face="Tahoma" size="2">     透明对此文的翻译： </font><a href="http://gigix.blogdriver.com/diary/gigix/inc/DependencyInjection.pdf"><font face="Tahoma" color="#006699" size="2">IoC 容器和Dependency Injection 模式</font></a></div><div><font face="Tahoma" color="#006699" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>冰云： </font></font><a href="http://dev.csdn.net/develop/article/24/24397.shtm"><font face="Tahoma" color="#006699" size="2">介绍 IOC</font></a><font face="Tahoma" size="2">     </font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>夏昕：</font></font><a href="http://www.xiaxin.net/Spring_Dev_Guide.rar"><font face="Tahoma" color="#006699" size="2">Spring开发指南</font></a></div><div><font face="Tahoma" color="#006699" size="2"></font> </div><div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>良葛格：</font></font><a href="http://www.javaworld.com.tw/confluence/display/opensrc/Spring"><font face="Tahoma" color="#006699" size="2">Spring入门</font></a><font face="Tahoma" size="2">（非常适合新手入门）</font></div></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">· </span>javaboutique网站上有篇教程（入门）： </font></font><a href="http://javaboutique.internet.com/tutorials/spring_frame/"><font face="Tahoma" color="#006699" size="2">The Spring Framework</font></a></div><div><font face="Tahoma" color="#006699" size="2"></font> </div><div><font face="Tahoma" color="#006699" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">●  </span> 如果要系统的学习Spring，还是需要Book的。</font></font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·  </span>Rod Johnson：</font></font><a href="http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764543857.html"><font face="Tahoma" color="#006699" size="2">Expert One-on-One J2EE Design and Development</font></a><font face="Tahoma" size="2">(10/2002)</font></div><div><font face="Tahoma" size="2">看看作者是谁，就知道这本书的质量如何了。毫无疑问，这本书吹响了向Spring进军的号角。前半部分主要阐述了J2EE开发的方方面面的经验和设计，后半部分通过对J2EE的改善设计而引申出了SpringFramework。这本书的中译本也出来了，不过翻译的一般。</font></div><div><font face="Tahoma" size="2">           </font></div><div><font face="Tahoma" size="2"> <span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·  </span>Rod Johnson, Juergen Hoeller：   </font><a href="http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764558315.html"><font face="Tahoma" color="#006699" size="2">Expert One-on-One J2EE Development without EJB</font></a><font face="Tahoma" size="2">（7/2004）</font></div><div><font face="Tahoma" size="2">看看书名就会吓一跳，不过Rod Johnson完全有资格说出来。前半本介绍EJB的不足，后半本讲Spring的原理。这本书的中译本也出来了。</font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma" size="2"> <span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·  </span>Bruce A. Tate, Justin Gehtland：</font><a href="http://www.oreilly.com/catalog/bfljava/"><font face="Tahoma" color="#006699" size="2">Better, Faster, Lighter Java</font></a><font face="Tahoma" size="2">（5/2004）</font></div><div><font face="Tahoma" size="2">这本书主要阐述了如何利用Java进行轻量级开发，有关Spring的内容比较少，只有一章，不过此书获得了Jolt 大奖，质量肯定没的说了。</font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·  </span> Craig Walls, Ryan Breidenbach：  </font></font><a href="http://www.manning.com/books/walls2"><font face="Tahoma" color="#006699" size="2">Spring in Action</font></a><font face="Tahoma" size="2">（1/2005）</font></div><div><font face="Tahoma" size="2">Manning出版的“in action”系列图书，质量一直非常好。此书系统介绍了Spring的方方面面，解析相当清晰。 </font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·  </span>Matt Raible: </font></font><a href="http://www.sourcebeat.com/TitleAction.do?id=7"><font face="Tahoma" color="#006699" size="2">Spring Live</font></a><font face="Tahoma" size="2"> </font></div><div><font face="Tahoma" size="2">这本是source beat的电子书(只出电子版)。如果要深入这本书，需要有相当的基础。这本书非常适合有实践项目经验的人。采用TDD的方式使用Spring，而且提供Spring整合其他framework的各种作法 (相当多）。同时作者也维护着一个开源的项目</font><a href="http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse"><font face="Tahoma" color="#006699" size="2">appfuse</font></a><font face="Tahoma" size="2">。 </font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·  </span>Rob Harrop，Jan Machacek：</font></font><a href="http://www.apress.com/book/bookDisplay.html?bID=405"><font face="Tahoma" color="#006699" size="2">Pro Spring</font></a><font face="Tahoma" size="2">（1/2005）</font></div><div><font face="Tahoma" size="2">我目前只看过了样章，还很不错，很系统，也很细致，尤其书中提供的源代码很适合新手练习。</font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·  </span>Rod Johnson等5人： </font></font><a href="http://as.wiley.com/WileyCDA/WileyTitle/productCd-0764574833.html"><font face="Tahoma" color="#006699" size="2">Professional Java Development with the Spring Framework</font></a></div><div><font face="Tahoma" size="2">预计2005年7月出版，作者阵容挺庞大的，几乎都是Spring开发团队的，值得期待。 </font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">·  </span>罗时飞  </font></font><a href="http://www.open-v.com/"><font face="Tahoma" color="#006699" size="2">精通Spring</font></a></div><div><font face="Tahoma" size="2">这好像是目前为止系统介绍Spring的唯一简体中文书籍。</font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma" size="2">以上书籍都在网上提供了书中的源代码下载和部分样章，如果拿不到书，看看源代码也是很不错。</font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma"><font size="2"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">●  </span>说完书籍，再介绍一些好的论坛。</font></font></div><div><font face="Tahoma" size="2"></font> </div><div><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><font face="Tahoma" size="2">· </font></span><a href="http://forum.springframework.org/"><font face="Tahoma" color="#006699" size="2">SpringFramework官方论坛 </font></a></div><div><font face="Tahoma" color="#006699" size="2"></font> </div><div><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><font face="Tahoma" size="2">· </font></span><a href="http://spring.jactiongroup.net/"><font face="Tahoma" color="#006699" size="2">SpringFramework中文论坛</font></a></div><div><font face="Tahoma" color="#006699" size="2"></font> </div><div><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><font face="Tahoma" size="2">· </font></span><a href="http://www.matrix.org.cn/topic.shtml?forumId=26"><font face="Tahoma" color="#006699" size="2">Matrix网站的Spring论坛</font></a><font face="Tahoma" size="2">  </font></div><div><font face="Tahoma" size="2"></font> </div><div><span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 12.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><font face="Tahoma" size="2">· </font></span><a href="http://www.hibernate.org.cn/viewforum.php?f=32&amp;sid=da0cc399bf2ccf1cb219299a779c6380"><font face="Tahoma" color="#006699" size="2">Java视线论坛上的SpringFramework</font></a></div><div><font face="Tahoma" color="#006699" size="2"></font> </div><div><font face="Tahoma" size="2">最后给大家推荐一个不错的资源收集站点  </font><a href="http://www.java201.com/"><font face="Tahoma" color="#006699" size="2">http://www.java201.com/</font></a></div><div><font face="Tahoma" size="2">在其右上方的搜索栏中填入“spring”，可以获得不少整理好的有关spring的资料。</font></div><div><font face="Tahoma" size="2"></font> </div><div><font face="Tahoma" size="2">好了，先写到这里了，以后会陆续添加一些好的资料和站点</font></div></font>
<img src ="http://www.blogjava.net/seaairland/aggbug/39108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/seaairland/" target="_blank">chenhui</a> 2006-04-04 11:04 <a href="http://www.blogjava.net/seaairland/archive/2006/04/04/39108.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>