1. 打開(kāi)工具Oracle SQL Plus 以dba身份登錄sys用戶
sqlplus /nolog
conn sys@url as sysdba
2. 創(chuàng)建用戶并指定表空間
使用客戶端工具或者Web管理控制臺(tái)創(chuàng)建表空間以及用戶
給用戶賦予connect、resource、dba權(quán)限
grant connect,resource,dba to username;
3. 使用imp工具導(dǎo)入dmp數(shù)據(jù)文件
imp username/password@url file=c:\db.dmp fromuser=username1 touser=username log=c:\log.txt
-------------------------------------------------------------------------------------------------------------
其它命令:
select * from dba_users; --查詢用戶
這幾天在看郎咸平的《誰(shuí)在謀殺中國(guó)經(jīng)濟(jì)》,這本書(shū)我基本看過(guò)一遍了,認(rèn)為全書(shū)的重點(diǎn)在于中華文化的四大茫然,整本書(shū)都是圍繞這四大茫然展開(kāi)論述,中華文化的四大茫然如下:
茫然之一:就知道賺錢(qián)
茫然之二:不了解世界
茫然之三:不了解別人為什么那么看你
茫然之四:不了解自己的缺點(diǎn)
大家有時(shí)間可以看看這本書(shū),我覺(jué)得寫(xiě)的不錯(cuò),至少我自己看完深有感觸,我覺(jué)得完全可以將這幾點(diǎn)套用到我們生活的很多方面,比如對(duì)于我們搞IT的技術(shù)人員來(lái)說(shuō),我認(rèn)為現(xiàn)在很多人也存在四大茫然:
茫然之一:只知道完成任務(wù)。也許是我年齡大了點(diǎn),但我覺(jué)得現(xiàn)在很多小朋友,尤其是85年以后出生的,工作的時(shí)候只是在完成任務(wù),事情做完了,有時(shí)也不測(cè)試,或者就是匆匆測(cè)試,匆匆結(jié)束,并沒(méi)有好好的想為什么這件事老大要讓我這樣做,這樣做有什么好處,會(huì)不會(huì)有缺點(diǎn),我是不是有更好的方法。當(dāng)你不去想的時(shí)候,意味著你少了很多提高的機(jī)會(huì)。
茫然之二:不追究為什么。很多人做事情就象第一條說(shuō)的那樣,只是完成任務(wù),并不去想其中的原理是什么。面試過(guò)很多人,對(duì)于目前工作兩三年的大部分人來(lái)說(shuō)(當(dāng)然我面試的不是好的學(xué)校畢業(yè)的,基本學(xué)校為中等偏下點(diǎn)),一旦涉及到Spring、Hibernate、Struts等框架深入點(diǎn)東西的時(shí)候,大都回答不上來(lái),只是對(duì)框架能熟練應(yīng)用而已。這樣夠么?計(jì)算機(jī)的很多知識(shí),當(dāng)你熟悉了其運(yùn)作原理,框架對(duì)于你來(lái)說(shuō),只是手到擒來(lái),看看學(xué)學(xué)就會(huì)用了。我問(wèn)過(guò)好幾個(gè)同事,平時(shí)晚上回去都干嘛,很多人都回答我晚上回去看看電視,稍微看看書(shū)就睡覺(jué)了。我有點(diǎn)驚訝,我想如果你想成為一個(gè)技術(shù)高手,一個(gè)能拿高薪的程序員,你又沒(méi)有天份,又不付出超過(guò)常人的努力,憑什么你比別人強(qiáng)呢?
茫然之三:不善于總結(jié)。很多人(又是很多人)過(guò)著做一天和尚撞一天鐘的日子,日子一天一天過(guò)去,基本不去總結(jié),只是過(guò)了好長(zhǎng)一段時(shí)間會(huì)發(fā)覺(jué),原來(lái)最近我啥也沒(méi)有進(jìn)步,啥也沒(méi)學(xué)到,還是老樣子。知識(shí)在于積累,你只有不斷總結(jié),知識(shí)才能更好的積累,才能更好的為你服務(wù)。
茫然之四:沒(méi)有明確的目標(biāo)。一個(gè)人沒(méi)有目標(biāo)就決定了他不會(huì)有長(zhǎng)足的進(jìn)步。你都沒(méi)有想過(guò)自己要成為一個(gè)架構(gòu)師,一個(gè)項(xiàng)目經(jīng)理,一個(gè)部門(mén)經(jīng)理,一個(gè)技術(shù)總監(jiān),都沒(méi)有想過(guò)要成為這樣的人需要具備什么樣的條件,你怎么可能知道自己欠缺什么?需要補(bǔ)充什么呢?長(zhǎng)遠(yuǎn)目標(biāo)要明確,然后根據(jù)長(zhǎng)遠(yuǎn)目標(biāo)進(jìn)行分析,我要達(dá)到這樣的目標(biāo),還有什么欠缺,據(jù)此制定短期目標(biāo),短期目標(biāo)一定要可實(shí)現(xiàn)可操作。這樣隨著你目標(biāo)的一步一步實(shí)現(xiàn),你各方面的能力也隨之提高了。
寫(xiě)了幾點(diǎn),也作為對(duì)自己的鞭策。
2010年已經(jīng)過(guò)去一個(gè)月了,趕在農(nóng)歷春節(jié)前列一下今年的讀書(shū)清單,不能總把精力放在工作中了,也需要補(bǔ)充點(diǎn)新知識(shí)了,否則沒(méi)有新東西能貢獻(xiàn)出來(lái)了。
1、《OSGI原理與最佳實(shí)踐》,結(jié)合這本書(shū)并研究SpringDM,做一些實(shí)例。
2、《SQL語(yǔ)言藝術(shù)》
3、《Oracle9i&10g編程藝術(shù)》
4、《架構(gòu)之美》
5、《UML和模式應(yīng)用》
6、《UML彩色建模》
7、《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)與模式實(shí)戰(zhàn)》
8、《敏捷軟件開(kāi)發(fā) 原則、模式與實(shí)踐》
9、《軟件開(kāi)發(fā)的邊界》
10、《軟件隨想錄》
11、《走出軟件作坊》
就這么多了,9、10、11去年都看過(guò)一遍了,但好多地方粗粗過(guò)了一下,還要仔細(xì)閱讀。
另外也對(duì)自己提個(gè)要求,看書(shū)要做讀書(shū)筆記。
2010年-我的讀書(shū)年!
摘自《軟件隨想錄》
看了軟件隨想錄中下面一段話,覺(jué)得非常棒,作為一名軟件從業(yè)人員,不一定有機(jī)會(huì)能實(shí)現(xiàn)描述中的優(yōu)秀軟件產(chǎn)品,但這樣的理念需要貫穿我們每個(gè)人的心田,時(shí)刻記在心中:
【創(chuàng)造一個(gè)有使用價(jià)值的軟件,你必須時(shí)時(shí)刻刻都在奮斗,每一次的修補(bǔ),每一個(gè)功能,每一處小小的改進(jìn),你都在奮斗,目的只是為了再多創(chuàng)造一點(diǎn)空間,可以再多吸引一個(gè)用戶加入。沒(méi)有捷徑可走。你需要一點(diǎn)運(yùn)氣,但是這不取決于你是否幸運(yùn)。你之所以會(huì)有好運(yùn)氣,那是因?yàn)槟愦缤帘貭?zhēng)。
每天你前進(jìn)一小步,將一件東西做得比昨天好一點(diǎn)點(diǎn)。這樣的改進(jìn)幾乎看不出可以讓誰(shuí)獲益,幾乎沒(méi)有變化。但是,你前進(jìn)了一小步。
有無(wú)數(shù)個(gè)要做的這樣微小的改進(jìn)。
為了發(fā)現(xiàn)可以改進(jìn)的地方。你必須有一個(gè)思維定勢(shì),始終如一的用批判的眼光看世界。隨便找一樣?xùn)|西,如果你看不出它的缺點(diǎn),那么你的思維轉(zhuǎn)型還沒(méi)有成功。當(dāng)你成功的時(shí)候,你身邊親密的人會(huì)被你逼得發(fā)瘋。你的家人恨不得殺了你。當(dāng)你步行上班的時(shí)候,看到一個(gè)司機(jī)漫不經(jīng)心地開(kāi)車(chē),你幾乎用了所有的意志力才勉強(qiáng)忍不住沖上去告訴那個(gè)司機(jī),他這樣開(kāi)車(chē)差點(diǎn)兒要了旁邊坐在輪椅上的那個(gè)可憐小孩的命。
當(dāng)你改正了一個(gè)又一個(gè)這樣的小細(xì)節(jié)后,當(dāng)你磨光、定型、擦亮、修飾你的產(chǎn)品的每一個(gè)小邊角后,就會(huì)有神奇的事情發(fā)生。厘米變成分米,分米變成米,米變成了千米。你最后拿出來(lái)的是一件真正優(yōu)秀的產(chǎn)品。它第一眼就讓人覺(jué)得震撼,出類(lèi)拔萃,工作起來(lái)完全符合直覺(jué)。就算100萬(wàn)個(gè)用戶中有一個(gè)用戶某天突然要用到一個(gè)他100萬(wàn)次使用中才會(huì)用到一次的罕見(jiàn)功能,他發(fā)現(xiàn)了這個(gè)功能不僅能用,而且還很沒(méi):在你的軟件中,即使是看門(mén)人的小屋都鋪著大理石的地板,配有實(shí)心的橡木門(mén)和桃花心木的壁板。
就是在這個(gè)時(shí)候,你意識(shí)到這是一個(gè)優(yōu)秀軟件。】
http://www.insideria.com/2009/05/flex-4-custom-layouts.html
http://www.insideria.com/2009/10/easy-flex-skinning-with-firewo.html
在Flash Builder 4 Beta 2版本中,使用mxml方式實(shí)現(xiàn)state的切換有了很大改進(jìn),使用起來(lái)更方便,具體可參見(jiàn)下文:
http://onflex.org/learn/fx4/index.php?page=States
看完這篇文章后,想到一個(gè)問(wèn)題,如何用編程的方式實(shí)現(xiàn)切換呢,找了參考資料,實(shí)現(xiàn)了一個(gè)例子,代碼如下:
開(kāi)發(fā)環(huán)境:Flash Builder 4 Beta2
這是前幾天在別人的BLog上看到的一幅圖,覺(jué)得不錯(cuò),基本涵蓋了IT人員需要掌握的基礎(chǔ)知識(shí)這塊,從這幅圖中可以看出語(yǔ)言并不重要,關(guān)鍵是要搞明白整個(gè)環(huán)節(jié),這樣遇到任何問(wèn)題就能有目的、有方法的學(xué)習(xí)了。
1、下載Ruby并安裝,下載地址:http://rubyforge.org/frs/?group_id=167
下載了1.8.6-27 Release Candidate 2(ruby186-27_rc2.exe)版本
2、在windows的命令行下,輸入 ruby –v,檢查ruby是否正確安裝,應(yīng)該出現(xiàn)如下信息:
ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32]
3、安裝rails,執(zhí)行g(shù)em install rails命令,安裝成功后,執(zhí)行rails -v檢查。
我安裝了Rails2.3.2版本。使用gem install -version rails可以指定安裝的rails版本,具體如何使用gem,可以用gem help install查看幫助。
參考:Ruby On Rails(ROR)安裝(http://enjoylog.cn/?p=8)
裝好了便到Ruby On Rails的官方網(wǎng)站(http://rubyonrails.org/),找到了
Getting Started with Rails(http://guides.rubyonrails.org/getting_started.html)
開(kāi)始一步一步follow up。
RubyOnRails的中文站上的翻譯文檔沒(méi)有完全跟進(jìn),還是看英文的吧。
我使用的是MySQL的數(shù)據(jù)庫(kù),操作系統(tǒng):Vista。
到創(chuàng)建POSTS應(yīng)用的時(shí)候遇到了問(wèn)題,創(chuàng)建數(shù)據(jù)后數(shù)據(jù)庫(kù)中有數(shù)據(jù),但是到Listing posts界面無(wú)法查看,總是報(bào)錯(cuò)。
網(wǎng)上Google了一下,果然有人遇到相同的問(wèn)題,參照了如下解決方案,到
http://instantrails.rubyforge.org/svn/trunk/InstantRails-win/InstantRails/mysql/bin/ 上下載了libmySQL.dll文件放到RUBY_HOME/bin/目錄下,問(wèn)題解決。
參考:升級(jí)2.2后mysql驅(qū)動(dòng)的問(wèn)題(http://www.javaeye.com/topic/283871?page=1)
感嘆一下,當(dāng)Listing Posts這個(gè)CRUD小應(yīng)用跑起來(lái)后,覺(jué)得Ruby On Rails的開(kāi)發(fā)是比Java開(kāi)發(fā)要快一些,看了一下它生成的代碼,貌似也不多。
今天晚了,明天繼續(xù)。
最近在做一個(gè)很小的項(xiàng)目的功能改進(jìn),小小的項(xiàng)目中原來(lái)連接的是MySQL數(shù)據(jù)庫(kù),現(xiàn)在需要新連接一個(gè)數(shù)據(jù)庫(kù)(Oracle),僅僅從一張表查詢數(shù)據(jù)即可,沒(méi)有添加、修改、刪除等等功能。本來(lái)這個(gè)小小的項(xiàng)目中用的是Hibernate,現(xiàn)在又要增加一個(gè)數(shù)據(jù)庫(kù)連接,覺(jué)得配置起來(lái)有點(diǎn)麻煩,忽然想起來(lái),我干嗎還要用Hibernate呢,直接用JDBC不也挺好使么,想了便做,果然寫(xiě)起JDBC來(lái),很是快捷,一會(huì)就搞好了。
做好了以后,忽然覺(jué)得有點(diǎn)迷茫,感覺(jué)不用Hibernate不也挺好的么,咱為什么現(xiàn)在開(kāi)口閉口都是Hibernate呢,于是便有了今天的題目。
很久以前沒(méi)有Hibernate的時(shí)候:
第一階段:我們寫(xiě)程序都是直接用JDBC,甚至在JSP頁(yè)面中直接去createConnection,然后執(zhí)行查詢,輸出到頁(yè)面。
第二階段:后來(lái)覺(jué)得每次都是創(chuàng)建一個(gè)連接,好像效率不高,于是看了別人的介紹,要用數(shù)據(jù)庫(kù)連接池,好的,那便用數(shù)據(jù)庫(kù)連接池吧,每次都從pool中獲得一個(gè)Connection,然后查詢數(shù)據(jù)。
第三階段:用了連接池,還是效率不高,那怎么辦呢?用緩存吧,自己實(shí)現(xiàn)緩存?可以,也可以用開(kāi)源的緩存框架。
第四階段:到了OO大流行的時(shí)代了,一切都要OO,恰逢Hibernate降臨人世,于是一切都用Hibernate來(lái)實(shí)現(xiàn)了,其實(shí)同期還是有不少其它ORMAP框架的,比如(TOPLINK、JDO、IBatis等,IBatis國(guó)內(nèi)用的還比較多,另外兩個(gè)好像用的比較少)。
第五階段:忽然EJB大流行,事務(wù)的概念被廣為傳播(并不是原來(lái)沒(méi)有事務(wù)的概念,只是實(shí)現(xiàn)起來(lái)比較麻煩),借助EJB的廣為傳播,Spring+Hibernate的組合也慢慢占據(jù)了大半市場(chǎng)。此時(shí)事務(wù)用Spring AOP的聲明式事務(wù)來(lái)解決,緩存可以用開(kāi)源的緩存框架(已經(jīng)和Hibernate無(wú)縫集成了),數(shù)據(jù)庫(kù)連接池也是通過(guò)配置的方式在SpringContext.xml文件中配置,貌似一切都很完美。
真的到了第五階段,一切是不是真的完美了呢,如果一個(gè)很小的應(yīng)用,需要從好幾個(gè)數(shù)據(jù)庫(kù)查詢數(shù)據(jù),但是每個(gè)數(shù)據(jù)庫(kù)僅需要查詢那么一兩張表的數(shù)據(jù),偶爾添加、刪除幾條數(shù)據(jù),數(shù)據(jù)量也不大,此時(shí)我們是不是還用第一階段的方式會(huì)更好呢,好像有時(shí)配置多數(shù)據(jù)源也不是那么方便的事情。或者使用Spring中的JDBCTemplate,貌似也不錯(cuò)。
再往后看,難道Spring+Hibernate的組合就天下無(wú)敵了么?難道就沒(méi)有新的框架了么?前段時(shí)間,JavaEye上關(guān)于充血模型、貧血模型的討論吸引了多少眼球,以后是不是會(huì)有這么一個(gè)框架用于實(shí)現(xiàn)充血模型呢?
說(shuō)了這么多,最終只是想說(shuō)明白這么一句:用恰當(dāng)?shù)募夹g(shù)做恰當(dāng)?shù)氖虑椋@真是一個(gè)艱難的選擇……,至于未來(lái),更是迷茫,因?yàn)槲覀冎皇歉S者,而不是領(lǐng)導(dǎo)者。
前兩天出差在外,利用空余時(shí)間將《深入淺出EXT JS》這本書(shū)的前五章翻了一遍,后面的章節(jié)粗粗瀏覽了一下,覺(jué)得這本書(shū)寫(xiě)的不錯(cuò),寫(xiě)下自己的一點(diǎn)感悟:
1、適合的讀者
a、是一名Java開(kāi)發(fā)程序員,做過(guò)WEB開(kāi)發(fā)
b、對(duì)Ajax開(kāi)發(fā)的基礎(chǔ)知識(shí)有所了解
2、書(shū)評(píng):
這本書(shū)我覺(jué)得應(yīng)該改成這個(gè)名字:《EXT JS CookBook》,可能使得書(shū)的內(nèi)容和名稱更貼切,呵呵。
書(shū)中對(duì)Ext JS的基礎(chǔ)類(lèi)、Grid、Form、Tree、布局管理器、數(shù)據(jù)獲取等各方面都做了詳細(xì)的描述,基本上開(kāi)發(fā)中需要用到的知識(shí)點(diǎn),在書(shū)中都會(huì)提到,而且書(shū)中的很多例子和實(shí)際工作還是非常貼切的,對(duì)于工作中需要用到EXT JS或者需要學(xué)習(xí)EXT JS的程序員來(lái)說(shuō)還是會(huì)很有幫助的。
最后提點(diǎn)缺點(diǎn),這本書(shū)中對(duì)EXT JS的知識(shí)點(diǎn)都做了比較詳細(xì)的描述,但是缺乏對(duì)EXT JS的框架的深入分析。
前兩天在InfoQ上看到一篇文章:利用Clear Toolkit連接Flex與Java開(kāi)發(fā),今天下載了說(shuō)明文檔粗略了翻了一遍,Clear Toolkit包含五個(gè)部分,分別是:
暫時(shí)用不到這個(gè)工具,記錄留待備查。
這篇Blog是原來(lái)寫(xiě)在別的地方的,今天將其轉(zhuǎn)到BlogJava上來(lái)。
-------------------------------------------------------------------------------
今天仔仔細(xì)細(xì)的看了一下Hibernate的緩存,并做了實(shí)例實(shí)踐了一把。google一下,網(wǎng)上的教程、文章很多。
自己小結(jié)一下:
Hibernate的緩存分為:
緩存的注釋寫(xiě)法如下,加在Entity的java類(lèi)上:
緩存的方式有四種,分別為:
另外還有如下注意事項(xiàng):
1、查詢緩存需要在Query的相應(yīng)方法執(zhí)行前加上這么一句:
query.setCacheable(true);
在使用Hibernate時(shí),獲得的query有setCacheable方法,可以設(shè)置使用緩存,但當(dāng)使用JPA時(shí),javax.persistence.Query并沒(méi)有setCacheable方法,此時(shí)如果JPA的實(shí)現(xiàn)是Hibernate時(shí),可以將其進(jìn)行如下轉(zhuǎn)化,再調(diào)用setCacheable方法(如果JPA的實(shí)現(xiàn)是其它ORMAP框架,就不知道怎么做了)。
2、還有就是查詢緩存的查詢執(zhí)行后,會(huì)將查詢結(jié)果放入二級(jí)緩存中,但是放入的形式是以ID為Key,實(shí)例作為一個(gè)Value。
3、hibernate的配置文件中需加入如下信息:
今天在Javaeye的新聞?lì)l道看到一個(gè)界面原型繪制工具,叫做“wireframesketcher”,下載試了試,感覺(jué)有如下幾個(gè)好處:
1、使用方便,可以很容易的做tree和table,比visio中的tree和table好用
2、集成在eclipse中,對(duì)于開(kāi)發(fā)人員來(lái)說(shuō)用起來(lái)更直接
3、其界面原型文件為xml格式,可以使用比較工具比較
唯一的缺點(diǎn):
不是免費(fèi)開(kāi)源的工具,但是現(xiàn)在可以申請(qǐng)免費(fèi)的license
隨便畫(huà)了一個(gè)圖,如下:
感興趣的兄弟姐妹們可以到如下地址看看:
http://wireframesketcher.com/index.html
由于要寫(xiě)一個(gè)Spring的培訓(xùn)教材,要做Spring的事務(wù)樣例,于是開(kāi)始寫(xiě)樣例,寫(xiě)好了一測(cè),控制臺(tái)有SQL輸出,數(shù)據(jù)庫(kù)卻查詢不到數(shù)據(jù),查亞查亞,花了一個(gè)多小時(shí),原來(lái)是獲取的Service不是經(jīng)過(guò)代理的Service,自然事務(wù)不起作用,數(shù)據(jù)庫(kù)里就沒(méi)有數(shù)據(jù)了,鄙視一下自己。
配置文件樣例如下(已經(jīng)修改了dao和service的命名,減少了寫(xiě)錯(cuò)的可能性,以后命名問(wèn)題一定要注意):
給自己做的這個(gè)程序起了個(gè)名字叫EasyWork,代碼可以從Google Code上下載,具體地址如下:
http://easywork.googlecode.com/svn/trunk/
由于時(shí)間關(guān)系,這個(gè)程序還存在不少問(wèn)題,所以只能供大家參考,有問(wèn)題不要罵我就行了:)
簡(jiǎn)要使用說(shuō)明:
1、開(kāi)發(fā)環(huán)境+運(yùn)行環(huán)境:MyEclipse6.0,JDK1.5,Tomcat6.0.14,MySQL5.0
2、準(zhǔn)備好上述環(huán)境后,使用下載代碼sql目錄中的easywork_init.sql腳本創(chuàng)建數(shù)據(jù)庫(kù)表和初始數(shù)據(jù)。
3、將項(xiàng)目導(dǎo)入Eclipse后,運(yùn)行Tomcat(此過(guò)程就不詳細(xì)描述了)。
4、使用http://localhost/easywork/system/login.jsp訪問(wèn)登錄頁(yè)面,目前還沒(méi)有做index.html,默認(rèn)用戶名/密碼:admin/1。
存在問(wèn)題如下:
1、任務(wù)管理功能還沒(méi)有完全完成,日志記錄還沒(méi)有做。
2、超時(shí)或者沒(méi)有登錄訪問(wèn)頁(yè)面時(shí),只是報(bào)不能訪問(wèn)的異常,沒(méi)有轉(zhuǎn)入登錄頁(yè)面。
3、對(duì)資源類(lèi)型(菜單、URL、字段、操作)的訪問(wèn)限制還沒(méi)有做。
4、很多界面的輸入信息校驗(yàn)沒(méi)有做。
5、基本沒(méi)有美工。
6、總而言之,目前這個(gè)項(xiàng)目中的代碼只能做Struts2 + ExtJS如何使用的借鑒:)
很近沒(méi)有更新BLog了,這一陣子忙著學(xué)習(xí)Struts2和ExtJS,使用這兩者做了一個(gè)小程序,使用RBAC實(shí)現(xiàn)了基本的權(quán)限管理功能,還做了一個(gè)任務(wù)管理和日志記錄,任務(wù)管理用于記錄當(dāng)前需要處理的事情,日志記錄用于記錄每天的工作情況。
用下來(lái)Struts2和ExtJS還是挺好用的。先貼幾張圖,后續(xù)再把學(xué)習(xí)過(guò)程中遇到的問(wèn)題整理出來(lái)。
任務(wù)管理
添加組
添加權(quán)限
添加角色
由于前段時(shí)間使用JSF做了一個(gè)項(xiàng)目,不少使用JSF的兄弟們對(duì)JSF評(píng)價(jià)并不好,因此在學(xué)習(xí)的過(guò)程中一直在想,JSF究竟是不是應(yīng)該繼續(xù)學(xué)習(xí)繼續(xù)研究使用下去,在看完Seam In Action的第三章后,這個(gè)星期又對(duì)Struts2簡(jiǎn)單學(xué)習(xí)了一下,終于決定結(jié)束JSF和JBoss Seam的學(xué)習(xí)了。
因?yàn)閺腏SF的學(xué)習(xí)和Struts2的學(xué)習(xí)對(duì)比中明顯覺(jué)得JSF復(fù)雜,對(duì)于一個(gè)技術(shù)力量不是非常強(qiáng)的項(xiàng)目組來(lái)說(shuō),使用JSF當(dāng)你遇到一些問(wèn)題時(shí),絕對(duì)是一件痛苦的事情。
從自己的實(shí)踐中覺(jué)得JSF至少有兩個(gè)致命傷:
1、覺(jué)得JSF貌似把簡(jiǎn)單的事情搞得復(fù)雜化了,在傳統(tǒng)的MVC框架如Struts中,從request中獲取param很容易,也可以將param封裝為對(duì)象,在JSF中,希望將這一切都模型化,一切都以組件為中心,類(lèi)似于Swing的架構(gòu),但是http的無(wú)狀態(tài)以及web的本質(zhì),使得一般JSF只能將組件樹(shù)存放在服務(wù)端,同時(shí)又不能象CS程序那樣方便的查看組件的狀態(tài)、屬性等信息。對(duì)于通常情況來(lái)說(shuō),JSF將其封裝的很好,不用我們開(kāi)發(fā)者操心,但是當(dāng)遇到一些問(wèn)題時(shí),對(duì)于開(kāi)發(fā)者想去調(diào)試查看問(wèn)題時(shí),問(wèn)題就顯得很復(fù)雜了。
2、JSF的自定義組件感覺(jué)超復(fù)雜,難度應(yīng)該比當(dāng)年自定義JSP標(biāo)簽更要高,試想一下,如果哪個(gè)組件不合意了,想改一下,還是比較困難的,除非對(duì)JSF組件有相當(dāng)?shù)纳钊肓私狻?/p>
順便把項(xiàng)目中遇到的一個(gè)RichFaces的缺點(diǎn)列出來(lái):
RichFaces在生成組件的html時(shí),大量使用了Div,曾經(jīng)有過(guò)一個(gè)頁(yè)面有1千多行(在一個(gè)table中),頁(yè)面上還有一個(gè)RichFaces的下拉菜單,從而導(dǎo)致菜單響應(yīng)非常之慢,后來(lái)只有將rich:datatable換為普通的html:table,就沒(méi)有問(wèn)題了。
再看看Seam In Action中總結(jié)的JSF的缺點(diǎn):
1、在JSF中初次請(qǐng)求的處理流程太過(guò)簡(jiǎn)單,而后續(xù)請(qǐng)求則執(zhí)行了完整的復(fù)雜的處理流程。在JSF中假設(shè)第一個(gè)調(diào)用應(yīng)該是在頁(yè)面被渲染后執(zhí)行,但實(shí)際中有時(shí)我們需要在第一次請(qǐng)求時(shí)就執(zhí)行某些操作。在JSF中缺少象Struts中的Controller。
2、所有的請(qǐng)求都是POST。瀏覽器處理POST請(qǐng)求是比較草率,當(dāng)用戶執(zhí)行了一個(gè)JSF Action操作后,點(diǎn)擊瀏覽器的刷新按鈕時(shí),瀏覽器會(huì)詢問(wèn)用戶是否重新提交,這會(huì)令用戶非常困惑。
3、僅僅擁有簡(jiǎn)單基礎(chǔ)的頁(yè)面導(dǎo)向機(jī)制。
4、過(guò)度復(fù)雜的生命周期。
JBossSeam宣稱對(duì)于JSF存在的缺點(diǎn)都提供了解決方法,但是有一種更復(fù)雜的感覺(jué)。
在Seam中,生成選擇的項(xiàng)目時(shí),有EAR和WAR的選項(xiàng),如果選擇了EAR選項(xiàng),那么Seam會(huì)生成四個(gè)項(xiàng)目,分別為war、ear、ejb、test四個(gè)類(lèi)型的項(xiàng)目。有一次我將生成的項(xiàng)目從一個(gè)目錄拷貝到另一個(gè)目錄,切換了Eclipse的workspace,此時(shí)問(wèn)題來(lái)了,ejb項(xiàng)目提示編譯錯(cuò)誤,提示無(wú)法找到某些class,找來(lái)找去找來(lái)找去......后來(lái)將項(xiàng)目關(guān)閉了一下,再打開(kāi)錯(cuò)誤提示就沒(méi)有了。
由這個(gè)問(wèn)題我忽然想到,使用Seam集成JSF、EJB是不是太重量級(jí)了,如果采用EJB作為替代普通的POJO,對(duì)于一個(gè)小型的項(xiàng)目組來(lái)說(shuō),一般的規(guī)模就是三至五個(gè)人(我個(gè)人的理解),開(kāi)發(fā)人員本來(lái)就不多,還要面對(duì)Seam劃分的四個(gè)項(xiàng)目,好像比較繁瑣,當(dāng)然采用war模式另當(dāng)別論。
相比較而言,這個(gè)星期看了一些Struts2的資料,覺(jué)得Struts2的架構(gòu)非常清晰,易于理解。
翻了很早之前的JavaEye上的一個(gè)帖子,提到JSF是面向開(kāi)發(fā)工具的,如果能做到象VB那樣,就大有前途了,4年過(guò)去了,不要提JSF的開(kāi)發(fā)工具了,就是Java各個(gè)方面的GUI開(kāi)發(fā)工具,又有哪個(gè)能和VB相比呢,看來(lái)選擇JSF作為一個(gè)方向不是一個(gè)好選擇........還是及早放棄吧,哎...
最后我覺(jué)得可以用這么一句話可以形容JSF,看起來(lái)很美,用起來(lái)不爽。
這個(gè)事情去年做過(guò)一次,不過(guò)沒(méi)有留下記錄,今天又要做一次,記錄下來(lái),呵呵
環(huán)境:
Spring版本為1.2,Tomcat為5.5.26,JDK為Jdk1.5.0_11。
1、下載Axis1.4,解壓后將其jar文件添加到web項(xiàng)目的lib目錄中。
2、配置Axis Servlet,在web.xml文件中加入如下信息:
3、編寫(xiě)java類(lèi),樣例如下。
接口:
實(shí)現(xiàn)類(lèi):
注意實(shí)現(xiàn)類(lèi)需要繼承ServletEndpointSupport類(lèi),該類(lèi)是由Spring提供的。
4、配置service-config.wsdd。
5、測(cè)試web service服務(wù),代碼如下。
至項(xiàng)目的WEB-INF目錄下,執(zhí)行如下命令:
Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/services/interchangeDataService?WSDL
會(huì)在WEB-INF目錄中生成四個(gè)JAVA文件,它們分別是:
最后編寫(xiě)一個(gè)Main方法,調(diào)用如下方法即可進(jìn)行測(cè)試:
上次使用Seam自動(dòng)生成了一個(gè)CRUD的例子,后來(lái)想還是自己白手起家做一個(gè)例子看看,于是開(kāi)始動(dòng)手。
首先使用JBossTools工具生成項(xiàng)目,在生成項(xiàng)目的向?qū)е校绻?xiàng)目類(lèi)型選擇ear,則會(huì)生成四個(gè)項(xiàng)目,分別對(duì)應(yīng)war、ear、ejb、test,覺(jué)得這樣太過(guò)繁瑣,還是選擇war類(lèi)型,又想要不使用tomcat作為運(yùn)行服務(wù)器吧,因?yàn)镴Boss也不太熟悉。沒(méi)想到這一試倒試出問(wèn)題來(lái)了,如果完全使用向?qū)身?xiàng)目,選擇tomcat作為運(yùn)行服務(wù)器,則項(xiàng)目根本無(wú)法運(yùn)行起來(lái),總是提示缺少這個(gè)jar,那個(gè)jar。好,又換回JBoss,沒(méi)問(wèn)題了。仔細(xì)看了一下,原來(lái)在自動(dòng)生成項(xiàng)目的WebContent/WEB-INF/lib目錄中,只有大概十幾個(gè)jar,連Hibernate的jar都沒(méi)有,而在JBoss的Server/default/lib目錄下則什么jar都有,怪不得不出錯(cuò)。
第一個(gè)教訓(xùn):還是先使用JBoss作為運(yùn)行環(huán)境,等整個(gè)Seam都搞熟了,再配一個(gè)Tomcat的運(yùn)行環(huán)境。
繼續(xù),將原來(lái)項(xiàng)目中的一個(gè)通用DAO和一個(gè)UserService拷貝過(guò)來(lái),代碼如下,啟動(dòng)服務(wù)器報(bào)錯(cuò)。分別為如下錯(cuò)誤信息:
第二個(gè)錯(cuò)誤解決:Caused by: java.lang.IllegalArgumentException: @PersistenceContext may only be used on session bean or message driven bean components: genericDao
既然提示@PersistenceContext只能用在SessionBean中,因?yàn)樵瓉?lái)的代碼是使用的Spring框架,想了好長(zhǎng)時(shí)間,在WebContent/WEB-INF/component.xml中看到這么一段,那么是不是通過(guò)@In來(lái)注入entityManager呢,修改@PersistenceContext為@In,編輯器自動(dòng)提示沒(méi)有發(fā)現(xiàn)名稱為em的Component(這點(diǎn)好像不錯(cuò)),于是再修改為@In("entityManager") ,重啟服務(wù)器,該問(wèn)題解決。
第三個(gè)錯(cuò)誤解決:Caused by org.jboss.seam.RequiredException with message: "@In attribute requires non-null value: userService.genericDao"
將UserService中的@In修改為@In(create = true, required = true)解決此問(wèn)題。
解決上述幾個(gè)問(wèn)題后,自己的例子終于運(yùn)行起來(lái)了 :-)
下一篇關(guān)于Seam In Action中對(duì)JSF的介紹及Seam如何增強(qiáng)JSF。
-------------------------------------------------------------------------------------------------
項(xiàng)目生成的代碼被分為兩個(gè)目錄,分別為Action和Model目錄,檢查JBoss中項(xiàng)目部署的目錄,發(fā)覺(jué)Action目錄下的代碼編譯生成的class文件被存放至WEB-INF/dev目錄下,Model目錄下的代碼編譯生成的class文件被存放至WEB-INF/classes目錄下,google了一下,發(fā)現(xiàn)在Seam Reference中提到這是Seam的增量式重部署,支持對(duì)JavaBean組件的增量重部署,可以加快編輯/編譯/測(cè)試的速度。
代碼如下:
通過(guò)這個(gè)實(shí)踐,小結(jié)一下:
1、發(fā)覺(jué)Seam確實(shí)簡(jiǎn)化了JSF開(kāi)發(fā),但由于它涉及的新東西相對(duì)較多,與傳統(tǒng)的SSH走的路線不太一致,還是覺(jué)得其學(xué)習(xí)曲線比較陡峭,需要對(duì)Seam熟練掌握后(包括開(kāi)發(fā)環(huán)境的搭建等)才能真正提高開(kāi)發(fā)效率。
2、Seam提供了IOC的功能,有時(shí)需要跳出Spring,從一個(gè)新的角度去審視Seam。
這個(gè)星期的后半周主要搞了kettle的試驗(yàn),做了兩個(gè)例子出來(lái),在后續(xù)工作中這兩個(gè)例子應(yīng)該也能派上用場(chǎng),本來(lái)以為kettle的文檔不多,后來(lái)單獨(dú)下載了kettle的doc壓縮包,發(fā)覺(jué)里面的內(nèi)容還是不少的,真要將kettle搞熟的話,這些文檔還是需要仔細(xì)研讀一番的。另外kettle doc解壓后文檔目錄挺奇怪的,都是數(shù)字命名的目錄名,不知有啥具體含義。
下周的學(xué)習(xí)重點(diǎn)還是要轉(zhuǎn)回到JBoss Seam中了 :-)
需求:
kettletest1數(shù)據(jù)庫(kù)中有table_source數(shù)據(jù)表,結(jié)構(gòu)如下:
該表中的數(shù)據(jù)對(duì)于不同的實(shí)例ID,一分鐘一條數(shù)據(jù),t_id字段表示數(shù)據(jù)的時(shí)間,精確到分鐘。
kettletest2數(shù)據(jù)庫(kù)中有table_target數(shù)據(jù)表,結(jié)構(gòu)如下:
需定期將table_source表中的數(shù)據(jù)獲取至table_target表中,并進(jìn)行如下處理:
1、將t_id數(shù)據(jù)時(shí)間字段拆分為三個(gè)字段,分別為marketdate、pointtime、pointnumber。
a、marketdate取t_id的日期部分。
b、pointtime取t_id的時(shí)間部分。
c、pointnumber為時(shí)間的數(shù)字表示,等于hour*60+minute。
d、但當(dāng)t_id的時(shí)間為某日的00:00時(shí),需將其轉(zhuǎn)化為24:00,并且marketdate需取日期的前一天。如t_id為2008-12-04 00:00,則marketdate為2008-12-03,pointtime為24:00,pointnumber為1440。
2、將part_id字段映射為plantcode字段,并根據(jù)如下規(guī)則進(jìn)行轉(zhuǎn)換:
part_id plantcode
3206 P01
3207 P02
3208 P03
測(cè)試中使用的數(shù)據(jù)庫(kù)均為mysql數(shù)據(jù)庫(kù)。
實(shí)戰(zhàn):
整個(gè)轉(zhuǎn)換工作共分為三個(gè)步驟,如下圖:
1、定義需獲取的數(shù)據(jù)的日期
2、刪除table_target表中已有數(shù)據(jù),注意一定要將“執(zhí)行SQl語(yǔ)句”面板中的“變量替換”要選上,否則SQL語(yǔ)句中的變量不會(huì)被替換,我剛開(kāi)始沒(méi)注意到這個(gè)地方,找問(wèn)題找了半天。
3、獲取table_source中的數(shù)據(jù),并將其插入table_target表
3-1、獲取table_source表的數(shù)據(jù)
3-2、值映射
3-3、字段選擇
3-4、對(duì)t_id字段進(jìn)行處理,增加了pointnumber字段。在這一步驟中發(fā)現(xiàn)kettle的一個(gè)bug,就是不能在JavaScript中使用str2date函數(shù),錯(cuò)誤的具體信息參見(jiàn):http://jira.pentaho.com/browse/PDI-1827。這個(gè)問(wèn)題也折騰了好長(zhǎng)時(shí)間,剛開(kāi)始怎么也想不通這個(gè)函數(shù)使用時(shí)怎么會(huì)報(bào)錯(cuò)呢,后來(lái)只好從字符串中截取年、月、日信息。
該步驟中還存在另外一個(gè)使人困惑的問(wèn)題,就是點(diǎn)擊“測(cè)試腳本”按鈕,會(huì)報(bào)錯(cuò),但是執(zhí)行job和transformation時(shí)則不會(huì)報(bào)錯(cuò)。
3-5、增加pointnumber字段至輸出結(jié)果中
3-6、插入數(shù)據(jù)至table_target表
3-4步驟中的JavaScript代碼如下:
至此,整個(gè)轉(zhuǎn)換工作完成,小結(jié)一下:
如果對(duì)kettle等etl工具比較熟悉的話,使用etl工具進(jìn)行數(shù)據(jù)轉(zhuǎn)換、抽取等事情還是比較方便的,比起寫(xiě)程序還是有優(yōu)勢(shì)的。但是這個(gè)轉(zhuǎn)換過(guò)程中遇到的kettle的兩個(gè)bug比較讓人頭疼,覺(jué)得kettle好像還不是很穩(wěn)定。
這個(gè)實(shí)踐其實(shí)不難,主要是有一個(gè)地方要注意,就是文件名通配符的寫(xiě)法,如果文件名格式為“TRANS_yyyymmdd.txt”,如TRANS_20081101.txt。如果想匹配所有以TRANS開(kāi)頭的文本文件,在kettle中要寫(xiě)成這樣:TRANS_.*[0-9].txt。
最后在windows操作系統(tǒng)中配置定時(shí)任務(wù)就可以定期執(zhí)行該Job了。
Job的圖:
FTP配置信息:
一定要給SQL Server2000打上sp3a補(bǔ)丁,打上補(bǔ)丁后,使用telnet訪問(wèn)1433端口一切正常。
另外學(xué)了一個(gè)查詢SQL Server版本的語(yǔ)句:select @@version
DATE_FORMAT(date,format)
根據(jù)format字符串格式化date值。下列修飾符可以被用在format字符串中: %M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英語(yǔ)前綴的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 數(shù)字, 4 位
%y 年, 數(shù)字, 2 位
%a 縮寫(xiě)的星期名字(Sun……Sat)
%d 月份中的天數(shù), 數(shù)字(00……31)
%e 月份中的天數(shù), 數(shù)字(0……31)
%m 月, 數(shù)字(01……12)
%c 月, 數(shù)字(1……12)
%b 縮寫(xiě)的月份名字(Jan……Dec)
%j 一年中的天數(shù)(001……366)
%H 小時(shí)(00……23)
%k 小時(shí)(0……23)
%h 小時(shí)(01……12)
%I 小時(shí)(01……12)
%l 小時(shí)(1……12)
%i 分鐘, 數(shù)字(00……59)
%r 時(shí)間,12 小時(shí)(hh:mm:ss [AP]M)
%T 時(shí)間,24 小時(shí)(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一個(gè)星期中的天數(shù)(0=Sunday ……6=Saturday )
%U 星期(0……52), 這里星期天是星期的第一天
%u 星期(0……52), 這里星期一是星期的第一天
%% 一個(gè)文字“%”。
看了Seam的例子,也看了Seam的簡(jiǎn)介,禁不住手癢,還是先做一個(gè)例子吧,遵照《seam_reference》第三章中的指導(dǎo),使用JBossTool生成了自己的第一個(gè)例子,過(guò)程如下:
1、生成Sem web項(xiàng)目
2、輸入項(xiàng)目的相關(guān)信息,如下圖:
注意,如果是第一次使用Eclipse,需要配置Target Runtime和Target Server。
3、然后一路next,到最后一步時(shí),如果是第一次使用,也要注意配置Seam Runtime和Connection Profile,如下圖。最后點(diǎn)擊finish按鈕,即可創(chuàng)建Seam項(xiàng)目。
4、生成項(xiàng)目后,在Eclipse中共出現(xiàn)了四個(gè)項(xiàng)目,如下:
此時(shí)運(yùn)行JBossServer服務(wù)器,訪問(wèn)http://localhost:8080/seamfirst鏈接,出現(xiàn)如下圖頁(yè)面,此時(shí)Seam幫我們生成了一個(gè)框架,包含了基本的登錄和退出功能,還有一個(gè)首頁(yè)。
5、繼續(xù)!使用Seam生成單表的CRUD操作。本步驟前提,有一個(gè)mysql數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)中有一個(gè)Customer表,該表有ID(int類(lèi)型)、customername(varchar2類(lèi)型)、customerdesc(varchar2類(lèi)型)、createdate(date類(lèi)型)、email(varchar2類(lèi)型)五個(gè)字段。在seamfirst項(xiàng)目上點(diǎn)擊右鍵,選擇Seam Generate Entities菜單,彈出界面如下圖:
單擊finish按鈕后,再運(yùn)行JBoss Server服務(wù)器,訪問(wèn)http://localhost:8080/seamfirst,發(fā)覺(jué)菜單欄上多了一個(gè)Customer List菜單,單擊此鏈接,即可進(jìn)行Customer的添加、刪除、修改、查詢操作,雖然生成的界面不是很好看,也不是很符合我自己的操作習(xí)慣,但是功能倒是完備。
以后若是修改了Seam提供的代碼自動(dòng)生成的模板,然后再使用該功能,想必生成的頁(yè)面就符合自己的項(xiàng)目要求了,記下一筆,先不管它。
生成的代碼分析:
生成的代碼主要有兩部分,一部分為Java代碼,一部分為頁(yè)面代碼。
Java代碼包括如下三個(gè)類(lèi):
CustomerHome和CustomerList類(lèi)中都使用了@Name annotation,這樣在頁(yè)面中就可以直接訪問(wèn)Session Bean中的方法了,達(dá)到了Seam將表現(xiàn)層和業(yè)務(wù)層直接融合的目標(biāo)。
頁(yè)面代碼包括如下文件:
剛開(kāi)始看這段代碼時(shí),困惑我的有兩個(gè)地方
至此第一個(gè)使用JBossTools生成的Seam例子完成了,好像很簡(jiǎn)單 :-)
需求:Oracle的數(shù)據(jù)庫(kù)文件都存放在C盤(pán),由于數(shù)據(jù)文件越來(lái)越大,所以想把一些數(shù)據(jù)文件移至D盤(pán)
環(huán)境:Oracle9i
操作步驟:
注意點(diǎn):
附Oracle的幾種啟動(dòng)方式
1、startup nomount
非安裝啟動(dòng),這種方式啟動(dòng)下可執(zhí)行:重建控制文件、重建數(shù)據(jù)庫(kù)。
讀取init.ora文件,啟動(dòng)instance,即啟動(dòng)SGA和后臺(tái)進(jìn)程,這種啟動(dòng)只需要init.ora文件。
2、startup mount dbname
安裝啟動(dòng),這種方式啟動(dòng)下可執(zhí)行:數(shù)據(jù)庫(kù)日志歸檔、數(shù)據(jù)庫(kù)介質(zhì)恢復(fù)、使數(shù)據(jù)文件聯(lián)機(jī)或脫機(jī)、重新定位數(shù)據(jù)文件、重做日志文件。
執(zhí)行“nomount”,然后打開(kāi)控制文件,確認(rèn)數(shù)據(jù)文件和聯(lián)機(jī)日志文件的位置,但此時(shí)不對(duì)數(shù)據(jù)文件和日志文件進(jìn)行校驗(yàn)檢查。
3、startup open dbname
先執(zhí)行“nomount”,然后執(zhí)行“mount”,再打開(kāi)包括Redo log文件在內(nèi)的所有數(shù)據(jù)庫(kù)文件,這種方式下可訪問(wèn)數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
4、startup,等于以下三個(gè)命令
startup nomount
alter database mount
alter database open
用JBossTools生成項(xiàng)目,生成CRUD的代碼,然后訪問(wèn)就報(bào)了如下異常:
Exception during request processing:
Caused by java.lang.IllegalStateException with message: "No phase id bound to current thread (make sure you do not have two SeamPhaseListener instances installed)"
org.jboss.seam.contexts.PageContext.getPhaseId(PageContext.java:163) org.jboss.seam.contexts.PageContext.isBeforeInvokeApplicationPhase(PageContext.java:175) org.jboss.seam.contexts.PageContext.getCurrentWritableMap(PageContext.java:91) org.jboss.seam.contexts.PageContext.remove(PageContext.java:105) org.jboss.seam.Component.newInstance(Component.java:2102) org.jboss.seam.Component.getInstance(Component.java:1987) org.jboss.seam.Component.getInstance(Component.java:1966) org.jboss.seam.Component.getInstance(Component.java:1960) org.jboss.seam.Component.getInstance(Component.java:1933) org.jboss.seam.Component.getInstance(Component.java:1928) org.jboss.seam.faces.FacesPage.instance(FacesPage.java:92) org.jboss.seam.core.ConversationPropagation.restorePageContextConversationId(ConversationPropagation.java:84) org.jboss.seam.core.ConversationPropagation.restoreConversationId(ConversationPropagation.java:57) org.jboss.seam.jsf.SeamPhaseListener.afterRestoreView(SeamPhaseListener.java:389) org.jboss.seam.jsf.SeamPhaseListener.afterServletPhase(SeamPhaseListener.java:228) org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:194) com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:175) com.sun.faces.lifecycle.Phase.doPhase(Phase.java:114) com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104) com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) javax.faces.webapp.FacesServlet.service(FacesServlet.java:265) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:38) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177) org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267) org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380) org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507) org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:54) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432) org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157) org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262) org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446) java.lang.Thread.run(Thread.java:619)
Google了一下,有人講是JBoss4.2.3GA版本的BUG,趕緊下載了JBoss4.2.2GA,再測(cè)試一切正常!
不知還會(huì)不會(huì)有其它莫名的BUG了......
把環(huán)境配好之后,Seam的例子也運(yùn)行起來(lái)了,看了seam_reference第一章中如下幾個(gè)例子講解:
又在滿江紅的網(wǎng)站上找了seam_reference2.0的中文文檔,主要看了《the contextual component model》一章,看完以后感覺(jué)Seam最核心的地方就是其contextual component model了,不過(guò)看完這一章以后只是對(duì)Seam有個(gè)大概的了解,對(duì)其具體的內(nèi)容,細(xì)節(jié)還缺乏進(jìn)一步的了解,對(duì)其優(yōu)點(diǎn)、缺點(diǎn)也缺乏進(jìn)一步的認(rèn)識(shí)。
然后又找到了《Seam in Action》的電子書(shū),看了一點(diǎn)之后還是覺(jué)得這本電子書(shū)寫(xiě)得好,內(nèi)容組織的很好,不象seam_reference后面的章節(jié)僅僅是羅列seam的各項(xiàng)功能。
今天把Seam in Action的第一章草草看了一遍,將第一章講述的內(nèi)容總結(jié)如下:
1、什么是Seam
在Seam in Action中,沒(méi)有將Seam稱之為web framework,而是將其稱為application stack。Seam將Java EE中的EJB3、JSF、JPA/Hibernate、JAAS等技術(shù)融合在一起,提供了更容易使用的方式,比如conversation、page flows、buisness precesses、rule-based security、JavaScript(Ajax) remoting、PDF rendering、email組合、charting、file uploads、Groovy integration等,用以簡(jiǎn)化web開(kāi)發(fā)。
2、Seam的目標(biāo)
簡(jiǎn)化web開(kāi)發(fā)
3、Seam如何集成各類(lèi)技術(shù)
在Seam中將EJB3.0中的Session Bean作為JSF的managed bean,直接將表現(xiàn)層和業(yè)務(wù)層銜接在一起,使得Session Bean可以直接訪問(wèn)web相關(guān)數(shù)據(jù),比如request、session、application、JSF的FacesMessage、Component Tree等。而在不使用Seam時(shí),一般都是使用JSF back bean來(lái)作為表現(xiàn)層和業(yè)務(wù)層之間的中介。
使用annotation中的@Name標(biāo)注替代了JSF的faces-config.xml中關(guān)于managed bean的配置。
Seam提供了7種類(lèi)型的上下文,其中屬于Seam特有的兩種上下文類(lèi)型分別為:Conversation Context、Business process Context。
Seam提供了統(tǒng)一的組件注冊(cè)、annotation、異常配置、方法攔截、統(tǒng)一的EL表達(dá)式等功能。其中Seam對(duì)其管理的組件攔截過(guò)程如下圖:
4、Seam的核心競(jìng)爭(zhēng)力
- Seam對(duì)JSF最被認(rèn)可的改進(jìn)就是消除了在配置文件中聲明managed bean。
- Prerender page actions
- Managed request parameters (for a given page)
- Intelligent stateless and stateful navigation
- Transparent JSF data model and data model selection handling
- Fine-grained exception handling
- Page-level security (per view ID)
- 基于Annotation的表單驗(yàn)證
- Bookmarkable command links (solving the “everything is a POST” problem)
- Entity converter for pick lists
- Conversation controls
- Support for preventing lazy initialization exceptions and nontransactional data access in the view
用一幅圖可以很好的說(shuō)明這句話的含義
引入了有狀態(tài)的變量范圍(INTRODUCING STATEFUL VARIABLE SCOPES)
Spring中提供了The Session In View Filter,使得persistence manage可以在一個(gè)請(qǐng)求中存在,避免了常見(jiàn)的LazyInitializationException。在Seam中,擴(kuò)展的Persistence Context可以跨越多個(gè)請(qǐng)求。其實(shí)擴(kuò)展的Persistence Context是Conversation Context、Business Process Context的基礎(chǔ)。
Seam提供了兩種方式將Ajax集成到Seam應(yīng)用中,一種是使用具有Ajax特性的JSF組件,如RichFaces和ICEFaces,另一種是可以在瀏覽器中使用JavaScript直接調(diào)用服務(wù)端的組件。
Seam還提供了另外一種意義上的Rich,即將PDF、mail等功能集成到Seam應(yīng)用中。
提供了一個(gè)快速開(kāi)發(fā)環(huán)境
從目前我個(gè)人的理解來(lái)看,Seam的作用與能力如下:
但由于Seam整合了如此多的框架,帶來(lái)的一個(gè)最大的缺點(diǎn):學(xué)習(xí)曲線陡峭,在SSH非常流行的今天,需要面對(duì)很多新技術(shù)(JSF、EJB3、JPA等),對(duì)于一個(gè)新手來(lái)說(shuō)難度比較大,如果想使Seam被更多的開(kāi)發(fā)人員使用,必須加強(qiáng)它的文檔,目前的文檔還是太少了。
今天早上在網(wǎng)上看到了kettle發(fā)布了最新的版本,忽然想起最近其實(shí)做了不少工作應(yīng)該是ETL工具的拿手好戲,趕緊下載下來(lái)看看,看是否能夠在實(shí)際的工作中應(yīng)用起來(lái)。
順便講一下,為啥看到kettle會(huì)兩眼發(fā)光。
最近寫(xiě)了好幾個(gè)小程序,用于從一個(gè)ftp去獲取數(shù)據(jù),然后轉(zhuǎn)發(fā)至另一個(gè)ftp去,或者是從一個(gè)數(shù)據(jù)庫(kù)獲取數(shù)據(jù)然后保存至本地的數(shù)據(jù)庫(kù)中,使用的是jdk中的Timer實(shí)現(xiàn)的定時(shí)調(diào)度,本來(lái)也沒(méi)什么問(wèn)題,連續(xù)運(yùn)行幾個(gè)月都不會(huì)出錯(cuò)。
可是最近網(wǎng)絡(luò)不是太好,周期性抽風(fēng),ping包時(shí),每5分鐘大概會(huì)丟7-8個(gè)包,從而導(dǎo)致程序也會(huì)假死,過(guò)一段時(shí)間后就不正常干活了,估計(jì)是因?yàn)橛昧藬?shù)據(jù)庫(kù)連接池的問(wèn)題,要是每次發(fā)起數(shù)據(jù)庫(kù)連接可能就不會(huì)有問(wèn)題了,偷懶也不想改了,因?yàn)榫W(wǎng)絡(luò)最終肯定是會(huì)修好的 :-) 但是想試試ETL工具,因?yàn)楹竺孢€有一些類(lèi)似的東西要處理,不想寫(xiě)代碼了,用別人的輪子感覺(jué)比較好,呵呵
首先下載了kettle的最新版,kettle3.1,解壓后即可運(yùn)行,一般的開(kāi)發(fā)人員稍微摸索一下,看看例子簡(jiǎn)單的轉(zhuǎn)換還是會(huì)做的,今天小試了一把,有幾個(gè)注意點(diǎn)記下來(lái)。
在一開(kāi)始使用命令行方式執(zhí)行job時(shí),總是報(bào)如下的錯(cuò)誤,琢磨了好長(zhǎng)時(shí)間總算整明白正確的方式了。
Unexpected error during transformation metadata load
No repository defined!
下一步準(zhǔn)備按照實(shí)際情況定制Job,做好了再寫(xiě)小結(jié)。
JBoss Envers目的是根據(jù)對(duì)實(shí)體的設(shè)置,提供記錄執(zhí)行數(shù)據(jù)變更歷史的功能(數(shù)據(jù)變更版本)。Envers的配置非常簡(jiǎn)單,如果需要對(duì)某個(gè)實(shí)例進(jìn)行歷史數(shù)據(jù)版本記錄,只需要在實(shí)例上配置@Versioned annotation即可。針對(duì)每個(gè)實(shí)體的版本的歷史數(shù)據(jù),Envers都會(huì)創(chuàng)建一個(gè)單獨(dú)的數(shù)據(jù)表進(jìn)行存儲(chǔ)。
目前Envers支持Hibernate和Hibernate-entitymanager(JPA實(shí)現(xiàn)).
這個(gè)特點(diǎn)在需要對(duì)歷史數(shù)據(jù)進(jìn)行存檔時(shí)很實(shí)用,而且目前Envers已經(jīng)合并到Hibernate的新版本中去了,使用起來(lái)更方便,具體Hibernate哪個(gè)不太清楚。
留個(gè)印記..............
準(zhǔn)備深入學(xué)習(xí)JBossSeam,好好研究研究,具體學(xué)習(xí)路線基本遵循jboss-seam-2.1.1.CR1中的<<seam_reference.pdf>>。
學(xué)習(xí)JBossSeam之前最好對(duì)相關(guān)技術(shù)有一定的了解,比如:
然后下載相關(guān)的軟件,如下:
環(huán)境的配置都比較簡(jiǎn)單,基本都是解壓即可,有如下注意事項(xiàng):
上述配置好后,啟動(dòng)JBoss Server,然后至SEAM_HOME(假定為Seam的安裝目錄)/examples/registration目錄下,運(yùn)行ant explode命令,即可編譯部署registration應(yīng)用至JBoss Server中,最后訪問(wèn):http://localhost:8080/seam-registration 即可體驗(yàn)Seam提供的第一個(gè)example程序 :-)
考核系統(tǒng)快結(jié)束了,將此項(xiàng)目的經(jīng)歷回憶如下,也小結(jié)一下,先談這個(gè)項(xiàng)目中值得提倡的地方:
1、在開(kāi)發(fā)之前進(jìn)行了完整的需求分析,形成了系統(tǒng)的需求文檔,需求文檔中最有用的部分感覺(jué)就是界面原型,還有系統(tǒng)的菜單,這樣給了用戶一個(gè)初步的直觀的印象,同時(shí)文檔中的一些對(duì)于界面原型的描述以及計(jì)算規(guī)則等內(nèi)容在后期的開(kāi)發(fā)中也起了指導(dǎo)作用。
2、在需求分析完成之后,進(jìn)行了概要設(shè)計(jì),包括完整的數(shù)據(jù)庫(kù)設(shè)計(jì),這樣在后期的開(kāi)發(fā)中對(duì)數(shù)據(jù)庫(kù)表結(jié)構(gòu)方面沒(méi)有大的修改了,只是添加了一些表和視圖。
再談?wù)?font color="#0080ff">項(xiàng)目中的缺點(diǎn)吧:
1、首先就說(shuō)說(shuō)需求文檔,雖說(shuō)需求文檔寫(xiě)了很多,大概有100頁(yè)左右(word),但由于一篇文檔中集中的內(nèi)容太多,對(duì)于用戶來(lái)說(shuō)只是關(guān)注了界面原型,系統(tǒng)菜單等部分,對(duì)于其它內(nèi)容用戶關(guān)注度不高;同時(shí)由于篇幅太大,開(kāi)發(fā)人員打開(kāi)查看或者后續(xù)修改也比較麻煩。
對(duì)于以后的需求文檔是否可以這樣編寫(xiě):首先有一個(gè)正文,正文中包括大綱,然后將每一個(gè)具體的需求放在單獨(dú)的一個(gè)文檔中,最好能類(lèi)似html鏈接那樣,這樣查看也方便,也一目了然。
原來(lái)用RobotHelp寫(xiě)過(guò)幫助,照此看來(lái),豈不可以用來(lái)寫(xiě)需求文檔了,呵呵
2、再說(shuō)數(shù)據(jù)庫(kù)設(shè)計(jì),還不夠細(xì)致,很多應(yīng)用場(chǎng)景由于設(shè)計(jì)的不夠細(xì)致,導(dǎo)致數(shù)據(jù)庫(kù)表也有所欠缺,因此對(duì)于以后的項(xiàng)目設(shè)計(jì)有兩個(gè)注意點(diǎn):
a、加強(qiáng)應(yīng)用場(chǎng)景設(shè)計(jì),具體可以用流程圖,甚至序列圖描述清晰的業(yè)務(wù)流程,完善數(shù)據(jù)庫(kù)表設(shè)計(jì)。
b、要求一定先修改模型(這里指PowerDesigner中的數(shù)據(jù)庫(kù)設(shè)計(jì)),然后再去修改POJO類(lèi)等具體代碼,最好不要先改代碼,再修改模型,這樣難免會(huì)有遺漏,時(shí)間久了,就會(huì)導(dǎo)致模型和代碼的不一致,慢慢的,模型文檔就沒(méi)有人看,也沒(méi)有人維護(hù)了。
c、順便提一下,模型文檔的好處一是方便后來(lái)者,二是可以方便的導(dǎo)出數(shù)據(jù)字典。
3、對(duì)于命名規(guī)范沒(méi)有在開(kāi)發(fā)前考慮全面,雖然在開(kāi)發(fā)前對(duì)命名規(guī)范有一定的規(guī)定,但是不夠全面,造成了后期開(kāi)發(fā)中各人各人的命名有所偏差。
4、分層架構(gòu)中的dao層和service層處理的不夠好,導(dǎo)致service層實(shí)際上是混雜了dao和service的功能,業(yè)務(wù)代碼不夠清晰。以后的項(xiàng)目考慮dao就是dao,提供數(shù)據(jù)訪問(wèn)的操作,service層則提供業(yè)務(wù)處理方法,service與dao的關(guān)系應(yīng)該是多對(duì)多的關(guān)系。
5、考核系統(tǒng)中使用了JSF/Richfaces做為表現(xiàn)層,好像不太好使,經(jīng)常會(huì)出現(xiàn)多次重復(fù)訪問(wèn)方法的問(wèn)題,后續(xù)還需要加強(qiáng)對(duì)JSF的學(xué)習(xí),避免類(lèi)似問(wèn)題。另外Richfaces在生成大數(shù)據(jù)量的頁(yè)面時(shí),一個(gè)表格有1440行數(shù)據(jù),頁(yè)面巨慢無(wú)比:(,后來(lái)沒(méi)有使用RichaFaces的表格,直接使用jstl+html標(biāo)簽,速度倒是很快。
6、項(xiàng)目中的日志輸出、異常處理不夠明晰,這個(gè)和命名規(guī)范一樣應(yīng)該在項(xiàng)目開(kāi)始時(shí)給出清晰的思路,在具體開(kāi)發(fā)中應(yīng)該經(jīng)常檢查。
具體內(nèi)容參見(jiàn)如下鏈接:
http://www.javaworld.com.tw/roller/ingramchen/entry/2005_9_20_JBossSeamKingofStateful_
今天在http://refcardz.dzone.com/上下載了《Getting Started with Hibernate Search》,乍一看標(biāo)題,以為是講如何使用Hibernate進(jìn)行查詢操作什么的,下載好以后打開(kāi)一看,原來(lái)是Hibernate集成了lucene,用來(lái)對(duì)自己的數(shù)據(jù)庫(kù)進(jìn)行全文檢索,真是厲害!
沒(méi)有仔細(xì)研究具體內(nèi)容,先記下一筆,日后有時(shí)間時(shí),可以實(shí)踐一把。
Template設(shè)計(jì)模式主要適用于需要按一定的步驟執(zhí)行的場(chǎng)合,但有的步驟在不同的場(chǎng)合執(zhí)行的內(nèi)容有不相同。如下類(lèi)圖中的TemplateClass中的execute()方法會(huì)按照如下的順序進(jìn)行調(diào)用:
public void execute() {
step1();
step2();
}
但由于step1在不同的場(chǎng)合執(zhí)行的內(nèi)容不一樣,此時(shí)就將step1設(shè)為抽象方法,在TemplateConcreteClass1和TemplateConcreteClass2中分別實(shí)現(xiàn),這樣就形成了Template設(shè)計(jì)模式,step1()方法也稱為模板方式。
類(lèi)圖如下:
1、在菜單中選擇“Weblog”,然后選擇“Another Weblog Service”。
2、在Weblog Homepage URL中輸入你的Blog主頁(yè)地址。
3、輸入用戶名與密碼。
4、在“Type of weblog that you are using”中選擇“Custom(Metaweblog API)”。
5、“Remote posting URL for your weblog”中輸入“http://www.cnblogs.com/用戶名/services/metaweblog.aspx”。