隨筆-22  評(píng)論-6  文章-17  trackbacks-0
            2005年11月22日
          帕金森定律

            美國著名歷史學(xué)家諾斯古德-帕金森通過長(zhǎng)期調(diào)查研究,寫了一本名叫《帕金森定律》的書,他在書中闡述了機(jī)構(gòu)人員膨脹的原因及后果:一個(gè)不稱職的官員,可能有三條出路。第一是申請(qǐng)退職,把位子讓給能干的人;第二是讓一位能干的人來協(xié)助自己工作;第三是任用兩個(gè)水平比自己更低的人當(dāng)助手。

            這第一條路是萬萬走不得的,因?yàn)槟菢訒?huì)喪失許多權(quán)力;第二條路也不能走,因?yàn)槟莻€(gè)能干的人會(huì)成為自己的對(duì)手;看來只有第三條路最適宜。于是,兩個(gè)平庸的助手分擔(dān)了他的工作,他自己則高高在上發(fā)號(hào)施令。兩個(gè)助手既無能,也就上行下效,再為自己找兩個(gè)無能的助手。如此類推,就形成了一個(gè)機(jī)構(gòu)臃腫、人浮于事、相互扯皮、效率低下的領(lǐng)導(dǎo)體系。

            苛希納定律

            西方管理學(xué)中有一條著名的苛希納定律:如果實(shí)際管理人員比最佳人數(shù)多兩倍,工作時(shí)間就要多兩倍,工作成本就要多四倍;如果實(shí)際管理人員比最佳人數(shù)多三倍,工作時(shí)間就要多三倍,工作成本就要多六倍。

            苛希納定律告訴我們,在管理上并不是人多力量大,管理人員越多,工作效率未必就會(huì)越高??料<{定律要求我們,要認(rèn)真研究并找到一個(gè)最佳人數(shù),以最大限度地減少工作時(shí)間,降低工作成本。

            馬蠅效應(yīng)

            林肯少年時(shí)和他的兄弟在肯塔基老家的一個(gè)農(nóng)場(chǎng)里犁玉米地,林肯吆馬,他兄弟扶犁,而那匹馬很懶,慢慢騰騰,走走停停。可是有一段時(shí)間馬走得飛快。林肯感到奇怪,到了地頭,他發(fā)現(xiàn)有一只很大的馬蠅叮在馬身上,他就把馬蠅打落了。看到馬蠅被打落了,他兄弟就抱怨說:“哎呀,你為什么要打掉它,正是那家伙使馬跑起來的嘛!”

            沒有馬蠅叮咬,馬慢慢騰騰,走走停停;有馬蠅叮咬,馬不敢怠慢,跑得飛快。這就是馬蠅效應(yīng)。馬蠅效應(yīng)給我們的啟示是:一個(gè)人只有被叮著咬著,他才不敢松懈,才會(huì)努力拼搏,不斷進(jìn)步。

            “南風(fēng)”法則

            “南風(fēng)”法則也稱“溫暖”法則,源于法國作家拉封丹寫過的一則寓言:北風(fēng)和南風(fēng)比威力,看誰能把行人身上的大衣脫掉。北風(fēng)首先來一個(gè)冷風(fēng)凜冽寒冷刺骨,結(jié)果行人為了抵御北風(fēng)的侵襲,便把大衣裹得緊緊的。南風(fēng)則徐徐吹動(dòng),頓時(shí)風(fēng)和日麗,行人因?yàn)橛X得春暖上身,始而解開紐扣,繼而脫掉大衣,南風(fēng)獲得了勝利。

            這則寓言形象地說明了一個(gè)道理:溫暖勝于嚴(yán)寒。領(lǐng)導(dǎo)者在管理中運(yùn)用“南風(fēng)”法則,就是要尊重和關(guān)心下屬,以下屬為本,多點(diǎn)“人情味”,盡力解決下屬日常生活中的實(shí)際困難,使下屬真正感受到領(lǐng)導(dǎo)者給予的溫暖,從而激發(fā)出工作的積極性。

            酒與污水定律

            酒與污水定律是指,如果把一匙酒倒進(jìn)一桶污水中,你得到的是一桶污水;如果把一匙污水倒進(jìn)一桶酒中,你得到的還是一桶污水。

            在任何組織里,都存在幾個(gè)難弄的人物,他們存在的目的似乎就是為了把事情搞糟。最糟糕的是,他們像果箱里的爛蘋果一樣,如果你不及時(shí)處理,它會(huì)迅速傳染,把果箱里其他的蘋果也弄爛。“爛蘋果”的可怕之處在于它那驚人的破壞力。一個(gè)正直能干的人進(jìn)入一個(gè)混亂的部門可能被吞沒,而一個(gè)無德無才者能很快將一個(gè)高效的部門變成一盤散沙。一個(gè)能工巧匠花費(fèi)時(shí)日精心制作的陶瓷品,一頭驢子一秒鐘就能將它毀壞掉。
          posted @ 2007-11-27 14:18 surffish 閱讀(374) | 評(píng)論 (0)編輯 收藏

           ?。?、WINKEY+D:這是高手最常用的第一快捷組合鍵(木頭按:也是我最喜歡用的哦,好像有點(diǎn)自詡為高手)。這個(gè)快捷鍵組合可以將桌面上的所有窗口瞬間最小化,無論是聊天的窗口還是游戲的窗口……只要再次按下這個(gè)組合鍵,剛才的所有窗口都回來了,而且激活的也正是你最小化之前在使用的窗口!

           ?。病INKEY + F:不用再去移動(dòng)鼠標(biāo)點(diǎn)“開始→搜索→文件和文件夾”了,在任何狀態(tài)下,只要一按WINKEY+F就會(huì)彈出搜索窗口。

           ?。?、WINKEY + R:在我們的文章中,你經(jīng)常會(huì)看到這樣的操作提示:“點(diǎn)擊‘開始→運(yùn)行’,打開‘運(yùn)行’對(duì)話框……”。其實(shí),還有一個(gè)更簡(jiǎn)單的辦法,就是按WINKEY + R!

            4、ALT + TAB :如果打開的窗口太多,這個(gè)組合鍵就非常有用了,它可以在一個(gè)窗口中顯示當(dāng)前打開的所有窗口的名稱和圖標(biāo),選中自己希望要打開的窗口,松開這個(gè)組合鍵就可以了。而ALT+TAB+SHIFT鍵則可以反向顯示當(dāng)前打開的窗口。

           ?。?、WINKEY + E:當(dāng)你需要打開資源管理器找文件的時(shí)候,這個(gè)快捷鍵會(huì)讓你感覺非?!八保≡僖膊挥抿v出一只手去摸鼠標(biāo)了!
          ?????????6、WINKEY+L,鎖定計(jì)算機(jī)

          小提示:
            WINKEY指的是鍵盤上刻有Windows徽標(biāo)的鍵。WINKEY主要出現(xiàn)在104鍵和107鍵的鍵盤中。104鍵盤又稱Win95鍵盤,這種鍵盤在原來101鍵盤的左右兩邊、Ctrl和Alt鍵之間增加了兩個(gè)Windwos鍵和一個(gè)屬性關(guān)聯(lián)鍵。107鍵盤又稱為Win98鍵盤,比104鍵多了睡眠、喚醒、開機(jī)等電源管理鍵,這3個(gè)鍵大部分位于鍵盤的右上方。
          posted @ 2007-02-15 15:30 surffish 閱讀(165) | 評(píng)論 (0)編輯 收藏
          不論你是單一團(tuán)隊(duì)的領(lǐng)導(dǎo)者還是多個(gè)團(tuán)隊(duì)的管理人,團(tuán)隊(duì)管理工作都是你職權(quán)范圍內(nèi)一個(gè)重要的組成部分。在今日,集多重技術(shù)于一身的工作方法已逐漸取代階層式的、缺乏彈性的傳統(tǒng)工作體制,團(tuán)隊(duì)合作因而很快就成為了一種很受歡迎的工作方式。對(duì)于每一位參與團(tuán)隊(duì)管理工作的人而言,《團(tuán)隊(duì)管理》是一本不可或缺的重要讀物。它向你提供了達(dá)成計(jì)劃所需的技巧、建立團(tuán)隊(duì)成員間的信任、激發(fā)團(tuán)隊(duì)最大的潛能等方面的知識(shí),為你能專業(yè)化地管理好你的團(tuán)隊(duì)創(chuàng)造了有利條件。另外,全書還散布了101條簡(jiǎn)明提示,為你提供重要而實(shí)用的訊息。后半部分有個(gè)自我評(píng)估練習(xí),使你能正確地評(píng)估自己的領(lǐng)導(dǎo)能力,并針對(duì)自己的不足加以改進(jìn)。

          了解團(tuán)隊(duì)運(yùn)作

            團(tuán)隊(duì)合作是所有成功管理的根基。無論你是新手還是資深管理人,對(duì)你而言,管理好團(tuán)隊(duì)都是重要且具激勵(lì)性的挑戰(zhàn)。

          1.切記:每位成員都能為團(tuán)隊(duì)作出一些貢獻(xiàn)。

          2.謹(jǐn)慎地設(shè)定團(tuán)隊(duì)目標(biāo),且認(rèn)真嚴(yán)肅地對(duì)待它們。

          3.切記成員間要彼此扶持。

          4.將長(zhǎng)程目標(biāo)打散成許多短程計(jì)劃。

          5.為每個(gè)計(jì)劃設(shè)定明確的期限。

          6.盡早決定何種形態(tài)的團(tuán)隊(duì)適合你的目標(biāo)。

          7.努力與其它團(tuán)隊(duì)的成員建立強(qiáng)有力的緊密關(guān)系。

          8.找一位可提升團(tuán)隊(duì)工作士氣的重量級(jí)人物。

          9.時(shí)時(shí)提醒團(tuán)隊(duì)成員:他們都是團(tuán)隊(duì)的一份子。

          10.將團(tuán)隊(duì)的注意力集中在固定可衡量的目標(biāo)上。

          11.利用友誼的強(qiáng)大力量強(qiáng)化團(tuán)隊(duì)。

          12.選擇領(lǐng)導(dǎo)者時(shí)要把握用人唯才原則。

          13.領(lǐng)導(dǎo)者需具備強(qiáng)烈的團(tuán)隊(duì)使命感。

          14.獎(jiǎng)賞優(yōu)異的表現(xiàn),但絕不姑息錯(cuò)誤。

          15.記住每位團(tuán)隊(duì)成員看事情的角度都不一樣。

          16.征召團(tuán)隊(duì)成員時(shí),應(yīng)注重他們的成長(zhǎng)潛能。

          17.密切注意團(tuán)隊(duì)成員缺少的相關(guān)經(jīng)驗(yàn)。

          18.應(yīng)使不適任的成員退出團(tuán)隊(duì)。

          19.找到能將人際關(guān)系處理得很好的人,并培養(yǎng)他們。

          設(shè)立一支團(tuán)隊(duì)

            成立一支團(tuán)隊(duì)是領(lǐng)導(dǎo)者的主要工作。確保你的團(tuán)隊(duì)有清楚明確的目的和足夠達(dá)成目標(biāo)的資源。要以開放和公正無私的態(tài)度對(duì)待團(tuán)隊(duì)成員。

          20.設(shè)定具挑戰(zhàn)性的目標(biāo)須根據(jù)限期來考量是否合理。

          21.設(shè)定目標(biāo)時(shí),考量個(gè)別成員的工作目標(biāo)。

          22.計(jì)劃的失敗危及整體計(jì)劃的成功。

          23.堅(jiān)持得到信息技術(shù)支持,它能為你提供確實(shí)需要的東西。

          24.對(duì)待團(tuán)隊(duì)外的顧問要如同對(duì)待團(tuán)隊(duì)成員一般。

          25.讓團(tuán)隊(duì)的贊助者隨時(shí)知道工作進(jìn)展情形。

          26.除非你確定沒有人能夠勝任,否則應(yīng)避免“事必躬親”。

          27.不要委托不必要的工作,最好將其去除掉。

          28.賦予團(tuán)隊(duì)自己作決策的權(quán)力。

          29.鼓勵(lì)團(tuán)隊(duì)成員正面積極的貢獻(xiàn)。

          30.肯定、宣揚(yáng)和慶祝團(tuán)隊(duì)每次的成功。

          31.找到易于讓成員及團(tuán)隊(duì)了解每日工作進(jìn)度的展現(xiàn)方式。

          32.鼓勵(lì)成員之間建立工作上的伙伴關(guān)系。

          33.鼓勵(lì)天生具有領(lǐng)導(dǎo)才能的人,并引導(dǎo)和培養(yǎng)他們的領(lǐng)導(dǎo)技巧。

          34.絕對(duì)不能沒有解釋就駁回團(tuán)隊(duì)的意見,與此相反,解釋要坦白,理由要充分。

          35.確定團(tuán)隊(duì)和客戶經(jīng)常保持聯(lián)系。

          36.以自信肯定的態(tài)度讓團(tuán)隊(duì)知道誰當(dāng)家,但要預(yù)防予人來勢(shì)洶洶的感覺。

          37.想辦法給新團(tuán)隊(duì)留下一個(gè)實(shí)時(shí)的好印象,但切忌操之過急。

          38.倘若你要求別人的建議,抱持的心態(tài)不能只是歡迎就行了,也要依循建議有所行動(dòng)。

          提升團(tuán)隊(duì)效率

            團(tuán)隊(duì)要達(dá)到應(yīng)有的效率,唯一的條件是每個(gè)成員都要學(xué)會(huì)集中力量。你必須了解團(tuán)隊(duì)的能力,以確保團(tuán)隊(duì)的成功。

          39.協(xié)助團(tuán)隊(duì)找出方法以改變有礙任務(wù)推展的團(tuán)體行為。

          40.找出可建設(shè)性地利用沖突的方法。

          41.記住要在工作中穿插安排娛樂調(diào)劑身心──這是每個(gè)人應(yīng)得的福利。

          42.若有計(jì)劃出錯(cuò),一定要作全面性、公開化的分析。

          43.如果你希望團(tuán)隊(duì)成員有問題時(shí)能毫不猶疑地找你談,就要實(shí)施“開門政策”。

          44.要求提出問題的人解決問題。

          45.安排正式的和非正式的會(huì)面,討論團(tuán)隊(duì)的工作進(jìn)展。

          46.使用不帶感情只問事實(shí)的態(tài)度,是化解紛爭(zhēng)的最好方法。

          47.保持團(tuán)隊(duì)成員間的熟稔,以易于溝通。

          48.設(shè)立交誼場(chǎng)所,讓團(tuán)隊(duì)成員可作非正式的碰面交談。

          49.鼓勵(lì)同事間自由的溝通活動(dòng)。

          50.建立最適合的通訊科技系統(tǒng),并經(jīng)常更新。

          51.實(shí)施會(huì)議主席輪流制,讓每個(gè)人都有機(jī)會(huì)主持會(huì)議。

          52.盡可能多地授權(quán)給團(tuán)隊(duì)成員。

          53.事先于會(huì)前發(fā)出議程,預(yù)留時(shí)間給與會(huì)者準(zhǔn)備。

          54.培養(yǎng)所有對(duì)團(tuán)隊(duì)有益的關(guān)系。

          55.努力保持團(tuán)隊(duì)內(nèi)外關(guān)系的均衡與平穩(wěn)。

          56.確定所有相關(guān)人士都能聽到、了解好消息。

          57.倘有麻煩在團(tuán)隊(duì)關(guān)系中發(fā)酵蘊(yùn)釀,要盡快處理。

          58.安排團(tuán)隊(duì)與機(jī)構(gòu)的其它部門作社交聯(lián)誼。

          59.找出你與“大佬”保持聯(lián)系的最佳通訊科技。

          60.要對(duì)你在團(tuán)隊(duì)或辦公室外接觸過的重要人士作聯(lián)系記錄。

          61.謹(jǐn)慎分派角色以避免任務(wù)重復(fù)。

          62.找尋建議中的精華,且絕不在公開場(chǎng)合批評(píng)任何建議。

          63.一定要找有經(jīng)驗(yàn)的人解決問題。

          64.分析團(tuán)隊(duì)成員每個(gè)人所扮演的角色。

          65.腦力激發(fā)出的意見,就算不采用,亦不得輕視。否則,會(huì)打擊人的積極性,創(chuàng)意的流動(dòng)也會(huì)因此停止。

          66.公平對(duì)待每個(gè)成員才能避免怨恨。

          67.確定團(tuán)隊(duì)成員真正有錯(cuò)之前,都須視他們沒有錯(cuò)。

          68.告訴同事他們做得很好,這有助于激勵(lì)團(tuán)隊(duì)士氣。

          69.尊重每一位成員,包括那些給你制造麻煩的人。

          70.避免和團(tuán)隊(duì)成員有直接的沖突。

          71.記住采用對(duì)事不對(duì)人的處事態(tài)度。

          72.確定整個(gè)團(tuán)隊(duì)都能夠從解決問題中學(xué)習(xí)經(jīng)驗(yàn)。

          73.先選擇完成一些規(guī)模大的、可快速達(dá)成及有成就感的任務(wù),以激勵(lì)成員再接再勵(lì)。

          74.確信團(tuán)隊(duì)成員皆了解團(tuán)隊(duì)中的其它角色。

          75.計(jì)算品質(zhì)的成本之前,先計(jì)算失敗的成本。

          76.針對(duì)每筆預(yù)算及每項(xiàng)團(tuán)隊(duì)行動(dòng)計(jì)劃,設(shè)定重大的改進(jìn)目標(biāo)。

          為未來努力

          為團(tuán)隊(duì)設(shè)定新的、更高的挑戰(zhàn)目標(biāo)是團(tuán)隊(duì)工作中最令人興奮的事情之一??蛇\(yùn)用一些適當(dāng)?shù)募记?,推?dòng)團(tuán)隊(duì)向更大、更好的目標(biāo)前進(jìn)。

          77.告知團(tuán)隊(duì)每位成員,在設(shè)定的標(biāo)準(zhǔn)中有哪些評(píng)量的項(xiàng)目。

          78.確定所有改善措施及新訂目標(biāo)都持續(xù)進(jìn)行著。

          79.召開檢討會(huì)議前傳閱所有相關(guān)資料及資料。

          80.開檢討會(huì)時(shí)一定要避諱人身攻擊。

          81.記住關(guān)系會(huì)隨時(shí)間改變。

          82.避開低估或忽視壞消息的陷井。

          83.每天結(jié)束時(shí)自問團(tuán)隊(duì)今天是否又向前跨出了一步。

          84.傾聽受訓(xùn)者關(guān)于訓(xùn)練課程的回饋意見。

          85.找到有最好設(shè)備的最佳訓(xùn)練場(chǎng)所。

          86.聘請(qǐng)顧問設(shè)立公司內(nèi)部的訓(xùn)練課程。

          87.利用移地訓(xùn)練時(shí)的用餐時(shí)間作非正式的計(jì)劃。

          88.每位團(tuán)隊(duì)成員都必須參與設(shè)定目標(biāo)的工作,以促進(jìn)團(tuán)隊(duì)合作及達(dá)成共識(shí)。

          89.允許團(tuán)隊(duì)自行決定達(dá)成目標(biāo)的方法,可激勵(lì)團(tuán)隊(duì)努力工作。

          90.確定目標(biāo)能激發(fā)團(tuán)隊(duì)的斗志,如果不行,請(qǐng)改變目標(biāo)。

          91.一支沒有“嚴(yán)峻”目標(biāo)的團(tuán)隊(duì),工作表現(xiàn)將不如接受過此類考驗(yàn)的團(tuán)隊(duì)。

          92.設(shè)定獎(jiǎng)勵(lì)標(biāo)準(zhǔn)時(shí),允許團(tuán)隊(duì)成員有發(fā)言權(quán)。

          93.避免使用名次表,因?yàn)槁浜蟮膱F(tuán)隊(duì)成員將會(huì)感到自尊心受創(chuàng)。

          94.指定某人監(jiān)視市場(chǎng)上每一個(gè)相關(guān)變化。

          95.隨時(shí)準(zhǔn)備作改變,甚至計(jì)劃的根本要素亦包含在改變的范圍內(nèi)。

          96.記住有某些人很害怕變革。

          97.尋找能推動(dòng)改革的團(tuán)隊(duì)成員。

          98.每隔一段時(shí)間作一次生涯發(fā)展的評(píng)量。

          99.記?。汗膭?lì)團(tuán)隊(duì)成員即是在幫助團(tuán)隊(duì)。

          100.與團(tuán)隊(duì)同事就生涯規(guī)劃達(dá)成一致意見,并給他們提供必要的協(xié)助。

          101.團(tuán)隊(duì)解散后仍舊要與團(tuán)隊(duì)成員保持聯(lián)系,因?yàn)槟憧赡苓€會(huì)與他們?cè)俅魏献?/p>

          posted @ 2006-09-21 08:05 surffish 閱讀(206) | 評(píng)論 (0)編輯 收藏

          LEFT JOIN 和 RIGHT JOIN 運(yùn)算

          用于 FROM 子句時(shí),把源表記錄組合起來。

          語法

          FROM1 [ LEFT | RIGHT ] JOIN2
          ????ON 1.字段1compopr 2. 字段2

          LEFT JOIN 及 RIGHT JOIN 運(yùn)算可分為以下幾個(gè)部分:

          部分 說明
          table1, table2 記錄被組合的表的名稱。
          field1, field2 被聯(lián)接的字段的名稱。且這些字段必須有相同的數(shù)據(jù)類型及包含相同類型的數(shù)據(jù),但它們不需要有相同的名稱。
          compopr 任何的關(guān)系比較運(yùn)算子:"=," "<," ">," "<=," ">=," 或 "<>."

          說明

          用 LEFT JOIN 運(yùn)算 創(chuàng)建左邊外部聯(lián)接.左邊外部聯(lián)接將包含了從第一個(gè)(左邊)開始的兩個(gè)表中的全部記錄,即使在第二個(gè)(右邊)表中并沒有相符值的記錄。

          用RIGHT JOIN 運(yùn)算 創(chuàng)建 右邊外部聯(lián)接.右邊外部聯(lián)接將包含了從第二個(gè)(右邊)開始的兩個(gè)表中的全部記錄,即使在第一個(gè)(左邊)表中并沒有匹配值的記錄。

          例如,可以使用 LEFT JOIN 與部門(左邊)及員工(右邊)表來選擇所有的部門,包含了沒有分配到員工的部門。可以使用 RIGHT JOIN 選擇所有的員工,包含了沒有分配到部門的員工。

          下列示例顯示如何在類標(biāo)識(shí)符字段中聯(lián)接類表及產(chǎn)品表。查詢將會(huì)列出所有種類的列表,包含那些沒有產(chǎn)品在其中的種類:

          SELECT CategoryName,

          ProductName

          FROM Categories LEFT JOIN Products

          ON Categories.CategoryID = Products.CategoryID;

          在本例中,CategoryID 是聯(lián)接的字段,但由于它不包含在 SELECT 語句中,因此,也不包含在查詢結(jié)果中。要包含聯(lián)接的字段,請(qǐng)?jiān)?SELECT 語句中輸入字段名 — 在這個(gè)示例中為 Categories.CategoryID。


          注意

          欲創(chuàng)建只包含聯(lián)接字段中數(shù)據(jù)相同的記錄的查詢,請(qǐng)用 INNER JOIN 運(yùn)算。

          • 在 INNER JOIN 之中可以寫一個(gè)嵌套的 LEFT JOIN 或一個(gè) RIGHT JOIN,但是在一個(gè) LEFT JOIN 或一個(gè) RIGHT JOIN 之中不能寫嵌套的 INNER JOIN。請(qǐng)參閱 INNER JOIN 主題中有關(guān)使用嵌套的討論,從其中可獲知如何在其它聯(lián)接中編寫嵌套聯(lián)接的信息。
          • 可以鏈接多個(gè) ON 子句。若需更多信息,請(qǐng)參閱在 INNER JOIN 主題中的子句鏈接的討論。

          若試圖聯(lián)接包含 MemoOLE Object數(shù)據(jù)的字段,會(huì)導(dǎo)致錯(cuò)誤。


          請(qǐng)參閱
          FROM 子句 (Microsoft Jet SQL) UNION 運(yùn)算 (Microsoft Jet SQL)
          INNER JOIN 運(yùn)算 (Microsoft Jet SQL) ?

          示例

          LEFT JOIN 和 RIGHT JOIN 運(yùn)算示例

          posted @ 2006-09-03 11:52 surffish 閱讀(242) | 評(píng)論 (0)編輯 收藏
          關(guān)閉msn,在開始->運(yùn)行中分別輸入
          regsvr32 softpub.dll

          regsvr32 mssip32.dll

          regsvr32 intipki.dll

          regsvr32 MSXML3.dll

          11221399B
          再重新啟動(dòng)msn即可
          posted @ 2006-08-21 08:03 surffish 閱讀(219) | 評(píng)論 (0)編輯 收藏
          1. 在業(yè)務(wù)層使用JDBC直接操作數(shù)據(jù)庫-最簡(jiǎn)單,最直接的操作

          1)數(shù)據(jù)庫url,username,password寫死在代碼中
          Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
          String url="jdbc:oracle:thin:@localhost:1521:orcl";
          String user="scott";
          String password="tiger";
          Connection conn= DriverManager.getConnection(url,user,password);
          Statement stmt=conn.createStatement(
          ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
          String sql="select * from test";
          ResultSet rs=stmt.executeQuery(sql);

          2)采用Facade和Command模式,使用DBUtil類封裝JDBC操作;
          數(shù)據(jù)庫url,username,password可以放在配置文件中(如xml,properties,ini等)。
          這種方法在小程序中應(yīng)用較多。

          2.DAO(Data Accessor Object)模式-松耦合的開始
          DAO = data + accessor + domain object

          例如User類-domain object (javabean)
          UserDAO類-accessor ,提供的方法getUser(int id),save(User user)內(nèi)包含了JDBC操作
          在業(yè)務(wù)邏輯中使用這兩個(gè)類來完成數(shù)據(jù)操作。

          使用Factory模式可以方便不同數(shù)據(jù)庫連接之間的移植。

          3.數(shù)據(jù)庫資源管理模式
          3.1 數(shù)據(jù)庫連接池技術(shù)
          資源重用,避免頻繁創(chuàng)建,釋放連接引起大大量性能開銷;
          更快的系統(tǒng)響應(yīng)速度;

          通過實(shí)現(xiàn)JDBC的部分資源對(duì)象接口( Connection, Statement, ResultSet ),可以使用Decorator設(shè)計(jì)模式分別產(chǎn)生三種邏輯資源對(duì)象: PooledConnection, PooledStatement和 PooledResultSet。


          一個(gè)最簡(jiǎn)單地?cái)?shù)據(jù)庫連接池實(shí)現(xiàn):
          public class ConnectionPool {

          private static Vector pools;
          private final int POOL_MAXSIZE = 25;
          /**
          * 獲取數(shù)據(jù)庫連接
          * 如果當(dāng)前池中有可用連接,則將池中最后一個(gè)返回;若沒有,則創(chuàng)建一個(gè)新的返回
          */
          public synchronized Connection getConnection() {
          Connection conn = null;
          if (pools == null) {
          pools = new Vector();
          }

          if (pools.isEmpty()) {
          conn = createConnection();
          } else {
          int last_idx = pools.size() - 1;
          conn = (Connection) pools.get(last_idx);
          pools.remove(last_idx);
          }

          return conn;
          }

          /**
          * 將使用完畢的數(shù)據(jù)庫連接放回池中
          * 若池中連接已經(jīng)超過閾值,則關(guān)閉該連接;否則放回池中下次再使用
          */
          public synchronized void releaseConnection(Connection conn) {
          if (pools.size() >= POOL_MAXSIZE)
          try {
          conn.close();
          } catch (SQLException e) {
          // TODO自動(dòng)生成 catch 塊
          e.printStackTrace();
          } else
          pools.add(conn);
          }

          public static Connection createConnection() {
          Connection conn = null;
          try {
          Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
          String url = "jdbc:oracle:thin:@localhost:1521:orcl";
          String user = "scott";
          String password = "tiger";
          conn = DriverManager.getConnection(url, user, password);
          } catch (InstantiationException e) {
          // TODO自動(dòng)生成 catch 塊
          e.printStackTrace();
          } catch (IllegalAccessException e) {
          // TODO自動(dòng)生成 catch 塊
          e.printStackTrace();
          } catch (ClassNotFoundException e) {
          // TODO自動(dòng)生成 catch 塊
          e.printStackTrace();
          } catch (SQLException e) {
          // TODO自動(dòng)生成 catch 塊
          e.printStackTrace();
          }
          return conn;
          }
          }

          注意:利用getConnection()方法得到的Connection,程序員很習(xí)慣地調(diào)用conn.close()方法關(guān)閉了數(shù)據(jù)庫連接,那么上述的數(shù)據(jù)庫連接機(jī)制便形同虛設(shè)。在調(diào)用conn.close()方法方法時(shí)如何調(diào)用releaseConnection()方法?這是關(guān)鍵。這里,我們使用Proxy模式和java反射機(jī)制。

          public synchronized Connection getConnection() {
          Connection conn = null;
          if (pools == null) {
          pools = new Vector();
          }

          if (pools.isEmpty()) {
          conn = createConnection();
          } else {
          int last_idx = pools.size() - 1;
          conn = (Connection) pools.get(last_idx);
          pools.remove(last_idx);
          }

          ConnectionHandler handler=new ConnectionHandler(this);
          return handler.bind(con);
          }

          public class ConnectionHandler implements InvocationHandler {
          private Connection conn;
          private ConnectionPool pool;

          public ConnectionHandler(ConnectionPool pool){
          this.pool=pool;
          }

          /**
          * 將動(dòng)態(tài)代理綁定到指定Connection
          * @param conn
          * @return
          */
          public Connection bind(Connection conn){
          this.conn=conn;
          Connection proxyConn=(Connection)Proxy.newProxyInstance(
          conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),this);
          return proxyConn;
          }

          /* (非 Javadoc)
          * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
          */
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
          // TODO自動(dòng)生成方法存根
          Object obj=null;
          if("close".equals(method.getName())){
          this.pool.releaseConnection(this.conn);
          }
          else{
          obj=method.invoke(this.conn, args);
          }

          return obj;
          }
          }

          在實(shí)際項(xiàng)目中,并不需要你來從頭開始來設(shè)計(jì)數(shù)據(jù)庫連接池機(jī)制,現(xiàn)在成熟的開源項(xiàng)目,如C3P0,dbcp,Proxool等提供了良好的實(shí)現(xiàn)。一般推薦使用Apache dbcp,基本使用實(shí)例:
          DataSource ds = null;
          try{
          Context initCtx = new InitialContext();
          Context envCtx = (Context) initCtx.lookup("java:comp/env");
          ds = (DataSource)envCtx.lookup("jdbc/myoracle");
          if(ds!=null){
          out.println("Connection is OK!");
          Connection cn=ds.getConnection();
          if(cn!=null){
          out.println("cn is Ok!");
          Statement stmt = cn.createStatement();
          ResultSet rst = stmt.executeQuery("select * from BOOK");
          out.println("

          rst is Ok!" + rst.next());
          while(rst.next()){
          out.println("

          BOOK_CODE:" + rst.getString(1));
          }
          cn.close();
          }else{
          out.println("rst Fail!");
          }
          }
          else
          out.println("Fail!");
          }catch(Exception ne){ out.println(ne);
          }


          3.2 Statement Pool
          普通預(yù)編譯代碼:
          String strSQL=”select name from items where id=?”;
          PreparedStatement ps=conn.prepareStatement(strSQL);
          ps.setString(1, “2”);
          ResultSet rs=ps.executeQuery();

          但是PreparedStatement 是與特定的Connection關(guān)聯(lián)的,一旦Connection關(guān)閉,則相關(guān)的PreparedStatement 也會(huì)關(guān)閉。
          為了創(chuàng)建PreparedStatement 緩沖池,可以在invoke方法中通過sql語句判斷池中還有沒有可用實(shí)例。

          4. 持久層設(shè)計(jì)與O/R mapping 技術(shù)
          1) Hernate:適合對(duì)新產(chǎn)品的開發(fā),進(jìn)行封閉化的設(shè)計(jì)
          Hibernate 2003年被Jboss接管,通過把java pojo對(duì)象映射到數(shù)據(jù)庫的table中,采用了xml/javareflection技術(shù)等。3.0提供了對(duì)存儲(chǔ)過程和手寫sql的支持,本身提供了hql語言。
          開發(fā)所需要的文件:
          hibernate配置文件: hibernate.cfg.xml 或 hibernate.properties
          hibernate 映射文件: a.hbm.xml
          pojo類源文件: a.java  

          導(dǎo)出表與表之間的關(guān)系:
          a. 從java對(duì)象到hbm文件:xdoclet
          b. 從hbm文件到j(luò)ava對(duì)象:hibernate extension
          c. 從數(shù)據(jù)庫到hbm文件:middlegen
          d. 從hbm文件到數(shù)據(jù)庫:SchemaExport

          2)Iatis :適合對(duì)遺留系統(tǒng)的改造和對(duì)既有數(shù)據(jù)庫的復(fù)用,有很強(qiáng)的靈活性 3) Apache OJB:優(yōu)勢(shì)在于對(duì)標(biāo)準(zhǔn)的全面支持 4)EJB:適合集群服務(wù)器,其性能也不象某些人所詬病的那么差勁 5) JDO (java data object)
          設(shè)置一個(gè)Properties對(duì)象,從而獲取一個(gè)JDO的PersistenceManagerFactory(相當(dāng)于JDBC連接池中的DataSource),進(jìn)而獲得一個(gè)PersistenceManager對(duì)象(相當(dāng)于JDBC中的Connection對(duì)象),之后,你可以用這個(gè)PersistenceManager對(duì)象來增加、更新、刪除、查詢對(duì)象。
          JDOQL是JDO的查詢語言;它有點(diǎn)象SQL,但卻是依照J(rèn)ava的語法的。

          5. 基于開源框架的Struts+Spring+Hibernate實(shí)現(xiàn)方案
          示例:這是一個(gè)3層架構(gòu)的web 程序,通過一個(gè)Action 來調(diào)用業(yè)務(wù)代理,再通過它來回調(diào) DAO類。下面的流程圖表示了MyUsers是如何工作的。數(shù)字表明了流程的先后順序,從web層(UserAction)到中間層(UserManager),再到數(shù)據(jù)層(UserDAO),然后返回。
          Spring是AOP, UserManager和UserDAO都是接口.
          1) web層(UserAction) :調(diào)用中間層的接口方法,將UserManager作為屬性注入。
          采用流行的Struts框架,雖然有很多人不屑一顧,但是這項(xiàng)技術(shù)在業(yè)界用的比較普遍,能滿足基本的功能,可以減少培訓(xùn)學(xué)習(xí)成本。
          2) 中間層(UserManager):將UserDAO作為屬性注入,其實(shí)現(xiàn)主要是調(diào)用數(shù)據(jù)層接口的一些方法;它處于事務(wù)控制中。
          采用Spring框架實(shí)現(xiàn),IOC與AOP是它的代名詞,功能齊全,非常棒的一個(gè)架構(gòu)。
          3) 數(shù)據(jù)層(UserDAO):實(shí)現(xiàn)類繼承HibernateDaoSupport類,在該類中可以調(diào)用getHibernateTemplate()的一些方法執(zhí)行具體的數(shù)據(jù)操作。
          采用Hibernate做O/R mapping,從種種跡象可以看出,Hibernate就是EJB3.0的beta版。 (轉(zhuǎn)載文章請(qǐng)保留出處:Java家(www.javajia.com))

          posted @ 2006-04-18 11:05 surffish 閱讀(265) | 評(píng)論 (0)編輯 收藏
          【品名】民間俗稱老婆,正式場(chǎng)合可稱妻子或夫人;古稱內(nèi)人,現(xiàn)亦可叫愛人。
          【成分】水、血液和脂肪類碳水化合物。
          【性狀】本品為細(xì)長(zhǎng)條塊狀糖衣片,表面涂層一般為粉底、口紅等化妝物,除去後呈淺黃色,外觀與除去前略有差異;本品隨時(shí)間推移,形狀會(huì)有所改變,出現(xiàn)發(fā)胖、起皺等現(xiàn)象,但不影響繼續(xù)使用。
          【功能主治】主治單身恐懼癥及傳宗接代等頑疾,對(duì)失戀和相思病也有明顯效果。
          【用法用量】口服兼外用,一次限一片。對(duì)無效者,可暫時(shí)停用并向婚姻專家咨詢,或間隔一段時(shí)間後重復(fù)使用。
          【注意事項(xiàng)】本品僅適用于單身之成年男性。服用時(shí) 小心謹(jǐn)慎,細(xì)心觀察有無不良反應(yīng),如有必須馬上停止服用,沒有則可繼續(xù)使用。若忌煙酒等不良習(xí)慣,會(huì)使療效更佳。
          【規(guī)格】通常為45千克至55千克,特殊情況下亦有例外。
          【貯藏】常溫下妥善保存,室內(nèi)陰涼處最佳;如在室外,則 避免強(qiáng)烈陽光直射。 貯藏期間,尤忌隨意棄置一旁不管
          posted @ 2006-03-23 12:00 surffish 閱讀(268) | 評(píng)論 (0)編輯 收藏

          用java寫服務(wù)端代碼

          import java.io.*;
          import java.net.*;
          public class test {
            public test() {
            }
            public static final int PORT = 8080;
            public static final String ip = "10.194.111.222";

            public static void main(String[] args) throws IOException {
              ServerSocket s = new ServerSocket(51,2,InetAddress.getByName(ip));
              System.out.println("Started: " + s);
              try {
                // Blocks until a connection occurs:
                Socket socket = s.accept();
                try {
                  System.out.println(
                    "Connection accepted: "+ socket);
                  BufferedReader in =
                    new BufferedReader(
                      new InputStreamReader(
                        socket.getInputStream()));
                  // Output is automatically flushed
                  // by PrintWriter:
                  PrintWriter out =
                    new PrintWriter(
                      new BufferedWriter(
                        new OutputStreamWriter(
                          socket.getOutputStream())),true);
                  while (true) {
                    String str = in.readLine();
                    if (str.equals("END")) break;
                    System.out.println("Echoing: " + str);
                    out.println(str);
                  }
                // Always close the two sockets...
                } finally {
                  System.out.println("closing...");
                  socket.close();
                }
              } finally {
                s.close();
              }
            }
          }

          .net寫客戶端代碼
          private void button2_Click(object sender, System.EventArgs e)
            {
             try
             {
              stSend = new Socket ( AddressFamily.InterNetwork ,
               SocketType.Stream , ProtocolType.Tcp ) ;
              //初始化一個(gè)Socket實(shí)例
              IPEndPoint tempRemoteIP = new IPEndPoint(IPAddress.Parse("10.194.111.222"),51);
              //根據(jù)IP地址和端口號(hào)創(chuàng)建遠(yuǎn)程終結(jié)點(diǎn)
              EndPoint epTemp =  ( EndPoint ) tempRemoteIP;
              stSend.Connect ( epTemp ) ;

             }
             catch ( Exception err)
             {
              string s = err.ToString();
             }
            }

          posted @ 2005-12-09 16:36 surffish 閱讀(1183) | 評(píng)論 (0)編輯 收藏

          1.工作區(qū): (顯隱)

          項(xiàng)目面板:ctrl + Alt + p (Project)
          設(shè)計(jì)面板: ctrl + Alt + c (content)
          結(jié)構(gòu)面板: ctrl + Alt + s (Structure)
          信息面板: ctrl + Alt + M (Message)
          狀態(tài)面板: ctrl + Alt + Z


          2.主面板:(代碼面板和設(shè)計(jì)面板)

          激活代碼模塊: ctrl + J (@1)
          參數(shù)提示信息的激活: ctrl + shift + H
          打開查詢、替換窗口: ctrl + F
          類的查詢: ctrl + -


          3.F 鍵的用法

          F1: 幫助快捷
          F4: 運(yùn)行多行
          F5: 加入斷點(diǎn)
          F7: 當(dāng)遇到方法時(shí)會(huì)運(yùn)行方法內(nèi)的代碼
          F8: 逐步運(yùn)行代碼
          F12: 代碼面板和設(shè)計(jì)面板切換


          4. Shift 鍵的用法

          添加多個(gè)相同組件: 按shift鍵在選項(xiàng)上選取組件,把組件添加到窗口即可
          調(diào)整組件間間隔和對(duì)齊: 假設(shè)有組件JPanel 1/2/3;(要達(dá)到3個(gè)組件寬度相同,組件間隔相等,并且都是依據(jù)JPanel1左對(duì)齊),按shift鍵,用鼠標(biāo)選中需要調(diào)整的組件,(第一個(gè)選中的組件是其他的基準(zhǔn))然后右鍵。


          5: codeInsight 和 Codetemplates
          MemberInsight -- 根據(jù)當(dāng)前的代碼提示可用的類成員或方法(說明)
          ParameterInsight -- 提示當(dāng)前的方法需要使用的參數(shù)
          SymbolInsigh -- 查看當(dāng)前的變量、方法或者類的愿代碼。

          MemberInsight: ctrl + space 或 ctrl + H
          ParameterInsight: ctrl + shift + space 或 ctrl + shift + H
          SymbolInsight: ctrl + Enter 或 Alt + shift + H
          ClassInsight : ctrl + alt + space 或 ctrl + alt + H




          注: (@1):使用代碼功能:(ctrl + J)
          1、 在想要輸入代碼的位置輸入代碼摸板名,然后按 ctrl + J(開發(fā)人員可以用主菜單上的Tools/Editor/Templates命令來查看代碼摸板的名字)
          2、把光標(biāo)定位于想要輸入代碼的位置,然后按ctrl + J

          posted @ 2005-12-09 11:40 surffish 閱讀(293) | 評(píng)論 (0)編輯 收藏

          Eclipse基礎(chǔ)--java環(huán)境變量設(shè)置

          http://blog.csdn.net/javamxj/archive/2004/10/11/131935.aspx

          我是一名java的愛好者,理所當(dāng)然裝了不少java方面的軟件,大部分是開放源碼的,而且多數(shù)是綠色軟件,只要解壓,設(shè)置一下環(huán)境變量即可使用。

           
             由于軟件本身升級(jí)比較頻繁,經(jīng)常需要重新設(shè)置使用的環(huán)境變量,而且我常常同時(shí)安裝同一軟件的不同版本(甚至是相同版本)。如eclipse我就分別在F,G,H三個(gè)盤上裝了不同的版本,一個(gè)是中文版,一個(gè)是英文的Latest Release,一個(gè)是Stream Stable,反正是綠色安裝,也不會(huì)發(fā)生沖突,這樣通過對(duì)比便于了解和測(cè)試最新版本的先進(jìn)之處。
             但是假如把JDK版本從1.3升級(jí)到1.4,即JDK目錄名可能要從“j2sdk1.3”改為“j2sdk1.4”,如果是這樣的話,那么eclipse可能會(huì)無法再啟動(dòng)了(它要從環(huán)境變量中尋找JAVA_HOME變量,而JAVA_HOME變量值已經(jīng)從“j2sdk1.3”改為“j2sdk1.4”了)。
             在談?wù)刯akarta-tomcat,這個(gè)軟件升級(jí)比較頻繁,如果你是結(jié)合eclipse來使用Tomcat的,那么每次Tomcat升級(jí),可能都要在eclipse中重新設(shè)置一下Tomcat的安裝目錄,是不是有些麻煩?
           
              對(duì)于此類問題,解決的方法很簡(jiǎn)單,只要把默認(rèn)的軟件安裝目錄名去掉版本號(hào)即可(如果擔(dān)心忘記版本號(hào),只要在目錄中添加一個(gè)readme文件加以說明即可)。
             
          如上圖,我的j2sdk,ant,jakata-tomcat等都沒有版本號(hào)。
           
             同樣,在環(huán)境變量設(shè)置中也沒有出現(xiàn)版本號(hào)。
             
           
          這樣,如果再需要升級(jí)軟件時(shí),僅僅把新版軟件安裝在舊版軟件目錄即可。其它一般都不需要再改動(dòng)了。
           
          另外,在環(huán)境變量設(shè)置中,可以用%變量%代替變量值,如Path變量值可以這樣設(shè)置:  %JAVA_HOME%\bin;%JBOSS_HOME%\bin;%ANT_HOME%\bin;
          posted @ 2005-12-07 16:31 surffish 閱讀(477) | 評(píng)論 (0)編輯 收藏

          我們要開發(fā)一個(gè)java類:其內(nèi)容只有一句,輸出"hello ant"字符串。并使用ant完成編譯和運(yùn)行工作,這個(gè)例子只是為了跑通ant,不附加多余的東西。

          下圖為文件組織,請(qǐng)建立相應(yīng)的目錄,并編寫HelloAnt.java

          按照人家老外的文件組織規(guī)則咱也照搬。

           hello.ant.HelloAnt.java

          在項(xiàng)目根目錄(hello-ant\)寫1個(gè)文件:ant執(zhí)行配置文件build.xml

           build.xml

          ok,一切大功告成,哦,不,還沒有運(yùn)行它。

          dos下進(jìn)入hello-ant的目錄,即build.xml所在的目錄,我們要用ant工具執(zhí)行它 , 

          執(zhí)行: %ant_home%/bin/ant -file build.xml     用ant工具執(zhí)行當(dāng)前目錄下的配置文件build.xml 

          或  :ant -file build.xml                    你如果設(shè)置%ant_home%/bin到path中

          這次ok了,這是答案:

          命令提示符窗口
          D:\temp\hello-ant>ant -file build.xml
          Buildfile: build.xml

          main:
          [javac] Compiling 1 source file to D:\temp\hello-ant\build\classes
          [java] hello ant,ant 的第一次接觸,好棒!

          BUILD SUCCESSFUL
          Total time: 2 seconds
          D:\temp\hello-ant>

          檢查一下build/classes目錄,哦,看到編譯過的文件就在這里:
          build/classes/hello/ant/HelloAnt.class.

          hello ant 進(jìn)級(jí)

          (此段比較廢話,可以略過)
          你也許會(huì)說:這末簡(jiǎn)單的工作寫個(gè)批處理不就得了,又xml又ant的,把我的時(shí)間都浪費(fèi)完了,我用jbuild或
          webShpere不就得了,怎末說你才明白呢?反正網(wǎng)上開源項(xiàng)目大多數(shù)都用ant,你總不能給人家個(gè)*.jpx吧,
          而且這樣的工具太貴,受不了(當(dāng)然用D的兄弟不怕^_^ ),而且ant可以讓你明確的管理和自動(dòng)化所有的東西:
          編譯-實(shí)施-測(cè)試...,哎,稍微麻煩一點(diǎn)點(diǎn),但節(jié)約你以前花在零碎的copy,paste上的時(shí)間.而且我發(fā)現(xiàn)管理
          代碼的質(zhì)量有所提高.

          我們要改進(jìn)build.xml,讓它做更多的事情:

          • 定義全局變量
          • 初始化,主要是建立目錄
          • 編譯  (已有)
          • 打包為jar
          • 建立API documentation
          • 生成distribution產(chǎn)品

          凡事都講究平衡,你要ant給你做更多事,當(dāng)然要累一點(diǎn)點(diǎn),不過只用累一次,以后的代碼修改后的構(gòu)建都是"一鍵式"完成,我們制作一個(gè)hello的簡(jiǎn)單例子,你可以自己做j2ee的練習(xí)。

          我們要擴(kuò)充目錄結(jié)構(gòu),使它更像回事:

          ant處理編譯之前的目錄:

          ant處理之后的目錄:

          圖中:\src,\docs,\lib是自己組織的文件結(jié)構(gòu),\build,\dist是ant動(dòng)態(tài)生成的成品。

          \src                     源文件:java源,script源,jsp源,xml配置.....
          \src\main         java源
          \src\script     window,unix,liunx的執(zhí)行script,我們的簡(jiǎn)單只有一個(gè):
                            run.bat:  java hello.ant.HelloAnt

          \docs                手寫說明文檔
          \lib                   程序所需類庫的jar,比如j2ee.jar,mail,jar...

          \build               用ant動(dòng)態(tài)生成的構(gòu)建目錄
          \build\classes  編譯的類文件
          \build\docs         copy "\docs"的手寫說明文檔,和ant生成的api文檔
          \build\lib           放置我們自己的HelloAnt.class打包成品hello-ant.jar

          \dist\bin        copy "\src\script" 得執(zhí)行文件
          \dist\docs      copy "\build\docs" 的文檔
          \dist\lib         除了copy "\build\lib"下的hello-ant.jar外,
                                        還應(yīng)copy "\lib"的程序所需jar,這里我們沒有。

          以上是我學(xué)老外的文件組織,大家可以按照自己的愛好組織

          我們編寫必要的文件:

          hello.ant. HelloAnt.java
          已有
          \src\script.bat
          \docs\index.html 隨便寫一個(gè)手寫的文檔

          hello ant 軟件項(xiàng)目手冊(cè)docs


          訪問api文檔

           
          \build.xml 配置文件 


          build.xml多了些,但其實(shí)很簡(jiǎn)單:(注釋比較詳細(xì)可以參照,這里再簡(jiǎn)單說一下)

          一個(gè)build.xml包含一個(gè)工程的自動(dòng)化處理的完整xml說明,并且基本由3種東東組成:

          <project >

              1.全局變量的定義
              <property/>

              2.任務(wù)組
              <target>
                  3.許多單項(xiàng)任務(wù)... 像copy,delete,javac,jar...
                  <task1/>
                  <task2/>
                  <task3/>
              </target>

          </project>

          參考及下載:

          本文程序:第1個(gè)hello-ant

          本文程序:第2個(gè)進(jìn)階的hello-ant

          ant最新下載:
          http://jakarta.apache.org/ant/index.html
           

          ant具體的編寫方法參考ant手冊(cè)以下2部分就形,
          http://jakarta.apache.org/ant/manual/using 使用說明
          http://jakarta.apache.org/ant/manual/coretasklist.html 核心tasks
          其他一大堆東西你要看也行。不過我覺得比較浪費(fèi)時(shí)間。
          http://jakarta.apache.org/ant/manual/index.html
            手冊(cè)index

          huihoo.com翻譯改編的ant/manual/using
          http://www.huihoo.com/java/ant.html

          用ANT構(gòu)造Application作者:余斌斌    
          http://developer.ccidnet.com/pub/disp/Article?columnID=295&articleID=27619&pageNO=1

          ibm 利用 Ant 和 JUnit 進(jìn)行增量開發(fā)——使用單元測(cè)試來逐步改進(jìn)代碼

          http://www-900.ibm.com/developerWorks/cn/java/j-ant/index.shtml

          posted @ 2005-12-07 14:33 surffish 閱讀(574) | 評(píng)論 (1)編輯 收藏

          本文以最新發(fā)布的Ant 1.5.1為例,介紹這款優(yōu)秀的Build工具的安裝配置、基本應(yīng)用和一些高級(jí)話題。最新的Ant下載地址是 http://jakarta.apache.org/ant/ 。

          Ant是一種基于Java的Build工具。理論上來說,它有些類似于C中的make,但比make優(yōu)越?,F(xiàn)在存在的大多數(shù)Build工具,如make、gnumake、nmake、jam等都存在這樣或那樣的不足,比如依賴于特定的平臺(tái)、配置文件過于復(fù)雜或者對(duì)格式無法檢查而容易出錯(cuò)等。與這些工具相比較,Ant的兩個(gè)特性決定了它是一款優(yōu)秀的Build工具:

          1. 基于Java的實(shí)現(xiàn)。具有良好的跨平臺(tái)性,同時(shí)可以通過增加新的Java類來擴(kuò)展Ant的功能,而無需去了解不同平臺(tái)上不同的腳本語言。

          2.基于XML的配置文件。Ant以XML樹來描述Target/Task的關(guān)系,文件結(jié)構(gòu)清晰、易讀易寫,并且利用XML對(duì)格式的控制來避免由于配置文件的錯(cuò)誤造成的Build操作失敗。

          安裝與配置

          Ant的安裝非常簡(jiǎn)單,把從網(wǎng)上下載的jakarta-ant-1.5.1-bin.zip解開到一個(gè)目錄下即可(以下假定安裝在目錄D:\jakarta-ant-1.5.1)。接下來需要進(jìn)行環(huán)境變量配置:

          SET ANT_HOME=D:\jakarta-ant-1.5.1 //注意是Ant的安裝目錄,不是bin子目錄
          SET PATH=%PATH%;%ANT_HOME%\bin;


          在配置環(huán)境變量之前,請(qǐng)確認(rèn)已經(jīng)正確設(shè)置了JAVA_HOME系統(tǒng)變量。輸入ant命令,看到如下輸出說明已成功安裝了Ant工具:

          Buildfile: build.xml does not exist!
          Build failed


          提示信息表明在當(dāng)前目錄不存在build.xml配置文件,但這本身已經(jīng)說明Ant成功運(yùn)行了。

          快速入門

          下面用一個(gè)最簡(jiǎn)單也是最經(jīng)典的例子-HelloWorld來感受一下Ant吧。

          //HelloWorld.java
          package com.sharetop.antdemo;
          public class HelloWorld {
          public static void main( String args[] ) {
          System.out.println("Hello world. ");
          }
          }


          要讓Ant編譯這個(gè)文件,首先需要編寫一個(gè)Build配置文件。在一般情況下,這個(gè)文件被命名為build.xml。

          <?xml version="1.0" encoding="UTF-8" ?>
          <project name="HelloWorld" default="run" basedir="." >
          <property name="src" value="src"/>
          <property name="dest" value="classes"/>
          <property name="hello_jar" value="hello.jar" />
          <target name="init">
          <mkdir dir="${dest}"/>
          </target>
          <target name="compile" depends="init">
          <javac srcdir="${src}" destdir="${dest}"/>
          </target>
          <target name="build" depends="compile">
          <jar jarfile="${hello_jar}" basedir="${dest}"/>
          </target>
          <target name="run" depends="build">
          <java classname="com.sharetop.antdemo.HelloWorld" classpath="${hello_jar}"/>
          </target>
          </project>


          來看一下這個(gè)文件的內(nèi)容,它描述了以下信息:工程的名字為HelloWorld,工程有四個(gè)target,分別是init、compil、build和run,缺省是run。compile只有一個(gè)任務(wù)javac,源文件位于src目錄下,輸出的類文件要放在classes目錄下。build的任務(wù)是jar,生成的jar文件為hello.jar,它打包時(shí)以classes為根目錄。而run則是執(zhí)行這個(gè)HelloWorld類,用hello.jar作為classpath。這四個(gè)target之間有一個(gè)依賴關(guān)系,這種關(guān)系用depends來指定。即如果Target A依賴于Target B,那么在執(zhí)行Target A之前會(huì)首先執(zhí)行Target B。所以從下面運(yùn)行缺省Target(run)的輸出看,這四個(gè)Target的執(zhí)行順序是:init→compile→build→run。文件目錄結(jié)構(gòu)如圖1所示。HelloWorld.java文件在src\com\sharetop\antdemo子目錄下。


          圖1 ant_demo應(yīng)用的目錄結(jié)構(gòu)


          在命令行輸入命令:ant,然后運(yùn)行,可以看到如下輸出:

          如果配置文件名不是build.xml,比如是build_front.xml,那么,可以使用-buildfile命令參數(shù)指定:

          G:\myDoc\ant_demo>ant -buildfile build_front.xml


          也可以單獨(dú)執(zhí)行指定的某個(gè)target,比如,只編譯不打包執(zhí)行,可以使用下面輸入命令即可:

          G:\myDoc\ant_demo>ant compile

          在相應(yīng)的目錄下會(huì)找到編譯出的HelloWorld.class文件。

          再看看上面的build.xml配置文件,文件開頭定義了3個(gè)屬性,分別指定了源文件輸出路徑、類文件輸出路徑和生成的Jar文件名,后面對(duì)這些路徑的引用都通過一個(gè)${property name}來引用。所以,要注意這樣一個(gè)原則“目錄的定義與目錄的引用應(yīng)該分開”。
          基本應(yīng)用

          建立工程的目錄

          一般要根據(jù)工程的實(shí)際情況來建立工程的目錄結(jié)構(gòu)。但是,有一些比較通用的組織形式可供參考,比如所有的jakarta項(xiàng)目都使用類似的目錄結(jié)構(gòu)。下面讓我們來看一下這種目錄結(jié)構(gòu)的特點(diǎn)。

          表1

          目錄 文件
          bin 公共的二進(jìn)制文件,以及運(yùn)行腳本
          build 臨時(shí)創(chuàng)建的文件,如類文件等
          dist 目標(biāo)輸出文件,如生成Jar文件等。
          doc/javadocs 文檔。
          lib 需要導(dǎo)出的Java包
          src 源文件

          對(duì)于一個(gè)簡(jiǎn)單的工程,一般包括表1的幾個(gè)目錄。其中bin、lib、doc和src目錄需要在CVS的控制之下。當(dāng)然在這樣的目錄結(jié)構(gòu)上,也可以做一些調(diào)整,例如,可以建立一個(gè)extra目錄來放置需要發(fā)布的Jar文件、Inf文件及圖像文件等。同樣,如果開發(fā)Web應(yīng)用可以建立一個(gè)Web目錄放置JSP、HTML等文件。

          如果我們開發(fā)的是一個(gè)比較復(fù)雜的項(xiàng)目,包括多個(gè)子項(xiàng)目,并且各個(gè)子項(xiàng)目是由不同的開發(fā)人員來完成的,那么要如何來設(shè)計(jì)它的目錄結(jié)構(gòu)?首先有一點(diǎn)是需要確定的,不同的子項(xiàng)目應(yīng)該擁有不同的Build文件,并且整個(gè)項(xiàng)目也應(yīng)該有一個(gè)總的Build文件??梢酝ㄟ^Ant任務(wù)或是AntCall任務(wù)調(diào)用子項(xiàng)目的Build文件,如下例:

          <target name="core" depends="init">
          <ant dir="components" target="core"/>
          <ant dir="waf/src" target="core"/>
          <ant dir="apps" target="core"/>
          </target>


          在各個(gè)子項(xiàng)目的耦合不是非常緊密的情況下,各個(gè)子項(xiàng)目應(yīng)該有各自獨(dú)立的目錄結(jié)構(gòu),也就是說它們可以有自己的src、doc、build、dist等目錄及自己的build.xml文件,但是可以共享lib和bin目錄。而對(duì)于那些耦合緊密的子項(xiàng)目,則推薦使用同一個(gè)src目錄,但是不同的子項(xiàng)目有不同的子目錄,各個(gè)子項(xiàng)目的build.xml文件可以放在根目錄下,也可以移到各個(gè)子項(xiàng)目的目錄下。

          編寫B(tài)uild文件

          要用好Ant工具,關(guān)鍵是要編寫一個(gè)build.xml文件。要編寫出一個(gè)結(jié)構(gòu)良好、靈活可擴(kuò)展的Build文件,有兩個(gè)問題要考慮,一是了解Build文件的基本結(jié)構(gòu),二是了解Ant定義的大量任務(wù)。

          Ant的Build文件是一個(gè)標(biāo)準(zhǔn)的XML文件,它包含一個(gè)根節(jié)點(diǎn)Project,每個(gè)Project定義了至少一個(gè)或多個(gè)Target,每個(gè)Target又是一系列Task的集合。它們之間的關(guān)系如圖2所示。


          圖2 build.xml文件的結(jié)構(gòu)


          每個(gè)Task是一段可被執(zhí)行的代碼,比如,前例中的javac、jar就是兩個(gè)最常用的Task。Ant定義了大量的核心Task,我們要考慮的第二個(gè)問題正是如何去掌握這大量的Task。其實(shí)唯一的方法就是邊學(xué)習(xí)邊實(shí)踐,這方面最好的參考就是官方的Ant使用手冊(cè)。

          外部文件的使用

          使用外部的Property文件可以保存一些預(yù)設(shè)置的公共屬性變量。這些屬性可以在多個(gè)不同的Build文件中使用。

          可以將一個(gè)外部的XML文件導(dǎo)入Build文件中,這樣多個(gè)項(xiàng)目的開發(fā)者可以通過引用來共享一些代碼,同樣,這也有助于Build文件的重用,示例代碼如下所示:

          <!DOCTYPE project [
          <!ENTITY share-variable SYSTEM "file:../share-variable.xml">
          <!ENTITY build-share SYSTEM "file:../build-share.xml">
          ]>
          <project name="main" default="complie" basedir=".">
          &share-variable;
          &build-share;
          ... ...


          在J2EE項(xiàng)目中的應(yīng)用

          只要掌握了Ant的使用方法,在J2EE項(xiàng)目中的應(yīng)用與在其它項(xiàng)目中的應(yīng)用并沒有太大的不同,但是仍有幾點(diǎn)是需要注意的。

          一是要清楚War和Jar文件的目錄結(jié)構(gòu),主要是War的配置文件web.xml文件的位置和EJB的配置文件(ejb-jar.xml和weblogic-ejb-jar.xml等)的位置,在調(diào)用Jar任務(wù)打包文件時(shí)一定要記得把它們也包含進(jìn)來。一般在編譯之前就要注意把這些需打包的文件拷入相應(yīng)目錄下。二是在J2EE項(xiàng)目中可能會(huì)涉及到一些特殊的任務(wù),比如在Weblogic中會(huì)調(diào)用ejbc預(yù)編譯EJB的代碼存根,或者需要在Ant中同時(shí)發(fā)布Jar到相應(yīng)的服務(wù)器中等??梢杂脙煞N途徑實(shí)現(xiàn)這些任務(wù),一是擴(kuò)展Ant任務(wù)實(shí)現(xiàn)這些任務(wù),二是直接用Java任務(wù)來執(zhí)行這些命令。下面是打包、發(fā)布一個(gè)EJB的build.xml配置文件片斷,代碼如下:

          <target name="deploy_HelloEJB" depends="compile">
          <delete dir="${temp}/ejb_make"/> <!-- 首先刪除臨時(shí)目錄 -->
          <delete file="${temp}/helloEJB.jar"/>
          <!-- 刪除WebLogic域中老版本的EJB -->
          <delete file="${weblogic.deploy.dest}/helloEJB.jar"/>
          <!-- 創(chuàng)建META-INF目錄,放置ejb-jar.xml和weblogic-ejb-jar.xml -->
          <mkdir dir="${temp}/ejb_make/META-INF"/>
          <!-- 拷貝ejb-jar.xml和weblogic-ejb-jar.xml 到臨時(shí)目錄-->
          <copy todir="${temp}/ejb_make/META-INF">
          <fileset dir="etc/baseinfo">
          <include name="*.xml"/>
          </fileset>
          </copy>
          <!-- 拷貝所有的helloEJB類到臨時(shí)目錄 -->
          <copy todir="${temp}/ejb_make/">
          <fileset dir="${dest.classes}/"> <!-- dest.classes是輸出的類文件目錄 -->
          <include name="${dest.classes}/helloEJB/**"/>
          </fileset>
          </copy>
          <!-- 將所有這些文件打包成helloEJB.jar -->
          <jar jarfile="${temp}/helloEJB.jar" basedir="${temp}/ejb_make"/>
          <!-- 進(jìn)行weblogic.ejbc編譯 -->
          <java classpath="${wl_cp}" classname="weblogic.ejbc" fork="yes" >
          <classpath>
          <fileset dir="lib">
          <include name="*.jar" />
          </fileset>
          </classpath>
          <arg value="${temp}/helloEJB.jar" />
          <arg value="${temp}/helloEJB_deploy.jar" />
          </java>
          <!-- 拷貝/發(fā)布到WebLogic的{DOMAIN}\applications目錄 -->
          <copy file="${temp}/helloEJB_deploy.jar" todir="${weblogic.deploy.dest}"/>
          </target>


          用Ant配合JUnit實(shí)現(xiàn)單元測(cè)試

          Ant 提供了JUnit任務(wù),可以執(zhí)行單元測(cè)試代碼。如何使用JUnit,以及如何編寫測(cè)試用例(TestCase),感興趣的讀者可以參閱JUnit的相關(guān)文檔。在Ant中使用JUnit的方法非常簡(jiǎn)單,首先需要把junit.jar拷入ANT_HOME\lib下,確認(rèn)在這個(gè)目錄下有optional.jar,因?yàn)镴Unit是Ant的擴(kuò)展任務(wù),需要引用這個(gè)擴(kuò)展包。然后就是在Build文件中加入JUnit的任務(wù),代碼如下:

          <target name="run" depends="client">
          <junit printsummary="yes" fork="yes" haltonfailure="yes">
          <classpath>
          <pathelement location="client.jar" />
          </classpath>
          <formatter type="plain" />
          <test name="com.sharetop.antdemo.HelloWorldTest" />
          </junit>
          </target>


          高級(jí)話題

          為Ant開發(fā)擴(kuò)展任務(wù)

          為Ant實(shí)現(xiàn)擴(kuò)展任務(wù)其實(shí)是非常容易的,只需按照以下幾個(gè)步驟即可:

          1. 創(chuàng)建一個(gè)Java類繼承org.apache.tools.ant.Task類;

          2. 對(duì)每個(gè)屬性實(shí)現(xiàn)set方法。Ant會(huì)根據(jù)需要自動(dòng)完成類型轉(zhuǎn)換;

          3. 如果擴(kuò)展的任務(wù)需要嵌套其它的Task,那么這個(gè)Java類必需實(shí)現(xiàn)接口org.apache.tools.ant.TaskContainer;

          4. 如果擴(kuò)展的任務(wù)要支持Text,需要增加一個(gè)方法void addText(String);

          5. 對(duì)每個(gè)嵌套的元素,實(shí)現(xiàn)create、add 或 addConfigured 方法;

          6. 實(shí)現(xiàn)public void execute方法;

          7. 在build.xml文件中使用 <taskdef> 來引用自定義的Task。

          下面以一個(gè)簡(jiǎn)單的例子來說明如何為Ant增加一個(gè)hello任務(wù),它可以連續(xù)打印多條信息,打印的次數(shù)由屬性count指定,而打印的內(nèi)容則由它內(nèi)嵌的一個(gè)helloinfo任務(wù)的message屬性指定,看上去這非常類似JSP中自定義標(biāo)簽的一些概念,實(shí)現(xiàn)代碼如下:

          //HelloInfoTask.java
          package com.sharetop.antdemo;
          import org.apache.tools.ant.*;
          public class HelloInfoTask {
          private String msg;
          public void execute() throws BuildException {
          System.out.println(msg);
          }
          public void setMessage(String msg) {
          this.msg = msg;
          }
          }


          下面是外部Task類的代碼:

          //HelloTask.java
          package com.sharetop.antdemo;
          import org.apache.tools.ant.*;
          public class HelloTask extends Task implements org.apache.tools.ant.TaskContainer
          {
          private Task info;
          private int count;
          public void execute() throws BuildException {
          for(int i=0;i<count;i++)
          info.execute();
          }
          public void setCount(int c){
          this.count=c;
          }
          public void addTask(Task t){
          this.info=t;
          }
          }


          實(shí)現(xiàn)了這兩個(gè)Task,在build.xml文件中定義它的task name,就可以在Target中執(zhí)行它了。如果你不想使用 <taskdef> 標(biāo)簽來定義Task,也可以通過修改default.properties文件來實(shí)現(xiàn)引入新Task,這個(gè)文件位于org.apache.tools.ant.taskdefs 包里。下例是一個(gè)使用 標(biāo)簽來引入新Task的Build文件部分:

          <target name="hello" depends="client">
          <taskdef name="hello"
          classname="com.sharetop.antdemo.HelloTask" classpath="client.jar"/>
          <taskdef name="helloinfo"
          classname="com.sharetop.antdemo.HelloInfoTask" classpath="client.jar"/>
          <hello count="3" >
          <helloinfo message="hello world" />
          </hello>
          </target>
          在自己的程序中調(diào)用Ant

          Ant的任務(wù)其實(shí)就是一段功能代碼。Ant內(nèi)置的大量任務(wù)對(duì)于我們開發(fā)Java應(yīng)用具有非常大的意義,為什么我們不能直接使用呢?

          因?yàn)楸M管在程序中調(diào)用Ant的任務(wù)并不復(fù)雜,而且我們知道Ant的任務(wù)其實(shí)都是一些Java類,調(diào)用的方法無非就是執(zhí)行這些類而已,不過在執(zhí)行之前需要對(duì)它做一些初始化的工作,所以我們需要引用一個(gè)Task類的子類來實(shí)現(xiàn)這個(gè)功能,比如如下代碼:

          package com.sharetop.antdemo;
          import org.apache.tools.ant.*;
          import org.apache.tools.ant.taskdefs.*;
          import java.io.File;
          public class RunAntTask {
          public RunAntTask() {
          }
          public static void main(String args[]){
          AntJAR j = new AntJAR();
          j.setBasedir(new File("./classes"));
          j.setJarfile(new File("aaa.jar"));
          j.execute();
          }
          }
          final class AntJAR extends Jar {
          public AntJAR() {
          project = new Project();
          project.init();
          taskType = "jar";
          taskName = "jar";
          }
          }


          注意AntJAR類的構(gòu)造方法,先創(chuàng)建了Project并初始化它,這是直接調(diào)用Task的必需條件。

          如果要在自己的程序中執(zhí)行Ant,需要了解的是Ant定義的幾個(gè)BuildEvent,它包括:

          ◆ Build started

          ◆ Build finished

          ◆ Target started

          ◆ Target finished

          ◆ Task started

          ◆ Task finished

          ◆ Message logged

          我們需要做的是實(shí)現(xiàn)BuildListener接口來處理各種事件,而執(zhí)行Ant的方法與上面給的例子非常類似,以實(shí)際開發(fā)的AntBuilder軟件的部分代碼為例:

          public void buildTarget(String targetName,String buildFileName) {
          try {
          Project p = new Project();
          p.init();
          File f = new File(buildFileName);
          p.setUserProperty("ant.file",f.getAbsolutePath());
          ProjectHelper.configureProject(p,f);
          p.addBuildListener(this);
          if( targetName==null )
          p.executeTarget(p.getDefaultTarget());
          else
          p.executeTarget(targetName);
          }
          catch (Exception ex) {
          jTextArea1.append(ex.getMessage());
          }
          }


          創(chuàng)建Project并初始化,設(shè)置它的配置文件(build.xml),執(zhí)行它缺省的或指定的Target,然后在實(shí)現(xiàn)了BuildListenser接口的監(jiān)聽器類中對(duì)你感興趣的事件作處理,代碼如下:

          public void buildStarted(BuildEvent event){ /* nothing*/ }
          public void buildFinished(BuildEvent event) { /* nothing*/ }
          public void targetStarted(BuildEvent event) {
          this.jTextArea1.append(event.getTarget().getName()+": \n\r");
          }
          public void targetFinished(BuildEvent event) {/* nothing*/ }
          public void taskStarted(BuildEvent event) {/* nothing*/ }
          public void taskFinished(BuildEvent event) { /* nothing*/ }
          public void messageLogged(BuildEvent event) {
          int prior = event.getPriority();
          switch(prior){
          case Project.MSG_ERR :
          this.jTextArea1.append("["+event.getTask().getTaskName()+"]Err:"
          +event.getMessage());
          break;
          case Project.MSG_INFO:
          this.jTextArea1.append("["+event.getTask().getTaskName()+"]"+event.getMessage
          ());
          break;
          case Project.MSG_WARN:
          this.jTextArea1.append("["+event.getTask().getTaskName()+"]"
          +event.getMessage());
          break;
          case Project.MSG_VERBOSE:
          this.jTextArea1.append(event.getMessage());
          break;
          }
          }


          Build.xml文件的寫法每個(gè)公司都有不同,這里沒有太大的參考價(jià)值,所以略去。(全文完)
          posted @ 2005-12-07 14:29 surffish 閱讀(1650) | 評(píng)論 (0)編輯 收藏
           

          //服務(wù)器代碼
          /********************************Main******************************/

          import java.io.*;
          import java.net.*;
          import java.util.*;
          public class ServerMain{
           public static Vector socketVector=new Vector();
           public static void main(String[] args) throws IOException{
                    System.out.println("服務(wù)器啟動(dòng)........");
            ServerSocket s = new ServerSocket(5000);
            while(true){
             Socket soc = s.accept();
             SocketThread st=new SocketThread(soc);
             socketVector.addElement(st);
             st.start();
            }
           }
           public static void sendEveryone(String msg){
                          Object object=null;
            int len=socketVector.size();
            for(int i=0;i<len;i++){
                                  try {
                                    object=socketVector.elementAt(i);
                                    SocketThread st = (SocketThread)object;
                                    st.sender.send(msg);
                                  }
                                  catch (Exception ex) {
                                    socketVector.removeElement(object);
                                  }
            }
           }
                  public static void removeObject(Object object){
                    socketVector.removeElement(object);
                  }
                  public static void removeObject(Sender sender) throws Exception{
                    int len=socketVector.size();
                          for(int i=0;i<len;i++){
                            Object object=socketVector.elementAt(i);
                            SocketThread st = (SocketThread)object;
                            if(st.sender==sender)
                              socketVector.removeElement(object);
                          }

                  }

          }

          /*********************************SocketThread **********************/
          import java.io.*;
          import java.net.*;
          import java.util.*;
          public class SocketThread implements Runnable{
           public Socket socke;
           public DataInputStream dis;
           public DataOutputStream dos;
           public Sender sender;
                  private boolean stop;
                  Calendar date;// = Calendar.getInstance(TimeZone.getTimeZone("Asia/ShangHai"));
           public SocketThread(Socket sok){
            socke=sok;
           }
           public void start(){
            Thread t=new Thread(this);
            t.start();
           }
                public void run() {
                  try {
                    socke.setKeepAlive(true);
                    dis = new DataInputStream(socke.getInputStream());
                    dos = new DataOutputStream(socke.getOutputStream());
                    sender = new Sender(dos);
                    while (true) {
                      StringBuffer sb = new StringBuffer();
                     char c;
                     while (((c = dis.readChar()) != '\n') && (c != -1)) {
                       sb.append(c);
                     }
                      if (c == -1) {
                        break;
                      }
                      date = Calendar.getInstance(TimeZone.getTimeZone("Asia/ShangHai"));
                      String ljnTime="("+date.get(date.YEAR)+"/"+(date.get(date.MONTH)+1)+"/"+date.get(date.DATE)+" "+date.get(date.HOUR_OF_DAY)+":"+date.get(date.MINUTE)+":"+date.get(date.SECOND)+")";
                      String acceptMsg=sb.toString();
                      System.out.println(ljnTime+acceptMsg);
                      ServerMain.sendEveryone(acceptMsg);
                    }
                    stop();
                   ServerMain.removeObject(this);
                  } catch (IOException ioe) {
                  } catch (Exception e) {
                    e.printStackTrace();
                  }
                }
            public void stop() {
             try {
              stop = true;
              if(sender!=null){
                sender.stop1();
              }
              if (dis != null) {
               dis.close();
              }
              if (dos != null) {
               dos.close();
              }
              if (socke != null) {
               socke.close();
              }
             } catch (IOException ioe) {
             }
            }
          }
          /*********************************************Sender**************************/
          import java.io.*;
          public class Sender extends Thread {
           private DataOutputStream dos;
           private String message;
           public Sender(DataOutputStream os) {
            this.dos = os;
            start();
           }
           public synchronized void send(String msg) {
            message = msg;
            notify();
           }

           public synchronized void run() {

            while (true) {
             if (message == null) {
              try {
               wait();
              } catch (InterruptedException e) {
              }
             }

             if (message == null) {
              break;
             }

             try {
             dos.writeChars(message);
             dos.writeChars("\r\n");
             } catch (IOException ioe) {
              try {
                ServerMain.removeObject(this);
              }
              catch (Exception ex) {
              }
             }
             message = null;
            }
           }

           public synchronized void stop1() {
            message = null;
            notify();
           }
          }
          //下面為手機(jī)客戶端代碼

          import javax.microedition.midlet.*;
          import javax.microedition.lcdui.*;

          public class ChatClientMIDlet extends MIDlet {
            private static ChatClientMIDlet instance;
            public static ChatForm displayable = new ChatForm();
            /** Constructor */
            public ChatClientMIDlet() {
              instance = this;
            }

            /** Main method */
            public void startApp() {
              Display.getDisplay(this).setCurrent(displayable);
            }

            /** Handle pausing the MIDlet */
            public void pauseApp() {
            }

            /** Handle destroying the MIDlet */
            public void destroyApp(boolean unconditional) {
            }
            public static void setCurrent(Displayable s){
               Display.getDisplay(instance).setCurrent(s);
            }
            /** Quit the MIDlet */
            public static void quitApp() {
              instance.destroyApp(true);
              instance.notifyDestroyed();
              instance = null;
            }

          }
          /********************************************************ChatForm ************************/
          import com.nec.io.*;
          import javax.microedition.lcdui.*;
          import javax.microedition.io.*;
          import java.io.*;
          public class ChatForm extends Form implements CommandListener,Runnable {
            public Form mainForm=new Form("聊天室");
            public Command enter=new Command("進(jìn)入",Command.OK,0);
            public Command send=new Command("發(fā)送",Command.OK,1);
            public Command exit=new Command("退出",Command.EXIT,0);
            public DataInputStream dis;
            public DataOutputStream dos;
            public SocketConnection sc;
            public Sender sender;
            public boolean stop;
            public TextField textField=new TextField("請(qǐng)輸入昵稱:", null, 10, TextField.ANY);
            public TextField info=new TextField("請(qǐng)輸入消息:", null,255, TextField.ANY);
            public ChoiceGroup choiceGroup=new ChoiceGroup(null,ChoiceGroup.EXCLUSIVE);
            public String MyName="游客";
            public boolean isCurrent=false;;
            public ChatForm() {
              super("我的聊天室");
              append(textField);
              addCommand(enter);
              mainForm.append(info);
              mainForm.append(choiceGroup);
              choiceGroup.append(");
              setCommandListener(this);
              mainForm.addCommand(send);
              mainForm.addCommand(exit);
              mainForm.setCommandListener(this);
            }
            public void commandAction(Command c, Displayable dis) {
              if(c==enter){
               if(textField.getString().length()==0){
                Alert alert=new  Alert("警告","昵稱不能為空!", null, AlertType.WARNING) ;
                alert.setTimeout(3000);
                ChatClientMIDlet.setCurrent(alert);
                return;
               }else
                 {
                   MyName = textField.getString();
                  append("正在進(jìn)入......");
                 }
                Thread t=new Thread(this);
                t.start();
              }else if(c==send){
                if(info.getString().length()==0){
                  Alert alert=new  Alert("警告","消息內(nèi)容不能為空!", null, AlertType.WARNING) ;
                  alert.setTimeout(3000);
                  ChatClientMIDlet.setCurrent(alert);
                  return;
                }
                sender.send(MyName+"說:"+info.getString());
                info.setString("");
              }
              else{
                stop();
                ChatClientMIDlet.quitApp();
              }
            }
            public void run() {
             try {
              sc = (SocketConnection) Connector.open("socket://127.0.0.1:5000");
              sc.setSocketOption(SocketConnection.LINGER, 5);
              dis = new DataInputStream(sc.openInputStream());
              dos = new DataOutputStream(sc.openOutputStream());
              sender = new Sender(dos);
              sender.send("歡迎"+MyName+"進(jìn)入房間");
              while (true) {
                if(stop) break;
                StringBuffer sb = new StringBuffer();
               char c;
               while (((c = dis.readChar()) != '\n') && (c != -1)) {
                  sb.append(c);
                }
               if (c == -1)   break;
               if(!isCurrent){
                 ChatClientMIDlet.setCurrent(mainForm);
                 isCurrent=true;
               }
               String msg=sb.toString();
               msg=msg.substring(0,msg.length()-2);
               choiceGroup.insert(0,msg,null);
               choiceGroup.setSelectedIndex(0,true);
              }
              stop();
             } catch (ConnectionNotFoundException cnfe) {
             } catch (IOException ioe) {
              if (!stop) {
               ioe.printStackTrace();
              }
             } catch (Exception e) {
              e.printStackTrace();
             }
            }
            public void stop() {
              try {
               stop = true;
               if (sender != null) {
                sender.stop1();
               }

               if (dis != null) {
                dis.close();
               }

               if (dos != null) {
                dos.close();
               }

               if (sc != null) {
                sc.close();
               }
              } catch (IOException ioe) {
              }
             }

          }
          /**************************Sender*********************************/

          同上

          主站蜘蛛池模板: 凤阳县| 长春市| 阜南县| 北安市| 大姚县| 永登县| 泸水县| 井陉县| 泽州县| 民勤县| 昂仁县| 汉川市| 富锦市| 延安市| 曲阜市| 天峨县| 九江市| 陇南市| 石城县| 孟村| 郸城县| 海晏县| 松原市| 衡东县| 和政县| 司法| 桐庐县| 丰顺县| 潼关县| 湟源县| 扶风县| 都江堰市| 石屏县| 罗江县| 宕昌县| 荔浦县| 湖口县| 阿尔山市| 阿荣旗| 宝鸡市| 遂平县|