1)管理虛擬化:有形的組織型管理和虛擬的IT流程管理相結合管理模式;
2)制造虛擬化:由生產線工人和由程序控制的機器人相結合的生產模式;
3)渠道虛擬化:由實體銷售店和虛擬的網上銷售相結合的渠道管理模式;
4)服務虛擬化:實體保養維修和遠程診斷,軟件更新相結合的服務模式;
5)組織虛擬化:垂直的組織機構和橫向的項目型組織機構相結合的企業組織模式。
2005年12月21日 #
@echo off
echo set sh=WScript.CreateObject("WScript.Shell") >telnet_tmp.vbs
echo WScript.Sleep 3000 >>telnet_tmp.vbs
rem ----------------UNIX IPAddress
echo sh.SendKeys "open 10.0.18.100{ENTER}" >>telnet_tmp.vbs
echo WScript.Sleep 3000 >>telnet_tmp.vbs
rem ----------------userID
echo sh.SendKeys "root{ENTER}" >>telnet_tmp.vbs
echo WScript.Sleep 3000 >>telnet_tmp.vbs
rem ----------------password
echo sh.SendKeys "root{ENTER}" >>telnet_tmp.vbs
echo WScript.Sleep 3000 >>telnet_tmp.vbs
echo sh.SendKeys "ls {ENTER}">>telnet_tmp.vbs
start telnet
cscript //nologo telnet_tmp.vbs
rem del telnet_tmp.vbs
很久沒有動手寫WebService了,這次,借項目間隙,對系統進行一個小改造,將一部分功能使用WS進行封裝,為下一步異構系統集成打下基礎。
但在WS化時,由于日久生疏,一個小小的WS化變動,卻花了整整好幾天時間!為此,狠下以來,將其過程進行記錄,以便下次參考。
WS整體流程:
以下分別介紹:
1、設計和實現WebService服務端功能組件,用于統一處理針對本應用系統所需進行WebService化的邏輯實現。并將系統邏輯處理中的對象轉成序列化后的String對象,以符合WebService交互標準。
2、根據SBPApi.java,生成WSDL等:通過Eclipse右鍵菜單中的WebService-->Create Web Service項。完成后,會在web目錄下建立wsdl目錄和SBPApi.wsdl,在WEB-INF目錄下建立(改寫)server-config.wsdd等文件,并完成對web.xml的修改。其操作流程示如下:
3、根據SBPApi.wsdl,生成WebService客戶端開發包和部署文件:
1)為不影響已有項目,可另建java Web項目;
2)將wsdl目錄復制至新項目對應的web目錄下;
3)通過eclipse已提供的webService插件(右鍵)功能,生成客戶端開發包所各文件。此時,所生成的文件與服務端對象文件結構一至。
4)調整關聯引用文件,將其調整至客戶端開發包,從而避免與服務器端的引用路徑重復而引發不便,并將服務器SDK中已有文件刪除。
5)建立客戶端的快速使用代理SBPClient.java,對WebService服務端交互工作的SBPApiSoapBindingStub.java進行客戶端封裝,并根據服務端中交互對象進行反向工程,其示例結構如下:
6)將clientApi下的所有文件打包后,加入測試項目進行測試。此時,因客戶端所使用的服務端對象未包含在WebService客戶端開發包中,因此需要將服務端對象也一同打包。
7)測試。
4、開發環境:Eclipse3.3.1.1 + JDK1.5.06 + Apache Axis version: 1.4
在一次基于多線程的編碼測試中,發現繼承Runnable接口的線程實現類在運行時并未按預計啟動多線程,經分析和比較后,找出問題所現,現將其記錄下來,以供分享。
Java中,多線程編程中的線程編寫,有兩種方式,即擴展Thread基類或繼承Runnable接口;例如:
public class T extends Thread {
public void run() {
……
}
}
public class R implements Runnable {
public void run() {
……
}
}
對于擴展Thread的實現類T,可以使用T.start()來啟動此線程;如
public static void main(String[] args) {
Thread t = new T();
t.start();
}
但對于繼承Runnable接口的實現類R,因接口中并沒有提供直接啟動線程的start()方法,只有一個線程主邏輯運行的run()方法。此時,如執行run(),會因為R.run()只是作為此線程實現類的一個方法,并未在主線程之外,啟動另一個線程,從而導致R.run()阻斷主線程繼續向下執行;并未達到多線程運行的目的。
錯誤啟動代碼如下:
public static void main(String[] args) {
R r = new R();
r.run();
}
那么,如何使用另外線程來啟動繼承Runnable接口的實現類呢?以下就是它的正確的使用方式:
public static void main(String[] args) {
R r = new R();
Thread t = new Thread(r);
t.start();
}
此時,需注意,在主線程執行時,需等待子線程執行,否則,當主線程結束后,子線程也將結束。
需求:
系統A與系統B分別部署在不同域的兩臺服務器中,但它們的身份都統一在身份認證服務器中;身份認證信息以Session方式存貯于各自系統中,并輔以cookie進行使用。
當用戶在A系統登錄后,訪問B系統時,由于是跨域訪問,導致身份信息不能正確的傳遞到B系統中,從而致使用戶需在B系統中重新登錄。
解決方案:
處理這類跨域訪問時,我們最先使用從B系統向C通過HttpRequest(類AJAX請求)的方式獲取身份信息,此方式好處是同步處理,方便用使用;但其限制諸多,如需設置信任站點、用戶訪問確認等,甚至,在對應用服務器作了一次安全升級后,根本無法訪問了。因此,需另行開辟途徑,于是,在同事建議下,我們使用IFrame內嵌跨域驗證網頁,來解決此問題。
1、原理設計:用戶在訪問B系統時,先使用一內置的iframe,并將iframe的src指向身份認證服務器系統代理驗證接口;如果用戶已經在A系統中進行過登錄,即A域了中已存在著身份認證信息后,身份認證服務器中也將具有其身份信息將其附帶著身份認證信息后重定向訪問B系統代理接口;B系統代理驗證接口在接收到由A系統傳遞而來的身份認證信息后,通過身份認證服務器驗證后,在B系統所在域重建身份認證信息。
2、實現邏輯貼碼:
1)B系統代理驗證接口:
(1)IFrame邏輯貼碼:
(2)JS檢測是否通過認證邏輯貼碼:
2)身份認證服務器端接口(JSP):
3、注意事項:
1)由于身份認證中心使用cookie作為身份標識,因此,需要用戶在瀏覽器中允許使用cookie的設置;
2)由于在iframe中進行跨域重定向,因此需在IE安全中的跨域瀏覽子框架項設為啟用:
4、源碼文件:
……
在windows下進行j2ee項目開發和部署時,常需要對系統存在問題進行更深入的分析。由此,實時的javacore就是分析的最佳方式之一。但如何以最方便直接的方式產生javacore文件,就是這項工作必需做的準備工作了。
1、通過dos窗口,進入至jdk安裝目錄下的bin目錄中;
2、運行jconsole.exe,并設置信息輸出的目標文件,以便于分析,否則將直接輸出至屏幕上;
3、連接正在運行的目標jvm;
4、連接后的jconsole如下:
5、通過通過Ctrl+Break組合鍵,產生javacore至指定文件中。
6、下一步就是對所產生的javacore文件進行具體的分析和使用了。
某日,公司進行年度一次的體檢!
在連續查出10個脂肪肝后,醫生對第11個進來檢查的人說:“等會,我們的B超機好像出問題了,等檢修后再進行”
這是一個真實的事件,我們這些IT行業的從業人員,多坐少動,壓力大,時間長,導致體質差的邊醫生都懷疑機器了!
唉!
一、項目建立及應用實現
1、建立J2ME項目
2、在完成開發后,進入Application Descriptor編輯界面
3、因默認情況下,Application Descriptor文件中未定義MIDlet啟動對象,因此需使用EditPlus或記事本等文本編輯器,編輯Application Descriptor文件(位于項目根目錄下),并添加以下項目,如:
4、運行Application Descriptor編輯界面中的Lanuch as enumlated Java ME JAD,進行測試
5、在步驟4之后,會在項目根目錄下的.mtj.tmp中生成LaunchFromJAD子目錄,其中的worm.jad和worm.jar即是手機程序的安裝文件
6、將worm.jad和worm.jar復制至手機中,運行worm.jad進行安裝后,即可使用
二、問題分析:
1、如報【文件不完整】錯誤,則檢查worm.jad中的項目是否完整。在Eclipse中使用Lanuch as enumlated Java ME JAD測試通過,并自動生成的此文件,一般都是完整的,不需作任何修改。
2、如報【版本錯誤】,則檢查您在Eclipse中使用的的模擬器版本是否是您手機所支持的,出現此錯誤后,將模擬器版本調低試試。其位置如下
三、開發環境:
1、java JDK1.6.0_10;
2、EclipseV3.3.1.1;
3、sun公司J2ME-WTK開發包:sun_java_wireless_toolkit-2_5_2-ml-windows.exe
4、Eclipse移動應用開發包:eclipseme.feature_1.7.9_site.zip
在XXX產品框架中,我們根據產品發展規劃和業務領域需要,使用基于JMS技術,通過應用WEBService,開發了消息中心中間件(簡稱MC)。通過消息中間件,我們可以實現各系統間的異步數據交換和事務處理、執行不需前臺使用人員干預的如后臺業務和數據同步工作,也可用來處理一些受到安全和其它一些因素制約,導致無法直接通過數據庫或應用系統進行處理的受限業務。
消息中心中間件,包括消息總線和消息客戶端兩部分:消息客戶端負責業務類消息實例的產生、發送消息實例到消息總線、接收從消息總線轉發而來的消息實例、將收到的消息實例交由其載體應用系統進行與之對應的業務處理等活動;消息總線負責接收從消息客戶端產生并發送而來的消息實例、消息重建、根據消息配置進行消息實例重建,將重建后的消息實例轉發至對應的消息客戶端等活動。
消息客戶端與XXX各應用系統集成在一起,并通過應用系統開放WEBService端口進行消息的發送和接收等,從而避免單獨部署和發布所帶來的困難和額外資源消耗。消息總線可單獨部署,也可和消息客戶端一樣,與XXX應用系統集成部署,在XXX產品框架下,有且只需要一套消息總線即可滿足需要。消息配置中心,其作用包括配置和管理消息中心各組成部分的部署方式和訪問信息,以此將消息中心各部有機的聯系起來;同時,各消息業務應用,也使用配置文件進行配置化管理,并與消息中心各組成部分進行關聯配置,從而形成一個統一且開放的整體;其它的如性能優化處理、日志記錄等也在配置中心進行配置和管理。
在消息中間件V1.0版本開發完成后,我們即將其投入實用。在XXX各分子系統這近一年時間的運行和使用過程中,消息中心很好的完成了預定任務,其可靠性、可擴展性和適用性得到很好的驗證。以此為據,通過使用消息中心,開發出基于消息中心的客戶化應用和業務活動也在持續的增加中,到現在為止,已經有包括網絡檢測、信息同步、配置更新、電子目錄樹更新、權限同步等諸多應用是基于消息中心應用開發,并很好的使用在XXX各分子系統的測試和內網正式環境中。
在XXX系統正式接入外網后,通過對業務進行跟蹤,發現外網用戶(系統)所產生的消息實例無法正常的到達指定的消息總線及消息客戶端。最主要的體現是權限同步消息應用無法正常完成的問題,導致外網用戶權限未得到及時更新。對此過程中消息中心所涉及部分進行分析發現:所有的權限同步消息實例在產生后,不能正常的將此消息實例發送至消息總線,分析失敗原因,只有一種,那就是”connect time out”。從此信息可看出,應該是外網系統所發出的消息無法通過WEBService送達指定的消息總線接收端所至。但從內網發出的同一類消息,其發送和接收卻又都是正常的。
1、先分析我們系統的整體部署方式,如下圖所示:
根據外網用戶可正常登錄和訪問系統,并可通過系統準確及時的發出執行指令操作,完成其所需的業務活動來看,網絡方面和系統和硬件方面都不存在問題。
2、在外網環境下,直接進行各消息客戶端和消息總線的服務的檢測,所發請求都能夠正確的到達指定目標,WEBService的響應也正常且正確,也就是說,各應用系統加載的消息服務運行也正常。
3、根據本次檢測需要,另行開發消息中心專用檢測工具,為本次和今后的行的消息中心檢測和問題分析,作好更充分的準備。
4、通過檢測工具,發現,外網環境下,消息客戶端和消息總線之間不能夠聯通,從而找到問題所出:即不知是何原因,導致外網消息與外網的消息總線間聯絡不通!
5、對外網用戶消息產生和發送的過程和邏輯實現進行分析:我們發現,為了滿足應用系統外網訪問的需要,我們對消息系統配置信息中服務地址的ServerName進行了偽處理,即在運行時,根據用戶瀏覽器的請求頭來判斷用戶使用的是哪一個WEB服務器地址,并將此地址動態的代替消息配置中的各ServerName信息,從而保證各使用用戶只能夠訪問其指定的WEB服務器,從而避免因WEB服務器的不匹配而影響其訪問速度、處理效率等故障的發生。此方式已在我部門多套同時服務于內外網絡的系統中得到可靠的驗證。
那么,會不會因為ServerName在動態解釋過程中,因多并發情況下,因后訪問者將前訪問者的ServerName改寫而導致錯誤的解釋,即將不同網絡用戶的消息地址進行張冠李戴而導致消息無法正常發送呢?
分析消息中心各部分WEBService生成和使用機制:因系統的并發性要求較高,在高峰期其在線用戶可達3000人,并發用戶在300以上,且系統穩定性要求極高。為提高系統的性能和穩定性,在系統啟動時即將消息中心各部的WEBService連接進行創建和緩存,以提升消息中心資源利用率,并提升其訪問性能。
當存在多網絡用戶訪問時,可能因消息中心存貯的WEBService連接并不是其用戶所使用的那個網絡的WEBService服務地址,此時,消息肯定是無法送達至此用戶所需要的目標的。因此,報”connect time out”錯誤就成必然的了。
既然已找到問題的可能原因,我們立即進行著手分析和解決:根據部署要求,我們對對消息服務連接服務進行了升級,即將服務請求進行分類處理和實現,并在消息配置中對所使用的部署方式、代理實現后,交由測試人員進行部署和測試。
測試結果:令人失望的是,此問題依然存在!在通過外網WEB服務器訪問的系統,其消息還是無法發送至消息總線。由此得知,此種分析方向是錯誤的!
至此,好像已經走入了死區,能想到的方式都已經想到了,但問題到底出在哪呢?
在一次與同事聊天的過程中,忽然想到一個問題,那就是:我們的消息的產生和應用都是由應用系統和與之集成在一起的消息客戶端自動產生和處理的,此過程中完全不受人工干預和影響。而應用系統是部署在應用服務器中,WEB服務器僅是用來處理用戶的HTTP請求à將此請求轉發至對應的應用服務器后à將應用服務器的響應返回給用戶。
在此過程中WEB服務器并未對用戶業的http請求進行過任何業務上的處理!那么,問題會不會出在WEB服務器端呢?檢查一下消息中心的配置不管是使用ServerName還是寫死IP和域名,我們的消息中心配置的地址都是指向WEB服務器。而在應用系統發現消息時,其所在位置是應用服務器。而應用服務器是無法直接訪問部署于外網IP中的WEB服務器的,當然,消息無法發送至目標就成為必然了。
既然已經找到問題,那就動手,將消息中心的配置信息指向應用服務器后,重啟應用系統后測試,問題果然解決!
通過應用服務器進行后臺自動處理的,進行HTTP或WEBService活動,其目標必需是它能夠訪問的有效地址!這個問題在以前也曾經碰到過,只是由于時間隔得太久,且這些場景應用出現太少,而導致再次發生。
1、 基于應用系統或后臺自動觸發的一些業務邏輯,如其中存在著系統間相互訪問或遠程調用等,必需以應用系統自身為根,進行連接測試;通過外層包裝或其它代理,進行訪問時,必需先剝離過外層包裝或其它代理后,再進行連接測試,并以測試結果,作為決策的依據!此舉適用于各類系統的架構設計和邏輯實現過程中。
2、 基于中間件產品應用,及時開發與之配套的檢測和使用工具,是一件必不可少的工作,此舉將為后期的實施和問題分析節省大量的工作量。
從小到大,椰子已經吃過很多次了,但在這些吃椰子有經歷中,我只知道一種吃法:開孔à插吸管à喝椰汁à丟椰殼à完事!
但在今天,事情有了些變化,于是產生的椰子的第二種吃法。
我和夫人在散步時,順便準備到超市買點水果,看到水果區的椰子又大又好且正在打特價。心中一動,就挑了個大的,買回家準備細細品嘗一番。在按通常吃法吸光椰子中的水汁后,突然想起,我們平時很喜歡吃超市中的一種叫椰角小吃的,又甜又韌很有嚼勁,但椰角是長大哪的呢?不會是椰子樹上的另一種產品吧!看著椰子開口的硬殼下面的白色軟組織,我們就突發奇想,這白色軟組織會不會就是那椰角呢?
說動就動,先用刀將空椰子殼砍開,發現其內層確實是一層約0.8cm厚的白色果肉。小心的切下一小塊嘗一嘗,味道淡淡的,很有韌勁,確實就是那椰角的源料。這就是我發現的椰子的第二種吃法了。
在生活中有很多事:你沒經歷,就不會想到;當你想不到時,美好的事情就可能錯過!
這就是生活。
2009/5/5夜
在我們公司的軟件研發體系中,存在著三種截然不同的軟件開發方式。而我,作為公司最老同事之一,也是這三種開發模式的親歷者,曾不只一次的被公司同事問過我關于這三類方式之間的異同點。于是利用空閑時間,對其進行一番整理、分析和對比。
1、全能型
部門經理在接到項目之后,將此項目交給部門內的熟練程序員后,此程序員就自動被委任其為項目經理。從此開始,程序員將根據項目售前方案和銷售合同內容,在項目進行過程中分別擔當起項目經理、功能設計師、數據存貯設計師、程序員、測試員和項目實施人員等諸多角色。并在項目進行的過程中,帶領少量其它程序員和輔助資源來完成此項目的所有工作。
此類項目其功能單一且不復雜,只是為了幫助用戶提升某一項工作的工作效率或解決客戶在其工作中的一些問題,如工作日志信息的采集和分析業務項目、辦公用品的申請和領用等。它們因為其涉及范圍小,使用人員不多,從而具有項目總費用少、開發和實施周期短、對性能要求不高的特點。
在此類開發模式中,程序員由于其工作的全面性,使他們在進入項目組后,能夠得到很快且全面的提升,并會在與客戶交往的過程中,建立起良好的客戶關系處理經驗,為其今后的成長和發展打開良好的基礎。
由于項目需要,程序員需要掌握全面技能,容易造成其在項目開發過程中需要全面的接觸項目管理及人際關系、需求分析、數據庫及對象設計、人機交互和用戶體驗設計、系統設計和開發、測試和系統提升、應用實施和售后維護等諸多截然不同的領域范圍;所以,作為此類程序員,其工作壓力之大,事務之復雜、綜合素質要求之高,是其它模式的程序員所無法對比的,這也是造成此類項目按時完成率極低、尾款回收困難、項目售后工作難做、用戶滿意度差、二次項目獲取困難的根本原因。
同時,由于程序員被大量的非開發性事務所干擾,造成他們無法專心致力于專業技能的學習和提升,也就無法造就一支高效率、高穩定性、配合默契的開發隊伍,這也是造成公司內此類人才大量流失的重要原因。
2、英雄型
部門經理在接到此類項目后,按項目所涉及的領域范疇,將其按領域進行分工。以企業信息協同系統為例,我們將進行如下分工:門戶信息的獲取、聚合、交互和展現工作交給專職于門戶開發的程序員;內部郵件系統的分析、設計、和實現將給郵件開發程序員;日程和事務的設計交給日程開發程序員;工作流應用工作交由工作流客戶化開發程序員等等。
在此類型的開發模式中,程序員將會是某一領域內的英雄式人物!由于他長期且相對穩定的負責著這個有限領域范圍內的一切事務,可以幫助他在一定時期內進行系統而穩定的業務研究和分析工作,進而成長為此領域內的業務專家。而且,通過持續的對其工作進行迭代式開發、升級和完善,可使此產品在產品品質、適用性和用戶體驗等方面得到穩定的提升,進而提升了整個產品的品質。
如果此領域內的工作產品能夠得到合理的規劃和實現,進而將其進行單獨的封裝、應用集成和推廣,就有可能形成一個具有相當競爭力的產品,從而為公司獲取新的銷售機會和利潤點。
但是,此類開發模式中的分工也容易造成程序員涉及業務領域單一和適應性窄的缺陷:由于其長期面對和研究著單一業務領域內的業務活動,而無法更多的接收和參考來自于用戶、企業和其它行業內的非它業務發展需要和趨勢,從而對其在產品領域內的發展產生限制,并造成其產品方向上的不準確或錯誤定位;由于其長期的在單一領域內工作,并在此領域內獲得了公司內的認可,這也將限制他在領域間的流動性。當公司或部門的產品方向和需要調整和改變時,此類程序員就需要被迫改變甚至放棄其在原領域內的所有積累而重新開始,從而造成巨大的浪費。
3、專業型
項目經理在接到項目之后,根據項目組成員的能力、特長職業規劃,對他們進行適當且專業化分工:由業務規劃人員負責項目的需求收集、業務規劃和需求分析;由系統架構師對系統的進行技術構架和支撐性技術的規劃和引進;由數據庫專員負責數據庫對象的設計和性能調優;由功能分析員在人機交互人員輔助下負責功能設計和人機交互模式;由業務邏輯實現專員根據功能設計進行高性能的業務邏輯處理實現和外部接口的設計和實現;由頁面開發人員負責實現人機交互;測試人員負責對系統進行全過程的測試和質量監督;專業化實施人員可快速高效的進行系統實施和在線維護,售后服務工作也將由專人負責;
通過恰當和合理的分工,將軟件研發過程中的各個環節進行拆分,從而將復雜的軟件工程分解成一個個相對獨立且又緊密關聯的工作項,從而有效的降低了軟件開發過程中的困難度和風險性;項目經理把分解后的工作項交給項目組中的合適項目成員,并根據項目組成員的能力、工作難度和工作量,制定出科學的項目計劃;同時,項目組成員在項目經理的協調和管理下進行密切的分工合作,此舉即能調動項目組成員的其工作積極性,又能使他們將工作、興趣和個人職業成長規劃進行有效的結合,從而使其在技能、收入和社會認可度等諸多方面得到快速成長,達到人盡其材,材盡其用的目的。通過使用專業的人做專業的事,公司將在人員分工、資源使用和業務拓展等領域走向專業化、規模化,最終成為專業且強大的產業實體。
但此開發模式也具有相當的局限性!其一,如何合理的利用項目組資源?項目組成員因其性格、能力和興趣各有不同,如何能將他們按項目分工和角色組成需要,進行專業化訓練和培養;其二,因項目組成員長期單一職能的工作,與其它環節的交叉和交流都受到限制,對其未來的全面發展和綜合成長都很不利;其三、各角色之間的分工、合作與工業化生產中的生產線相似,那么,建立與之相適應的質量保證體系,保證各工序之間生產產品的質量,從而從事實上提升軟件產品的整體質量?
通過對這三類開發模式的分析,我們可以看出,它們各有合理性,也又具有的相當的局限性。
全能型開發模式是早期的CS類項目開發的主要模式,其適用于哪些規模小,程序員少的小規模IT開發企業進行小型項目的開發中。但對于那些工期較長、業務范疇廣、復雜度較大的項目,此種開發模板將采用將導致風險最大化,失敗幾乎是其唯一的結局。
英雄型開發模式,因項目組成員領域化的分工和合作,使它在通用型復合類產品開發中具有優勢。通過對產品的各組成部份進行持續的改進和迭代性開發,使產品在功能、性能、用戶體驗等方面得到持續的改善和提升,從而有利于產品拓展并在此過程中做大做強,最終取得競爭優勢。但此開發模式也將導致項目組成員之間的工作協調、技術互用等方面存在諸多不便;另外,因領域的專業性和不可替換性,也就限制了公司在處理關健人員的流動性方面存在諸多困難,并在核心競爭力的保證方面存在著很大風險。
專業型開發模式,通過對人員進行專業化分工,從而在軟件開發過程中最大的利用了人力資源,提升軟件的生產效率,并降低了軟件的從業門檻。此方式在新形式下的項目開發和產品研發中都具有相當的競爭力,也易有利于保證公司的核心競爭力。但采用此種開發模式時,需要完善內部的人員激勵機制,保證各角色的從業人員都有與之適應的職位規劃和發展模式,并能根據項目組成員所處階段的需要,提供相應的技能培訓和交流機會,從而促進其成長,激勵其上進。
總之,采取何種開發模式,要根據公司的實際業務情況,發展規劃和人員構成,進行科學的分析之后,再采取行動、從而得到具有延續性和競爭性,并與自身相匹配的軟件開發模式。
2009/4/20夜
今天,在陪夫人逛街回來的路上,看到一幕慘劇的發生:一位中年男子,從家中跳樓而下,墜落于堅硬的水泥地面上,當場身亡!
人生為何?為已?為親?還是為他?
人生為已,就應該珍惜自己的生命,為自己這短暫的一生中,充實、幸福和快樂的活著,而不能因為暫時的挫折、失敗而絕望和放棄;人生漫漫而無現存路,需要自己去探索和開拓,在此過程中,必然會經歷曲折和無法避免的挫折。但是,不經歷風雨,如何能見彩虹!挫折過后,往往就伴隨著一段平坦的直道;人生艱難,生活、事業、家庭、社會各種矛盾在我這會聚,理不清也扯不斷!既然如此,何不干脆看開,將不可調和的矛盾進行暫時地休眠,讓時間這個解決矛盾的最好的潤滑劑來慢慢解決它。
人生為親,為父母:他們含辛茹苦的將你從無到有、從幼養成,而你卻要在他們需要照顧和看護的年齡離他們而去!你忍心嗎!為妻:相汝以沫幾十年、同床共枕伴一生!鍋碗瓢盆一屋住,酸甜苦辣是生活。你就忍心在她人生路中間,正需你堅強的肩膀作支撐時,卻拋下她一人孤苦的走在這漫長的人生路上,你安心嗎?人生為子:父親是兒女的榜樣和偶像,他們需要借助你那成熟的智慧來打開事業的大門,也需要你那豐富的閱歷來開拓自己的人生路,更需要你成功的經驗來保護雛鳥并解決初飛時所遇到的種種風險!在這種關鍵的時候,你卻拋棄了他,你放心嗎?
人生為他,為朋友兄弟:有多少美好時光值得回憶,有多少美妙經歷值得回味,又有多少坎坷擔當值得珍惜!你就此離開,從此兄弟聚首少一人,朋友舉杯缺一環!為事業:你正值人生當年,恰逢事業當期,失敗你經歷,成功應有你,酸甜苦辣都嘗遍,還有什么過不去?為社會:當今社會多少不平事,何必事事放我心!不必為人先,也不全落后;比上我不足,哪我就比下,實在比不過,阿Q一把也不錯!
生命如此脆弱,稍有不慎就將墜落:走在路上被車撞死,走下樓下被東西砸死,乘車墜橋而死,去醫院被錯藥藥死,上班被累死,下班被煩死,既然如此,何必再來一個自己尋死呢!
請珍惜生命,愛護自己!
20090330于家中
前段時間,項目組安排同事進行項目移植,并考慮在其過程中進行技術預研等相關工作,以對項目進行優化;
在此過程中,有同事誤解面向對象化開發的精髓,在匆匆了了解JavaScript面向對象的方法和示例后,對項目中的公共門戶頭以對象的方式進行重寫。結果,將原30行的單一文件代碼變成了400多行,并分布于多個文件了。
在拿到此結果之后,我是哭笑不得,于是得出了:“新技術的引入必需能夠提高生產效率或降低工作難度,否則,沒有引入的必要”這句話。
總是聽說Vista在軟件兼容性上有諸多問題,且一直未得到很好的解決,由于一直使用XP,對此也就不太在意。但是,因工作因素,需要升級我的飯碗(購買新筆記本,操作系統為vista)后,麻煩果然來了:
先是Oracle數據庫安裝不了。還好,我在開發時可以使用公司的數據庫進行開發,不在本機安裝數據庫還可節約一筆硬盤空間和內存。故其影響并不大,只是在下班離開公司后,沒時使用數據庫而已。
安裝Eclipse,繼續java項目開發,未發現兼容性問題;
成功安裝Tomcat(版本號為5.5.17),但在啟動時,發現其只能用管理員身份進行啟動,而無法向往常一樣,通過開始菜單直接啟動。進入Eclipse,啟動項目(WebApplication),發現麻煩來了,不管我用何種方式,TomcatServer一直報服務超時,不能正常啟動!
唉,難道要我重新恢復XP嗎,這可不是一張恢復盤的問題,而是我花了兩天時間,進行操作系統和相關相關軟件安裝,我的媽也!!
到網上查找相關資料,也未獲取明確的解決之道;到MS支持網站,沒找到合適的方案;問周邊同事,得到N種可能的解決方式;經過一天時間,逐個試驗,終獲解決之道。
可在環境操作系統變量中添加classpath項,其值如:C:/Program Files/Java/jdk1.5.0_11/lib;C:/Program Files/Java/jdk1.5.0_11/lib/tools.jar
昨日,在將應用程序(JSF應用,其中包含Tiles包)發布至測試服務器(Solaris8+Tomcate5.5)時,發現其不能正常運行,其錯誤如下:
......
2006-11-1 17:09:54 org.apache.tiles.servlets.TilesServlet init
信息: Initializing TilesServlet
2006-11-1 17:09:54 org.apache.tiles.servlets.TilesServlet readFactoryConfig
信息: CONFIG FILES DEFINED IN WEB.XML
信息: initializing definitions factory...ets.TilesServlet initDefinitionsFactory
2006-11-1 17:09:54 org.apache.tiles.servlets.TilesServlet saveExceptionMessage
警告: Caught exception when initializing definitions factory
2006-11-1 17:09:54 org.apache.tiles.servlets.TilesServlet saveExceptionMessage
警告: I/O Error reading definitions.
2006-11-1 17:09:54 org.apache.tiles.servlets.TilesServlet saveExceptionMessage
s.
2006-11-1 17:09:54 org.apache.tiles.servlets.TilesServlet saveExceptionMessage
警告: Caught exception when initializing definitions factory
2006-11-1 17:09:54 org.apache.tiles.servlets.TilesServlet saveExceptionMessage
警告: I/O Error reading definitions.
2006-11-1 17:09:54 org.apache.tiles.servlets.TilesServlet saveExceptionMessage
警告: javax.servlet.ServletException: I/O Error reading definitions.
2006-11-1 17:09:55 org.apache.coyote.http11.Http11BaseProtocol start
信息: Starting Coyote HTTP/1.1 on http-8800
......
根據此錯誤分析,是由于TilesServlet未正確讀取tiles.xml配置文件,但在對tiles.xml進行權限變更后,也未解決此問題!!!
但是,此應用在開發環境下是正常的,如何是好??
我和同事在對比開發環境和測試環境之后,發現二者的運行環境差別只有操作系統(UNIX<>WINDOWS XP);
搜索Google和BeiDu,找到一篇相類似的報到,據其所說,當他的系統在斷開網絡后會出現類似的情況,難道是TilesServlet必需聯上互聯網?
在分析tiles.xml后,發現,其中有如下一句:
???<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "原來,當互聯網斷開之后,不能從tiles-config_2_0.dtd中獲取驗證,導致此文件解釋失敗,將此刪除之后,系統就可正常部屬在測試環境之中了.
懷疑論者的 JSF: JSF 組件開發省時運動使得構建 JSF 組件輕而易舉 ![]() |
![]() |
![]() |
級別: 中級 Rick Hightower , CTO, ArcMind 2005 年 8 月 16 日 在四部分的 懷疑論者的 JSF 系列的最后一期中,Rick Hightower 介紹了省時運動,它可以一次或永遠地說服您:JSF 組件開發要比您想像的更容易。 組件模型的關鍵考驗就是:能否從第三方供應商購買組件,并把它們插入應用程序?與可購買可視 Swing 組件一樣,也可以購買 Java ServerFaces (JSF) 組件!需要一個好玩的日歷?可以在開源實現和商業組件之間選擇。可以選擇購買一個,而不是自行開發復雜的基于 Web 的 GUI 組件。 JSF 擁有一個與 AWT 的 GUI 組件模型類似的組件模型。可以用 JSF 創建可重用組件。但不幸的是,存在一個誤解:用 JSF 創建組件很困難。不要相信這些從未試過它的人們的 FUD!開發 JSF 組件并不困難。由于不用一遍又一遍重復相同的代碼,可以節約時間。一旦創建了組件,就可以容易地把組件拖到任何 JSP、甚至任何 JSF 表單中,如果正在處理的站點有 250 個頁面,這就很重要了。JSF 的大多數功能來自基類。因為所有的繁重工作都由 API 和基類完成,所以 JSF 把組件創建變得很容易。 貫穿這個系列,我一直在試圖幫助您克服造成許多 Java 開發人員逃避使用 JSF 技術的 FUD。我討論了對這項技術的基本誤解,介紹了它的底層框架和它最有價值的開發特性。有了這些基礎工作之后,我認為您已經可以采取行動,開發自己的定制 JSF 組件了。使用 JSF 的東西,我敢保證要比您想像的要更加容易,而且從節約的時間和精力上來說,回報如此之多,多得不能忽略。 這篇文章中的示例是用 JDK 1.5 和 Tomcat 開發的。請單擊頁面頂部的 示例代碼 下載示例源代碼。注意,與以前的文章不同,這篇文章沒有關聯的 build 文件,因為我特意把它留給您作為一個練習了。只要設置 IDE 或編譯器,把 /src 中的類編譯到 /webapp/WEB-INF/classes,并在 /webapp/WEB-INF/lib 中包含所有 JAR 文件(以及 servlet-api.jar 和 jsp-api.jar,它們包含在 Tomcat 中)。 JSF 組件模型與 AWT GUI 組件模型類似。它有事件和屬性,就像 Swing 組件模型一樣。它也有包含組件的容器,容器也是組件,也可以由其他容器包含。從理論上說,JSF 組件模型分離自 HTML 和 JSP。JSF 自帶的標準組件集里面有 JSP 綁定,可以生成 HTML 渲染。 JSF 組件的示例包括日歷輸入組件和 HTML 富文本輸入組件。您可能從來沒時間去編寫這樣的組件,但是如果它們已經存在,那會如何呢?通過把常用功能變成商品,組件模型降低了向 Web 應用程序添加更多功能的門檻。 組件的功能通常圍繞著兩個動作:解碼和編碼數據。解碼 是把進入的請求參數轉換成組件的值的過程。編碼 是把組件的當前值轉換成對應的標記(也就是 HTML)的過程。 JSF 框架提供了兩個選項用于編碼和解碼數據。使用直接實現 方式,組件自己實現解碼和編碼。使用委托實現 方式,組件委托渲染器進行編碼和解碼。如果選擇委托實現,可以把組件與不同的渲染器關聯,會在頁面上以不同的方式渲染組件;例如多選列表框和一列復選框。 因此,JSF 組件由兩部分構成:組件和渲染器。JSF 組件 類定義 UI 組件的狀態和行為;渲染器 定義如何從請求讀取組件、如何顯示組件 —— 通常通過 HTML 渲染。渲染器把組件的值轉換成適當的標記。事件排隊和性能驗證發生在組件內部。 在圖 1 中可以看到數據編碼和解碼出現在 JSF 生命周期中的什么階段(到現在,我希望您已經熟悉 JSF 生命周期了)。 圖 1. JSF 生命周期和 JSF 組件 ![]()
所有 JSF 組件的基類是 組件擁有雙親和標識符。每個組件都關聯著一個組件類型,組件類型用于在 face 的上下文配置文件(faces-config.xml)中登記組件。可以用 JSF-EL (表達式語言)把 JSF 組件綁定到受管理的 bean 屬性。可以把表達式關聯到組件上的任何屬性,這樣就允許用 JSF-EL 設置組件的屬性值。在創建使用 JSF-EL 綁定的組件屬性時,需要創建值綁定表達式。在調用綁定屬性的 getter 方法時,除非 setter 方法已經設置了值,否則 getter 方法必須用值綁定獲得值。 組件可以作為 像表單字段組件這樣的組件擁有一個 這里描述的許多組件的概念將會是接下來展示的示例的一部分,所以請記住它們!
我們用一個又好又容易的示例來開始 JSF 組件的開發:我將展示如何渲染 Label 標記(示例: 下面是我要采取的步驟:
Label 示例將演示 JSF 組件開發的以下方面:
返回 圖 1,可以看到在這個示例中會有兩個生命周期屬性在活動。它們是 Apply Request Value 和 Render Response。 在圖 2 中,可以看到在 JSP 中如何使用 Label 標記的( 圖 2. 在 JSP 中使用 JSF 標記 ![]() 第一步是創建一個組件,繼承 清單 1. 繼承 UIComponent 并添加 label
接下來要做的是保存組件狀態。JSF 通常通過會話、隱藏表單字段、cookies 等進行實際的存儲和狀態管理。(這通常是用戶配置的設置)。要保存組件狀態,需要覆蓋組件的 清單 2. 保存組件狀態
可以注意到,我使用的是 JDK 1.5。我對編譯器進行了設置,所以我必須指定 override 注釋,以便指明哪些方法要覆蓋基類的方法。這樣做可以更容易地標識出 JSF 的鉤子在哪。 創建組件的最后一步是用 faces-config.xml 登記它,如下所示:
下面要做的是內聯地定義渲染器的功能。稍后我會介紹如何創建獨立的渲染器。現在,先從編碼 Label 組件的輸出、顯示 label 開始,如清單 3 所示: 清單 3. 編碼組件的輸出
注意,響應寫入器( 下面顯示的 family 屬性用來把 Label 組件與渲染器關聯。雖然目前 Label 組件還不需要這個屬性(因為還沒有獨立的渲染器),但是在這篇文章后面,在介紹如何創建獨立渲染器的時候,會需要它。
如果正在使用來自 Sun Microsystems 的 JSF 參考實現(不是 MyFaces 實現),那么就不得不在組件創建代碼中添加下面一段:
Sun 的 JSF RI 期望,在組件沒有渲染器的時候,渲染器會發送一個空指針異常。MyFaces 實現不要求處理這個需求,但是在代碼中包含以上方法依然是個好主意,這樣組件既可以在 MyFaces 環境中工作也可以在 JSF RI 環境中工作了。
JSF 組件不是天生綁定到 JSP 上的。要連接起 JSP 世界和 JSF 世界,需要能夠返回組件類型的定制標記(然后在 faces-context 文件中登記)和渲染器,如圖 3 所示。 圖 3. 連接 JSF 和 JSP ![]() 注意,由于沒有獨立的渲染器,所以可以給
記住, 圖 4. 綁定 JSF 和 JSP ![]() 現在要做的全部工作就是創建一個 TLD(標記庫描述符)文件,以登記定制標記,如清單 4 所示: 清單 4. 登記定制標記
一旦定義了 TLD 文件,就可以開始在 JSP 中使用標記了,如下面示例所示:
現在就可以了 —— 開發一個簡單的 JSP 組件不需要更多了。但是如果想創建稍微復雜一些的組件,針對更復雜的使用場景時該怎么辦?請繼續往下看。
在下一個示例中,我將介紹如何創建這樣一個組件(和標記),它可以記住最后一個人離開的位置。Field 組件把多個組件的工作組合到一個組件中。復合組件是 JSF 組件開發的重點,會節約大量時間! Field 組件把標簽、文本輸入和消息功能組合到一個組件。Field 的文本輸入功能允許用戶輸入文本。如果有問題(例如輸入不正確),它的標簽功能會顯示紅色,還會顯示星號(*)表示必需的字段。它的消息功能允許它在必要的時候寫出出錯消息。 Field 組件示例演示了以下內容:
與 Label 組件不同,Field 組件使用獨立渲染器。如果為一個基于 HTML 的應用程序開發組件,那么不要費力使用獨立渲染器。這么做是額外的無用功。如果正在開發許多 JSF 組件,打算賣給客戶,而針對的客戶又不止一個,那么就需要獨立的渲染器了。簡而言之,渲染器適用于商業框架的開發人員,不適用于開發內部 Web 應用程序的應用程序開發人員。 由于我已經介紹了創建組件、定義渲染器以及創建定制標記的基本步驟,所以這次我讓代碼自己說話,我只點出幾個重要的細節。在清單 5 中,可以看到在典型的應用程序示例中如何使用 Field 標記的: 清單 5. Field 標記
以上標記輸出以下 HTML:
圖 5 顯示了瀏覽器中這些內容可能顯示的效果。 圖 5. Field 組件 ![]() 清單 6 顯示了創建 Field 組件的代碼。因為這個組件負責輸入文本而不僅僅是輸出它(像 Label 那樣),所以要從繼承 清單 6. Field 繼承 UIInput
可以注意到,代表片段中遺漏了編碼方法。這是因為編碼和解碼發生在獨立的渲染器中。我稍后會介紹它。 雖然 Label 組件只有一個屬性(JSP 屬性),可是 Field 組件卻有多個屬性,即 像使用 Label 組件時一樣,需要用定制標記把 Field 組件綁定到 JSP,如清單 7 所示: 清單 7. 為 FieldComponent 創建定制標記
從概念上說,在上面的代碼和 Label 組件之間找不出太大區別。但是,在這個示例中,
雖然 這個修訂后的
這個代碼允許 Field 組件的 最后介紹渲染器,但并不是說它不重要。獨立渲染器必須考慮的主要問題是解碼(輸入) 和編碼(輸出)。Field 組件做的編碼比解碼多得多,所以它的渲染器有許多編碼方法,而只有一個解碼方法。在清單 8 中,可以看到 Field 組件的渲染器: 清單 8. FieldRenderer 擴展自 Renderer
正如前面提到的,渲染器做的主要工作就是解碼輸入和編碼輸出。我先從解碼開始,因為它是最容易的。
Label 組件不需要進行解碼,因為它是一個 編碼方法沒什么驚訝的。它們與 Label 組件中看到的類似。第一個方法
首先, 您可能已經注意到,有一個方法我還沒有介紹。這個方法就是這個類中的“黑馬”方法。如果您閱讀 實際上,基類 相反,需要使用方法 清單 9. getConvertedValues 方法
清單 9 的代碼添加了 如果想知道如何把組件和渲染器關聯,那么只要看看圖 6 即可。 圖 6. 把渲染器映射到組件 ![]() 定制標記有兩個方法,分別返回組件類型和渲染器類型。這些方法用于查找配置在 faces-config.xml 中的正確的渲染器和組件。請注意(雖然圖中沒有)組件必須返回正確的 family 類型。
通過這些內容,您已經切實地了解了 JSF 組件開發的核心。當然,在這個領域還有許多其他主題需要涉及 —— 包括發出組件事件、國際化組件、創建 在編寫這篇文章的過程中,我遇到了 我希望在這個由四部分組成的系列中,您已經學到了關于使用 JSF 的優勢的充足知識,以及它如何工作的基礎知識,還希望您會喜歡進一步深入這項技術。而且當您有時可能迷失方向的時候,請不要陷入 FUD。相反,請記住我說過的:彎路會看到優美的風景,請繼續前行。 |
14年前那個風雨交加的夜晚,我眾叛親離,跟著深愛的你到深圳做了打工妹。貧窮的你落榜后除了生病的母親、衰弱的父親和那半間破瓦屋,就剩下我了。記得當初來深圳打工的路費用的也是我做一個月民辦老師的工資。我所受的苦都是為了今生能與你長相守。
或許,我的眼光不錯,你是很棒的。10年后的今天,當我家所有的人松了一口氣,原諒我沒嫁錯郎的時候,有了車、有了別墅的你卻在直言不諱地對我說,你找到了“心靈知音”,如果我愿意解除婚姻的話,財產、孩子都給我;否則你背叛我,我不能有怨言。
我笑了,說3天后給你答復。
3天后,我開列了一張婚姻的清單給你過目:
1、婚姻10年,你穿舊了3套睡衣,穿壞了4雙拖鞋,踏破了21雙皮鞋。破的皮鞋最多,因為你在外面掙錢所花的時間多,所以會有“心靈知音”看上成功的你。
2、婚姻10年,我穿舊了10套睡衣、穿爛了11雙拖鞋、踏壞了16雙皮鞋。
|
3、婚姻10年,常青樹的你升值X倍,離婚后,從深圳排到杭州那么多的美女等著“成功人士、成熟有品位”的你挑選。
4、婚姻10年,青春快逝的我貶值了10000倍;實話實說,離婚了我再婚的機會是1%,年老的我看不上和我年齡相近的男人,而除非太差,一般的男人是不愿意娶一個帶著孩子的中年女人的。
5、婚姻10年,繁忙的你只燒過26次飯給我吃。
6、婚姻10年,忙碌的我一年365天,日日三餐,做好飯給你吃。
7、婚姻10年,生一個孩子,我用了10個月,養、育、教了10年。
8、婚姻10年,生一個孩子,你用了10分鐘,給了他一個姓。
9、婚姻10年,我和你父母和睦相處,沒有一句高聲的話語。
10、婚姻10年,你一直不肯原諒愛女心切的我的父母,沒有叫過一聲爸爸媽媽。貧窮時你說我爸爸媽媽不會應答你,你堅決不肯叫;有錢后說不再怕他們了而不叫。難道你愿意自己的女兒在能夠選擇的時候去選擇貧窮嗎?希望女兒富足,這是人之常情呀!
親愛的,如果你看了上面的婚姻總結,能夠用眼睛看著我說離婚的話,我成全你的心愿。你什么時間跟我說都可以,我答應和你離婚。
只是,我等了你一年,你都沒有再提離婚這件事。變得早回家、勤炒菜、會拖地的你不是將功贖罪吧?或許,因為,有良心的人居多,所以這世界上還是房子比監獄多!