來源:http://www.jdon.com/artichect/whyEJB.htm
首先,我們必須明確,為什么要使用J2EE?J2EE優(yōu)點是什么?使用J2EE的主要原因是多層結構,傳統的兩層C/S結構難于維護,穩(wěn)定性極差,界面代碼和數據庫代碼混淆在一起,牽一動百,多層結構使得界面和數據庫完全分離,并且誕生了中間件這樣的技術,如下圖:
為什么使用EJB我原先認為這不是一個討論的話題,因為EJB是J2EE重要的組成部分,可以說沒有EJB的J2EE只是一種Web系統,這樣的系統非常容易喪失了多層結構的大部分優(yōu)點(仔細想想那些混合多種層次功能JavaBeans和傳統兩層結構有什么區(qū)別?)。
當然,可以人為地在Javabeans之間進行層次劃分,例如Hibernate算數據持久層,某些JavaBeans是業(yè)務核心層,但是因為都是普通JavaBeans,這種劃分沒有一種強制性和明顯標志性,這樣的系統更換了主創(chuàng)人員或設計師,可能就會被新的程序員修改得非常混亂。
我們先看看一個包含EJB的J2EE系統是如何清晰地表達層次。如下圖:
Web完全只是一個MVC模式的實現,關鍵業(yè)務核心是在EJB的服務層實現,這樣做的優(yōu)點是,Web只負責界面相關部分,因為,如果是一個智能客戶端,如Swing或J2ME,在不需要修改任何業(yè)務核心的情況下能夠方便地更換。同樣,提供Web Services功能,也只是在 Web層修改,不會涉及EJB方面的修改,同樣保證了系統的穩(wěn)定性,保證了系統升級和未來的擴展性。
如果不使用EJB,在EJB服務層實現的業(yè)務核心將由普通JavaBeans實現,使用何種架構或設計能夠保證負責MVC的JavaBeans和負責業(yè)務核心的JavaBeans清晰地分開,又如何保證在新的程序員不會破壞和打亂你精心布局的JavaBeans架構?
最主要的是性能問題,由于以前國內中文Java網站有些人彎曲EJB,認為EJB性能低,其實這是一種非常膚淺錯誤的認識,我們首先看看在一般Java環(huán)境中是如何提高性能。
假定一個JavaBeans為A,那么一般使用這個JavaBeans命令如下:
A a = new A();
但是,在高訪問量的環(huán)境中,new A()其實是很費時消耗系統性能的,因此,能不能在軟件系統啟動時候就預先建立一些對象,這樣,系統運行時,從這些已經生成的對象池中借用一個,這樣,就無需在使用時進行New,節(jié)約了開銷,提高了性能,因此,真正成熟性能解決方案都是需要對象池等支持。
在一個純Web結構的系統(也就是只能運行在Tomat環(huán)境中),例如Struts + Hibernate等這樣的系統,除非自己動手做,一般是沒有對象池技術支持的,因此他們的性能只能算是Demo演示版本的性能,根本無法承受大容量并發(fā)訪問,也無法稱為一個成熟的系統,所以,我們研究成熟的開源Web系統,如Jive、OFBize,LifeRay等,他們都在Web層擁有自己的對象池和緩存池。
對象池和緩存機制是J2EE必須的嗎?當然,是所有成熟系統必須的,Windows系統如果去掉緩存將會變得怎樣?
自己動手開發(fā)對象池和緩存機制并不是一件簡單的事情,需要對多線程以及同步鎖等底層原理有深層次的把握,這其實也是一門非常深入的Java研究分支,所以,你可以拋開你的客戶焦急的催促,精心研究開發(fā)自己的對象池和緩存池。
但是,EJB容器(如JBoss)已經提供了對象池和緩存機制,所以,沒有事務機制的無狀態(tài)Session Bean的性能肯定要強于普通JavaBeans。EJB容器不但在單機中提供了對象池和緩存,而且可以跨服務器實現動態(tài)負載平衡,這些都無需開發(fā)者自己開發(fā)任何軟件代碼,結構如下:
每一個jar包代表一個EJB組件,一個系統可以由多個可重用的EJB組件構成,例如:樹形結構EJB組件;自增序號EJB組件;用戶資料EJB組件等,這樣的EJB組件可以象積木一樣搭配在大部分應用系統中,提高了系統的開發(fā)效率,保證了開發(fā)質量。
下圖是某個新的具體系統時應用到的EJB組件圖,在這個新的應用中,由于使用了以前大量可重用的EJB組件,新的開發(fā)工作基本集中在界面設計和流程安排上:
事務機制對于一些關鍵事務是很重要的,例如ATM機提款,提款有多個動作:修改數據庫以及數錢等,如果這其中有任何一個環(huán)節(jié)出錯,那么其它已經實現的操作必須還原,否則,就會出現,提款人沒有拿到錢,但是卡上已經扣款等不可思議的事情發(fā)生。
EJB提供的事務機制非常周全,但事務機制帶來的缺點是性能的降低,因此,有些人認為EJB很重,因為在實際應用中,有的用戶系統可能不需要事務機制,只是需要EJB提供的性能優(yōu)化機制,這樣,如果使用EJB,就象叫一個人來背東西,他除了背著我要的東西外,還背著我不要的東西。
除非你是一個完美主義,在一般企業(yè)應用或數據庫系統應用中,EJB不會對你構成很重的包袱。
開源以及一些數據庫持久層技術崇拜者,一直抨擊CMP,認為CMP慢無用,實際最大的問題是他們的設計和使用問題。
由于EJB容器(如JBoss)對CMP實現有事務機制的緩存優(yōu)化,因此,CMP特別適合多個用戶同時更新同一個數據源的情況,CMP這種嚴格的事務完整性保證多個用戶同時操作一個數據記錄時,能夠保證性能優(yōu)化和數據的完整性,如果這個數據記錄是是軟件系統的狀態(tài)標志,它的狀態(tài)會影響系統中很多的環(huán)節(jié),那么狀態(tài)更改的重要性不言而喻。
如果沒有事務完整性支持,你的軟件系統在用戶訪問量變大,就會變得發(fā)生各種不可能發(fā)生的邏輯錯誤,查看程序邏輯是正確的,那么問題出在哪里?出在數據完整性上。
由于每個CMP在內存中都有一個緩存,在實際應用中,如果使用CMP批量讀數據庫數據,幾萬條查詢完畢,內存中充滿了幾萬條CMP緩存,如果這時你的EJB容器設置不當(如使用JBoss缺省配置),那么JVM的垃圾回收機制就會頻繁啟動,導致你的系統變慢甚至死機,這也是一些人抨擊CMP慢的原因所在,其實他們使用方法不當,或者沒有正確配置EJB容器CMP緩存。
對于這種情況,根據J2EE核心模式,推薦使用DAO+JDBC方式。
除非你對設計模式非常精深,能夠將自己系統中的JavaBeans使用模式或某種框架進行固定分層,同時,你孜孜不倦研發(fā)出對象池,又熟練于JTA等事務機制,你可以選擇沒有EJB的純Web結構,就象Jive、OFBiz那樣。當然還有一個前提,老板不懂或者非常有挑戰(zhàn)性(做與IBM SUN 微軟齊名的公司和技術)。
不要再被TSS那些狂熱的開源先生誤導,他們有時間有保障可以做他們喜歡的事情,作為專業(yè)的J2EE程序員,按照J2EE標準去學習去行動,也不要認為,只要使用了J2EE其中某個技術如Jsp或JavaBeans就心安理得認為自己的系統是J2EE了。
當然,我并不是說純Web系統不能實現多層結構,但是至少在很多方面沒有Web+EJB結構完善和清晰,所以,EJB不是J2EE可以忽視的部分,而是主要的重要的部分,重要業(yè)務功能核心都封裝在EJB中,相反Web層是一種次要的、和界面相關的層次。
補充:什么情況下不需要EJB,在SUN的SECA架構師試卷中回答:小型系統和不需要事務。另外過去那種認為“EJB有性能問題”根本是一種繆誤,具體可參考下面有關問題。
網絡上、書店都提供了很多資料,很多方式都可以得到J2EE方面的資料。如何系統的、高效的學習J2EE這個問題擺在我們面前。比如,有些人在看完一大堆書后,動起手來時還是不知道怎么開始。等等這些問題是我們最難處理的。如何尋找到一條很好的方式方法呢?
?
其實,換一個角度來看,比如,學英語,一共有三個層面的東西,首先是詞匯,然后是語法,再者是習慣用法(希望讀者能夠從程序設計的角度考慮問題,看看這兩者有什么相似之處,其實他們的邏輯是一樣的)。還比如,上數學課,老師在黑板上解題,大家都很輕松得聽懂,自己動手時就會有很多問題。這些看來很簡單的問題,其實都包含一個道理:理論聯系實際,理論指導實踐。
我們的理論在于,我們要有很好的方法。有些人看了很多書,寫了不少程序,水平還是提高得很慢,很難跨越這道難關。還是方法問題。當然,我所談論的方法,是自己的心得,體會,大家都有自己很獨特的方法。沒有絕對好、絕對壞的方法,看作用對象是誰。所以這里我們重點看看我這文章中所會提出來的方法。大家來評論評論。
上一篇文中《走向J2EE,漫長的道路》,我談到學習J2EE是一個漫長的過程,對,就是如此。因為她里面包含了很多全新的東西。而且,J2EE是現在進行時。我們知道J2EE由很多技術構成,比如,EJB、XML、JDBC、RMI、JSP、Servlet等等這些,又包含很多內容。無論這些具體的技術會怎么發(fā)展,怎么變化,我們要抓住主線,那就是掌握J2EE構架的精髓。用什么來分析呢,作用對象自然是J2EE Specification(最新版是1.4,http://java.sun.com/j2ee )!!!當然學習J2EE的前提是你對J2SE有了足夠的熟悉了,還有一點,你有很好的態(tài)度和興趣。只看J2EE規(guī)范是不夠的,最好結合產品和例子去思考,我建議大家用JBuilder 7 +BEA WebLogc Platform 7.0,這種開發(fā)模式。為什么這么說呢?首先,JBuilder 7本身的功能就是不錯,應該屬于主流Java IDE了。其次,BEA WebLogic Platform 7.0對J2EE Specification最新版支持程度很好,同時也較容易獲取,用的人也多。第三,開發(fā)效率不錯。(Borland網站有一份講述JBuilder 7 + BEA WebLogic 7.0集成開發(fā)的文檔,PDF格式。)
JBuilder 7本身提供了很多幫助文檔,有PDF格式,也有HTML格式(采用JavaHelp技術制作的),另外書店有一些JBuilder的參考用書,個人認為沒有必要,第一,提供的版本都比較陳舊;第二,沒有什么內容;第三,一般都是抄襲JBuilder 本身提供的幫助文檔。(個人觀點,沒有任何商業(yè)目的)。當然,你的外語差不多要有四級水平,這個可不能沒有,至少閱讀能力不錯(其實也不是這樣的,我最開始時也是害怕,但開始投入后,英語資料也很簡單,而且很地道!同時提高了您的外語)。WebLogic同樣也不錯,也提供了很多文檔,http://www.bestdown.com 上有一本WebLogic Bible(針對6.1版),國內的BEA公司好像也出了一本,有興趣地可以去china pub看看。
有了這兩者,我們需要找出合適的對象來學習。在這里給出幾方面的素材給大家提供參考。
第一,在JBuilder 7的安裝目錄的這個地方,~~:\JBuilder7\samples\Ejb\Ejb20\ESiteWL,有一個很好的例子,ESite。其中用到了Session Fa?ade設計模式,用到了JSP、Servlet、Session Beans、Entity Beans(cmp)等技術,學習過程中不懂得地方可以參考第二。
第二, Sun公司提供的J2EE Tutorial資料,很不錯。
第三,Java Pet Store,剛開始學習J2EE技術分析該例子有點困難,再者這個例子中的J2EE構架不是很實用,但她給我們展示了J2EE幾乎所有的核心技術,同時還提供了一本書,Design Enterprise Applications with J2EE Platform,很不錯。
第四,對J2EE構架比較了解,對EJB,XML,JSP,Servlet等技術有了較好的理解和程序經驗后,建議看看這幾本書:《J2EE In Practice》、《Core J2EE Patterns》、《Sun Certified ENT Architect for J2EE - Tech Study Guide》、《Java Tools for Extreme Programming - wiley》、《EJB Design Patterns》、《MasteringEJB 2》、《Enterprise JavaBeans,3rd》,夠你看得了:)。
有了上述基礎,結合大家做項目中的一些經驗,我想水平應該會有不少提高。在初步掌握上述基礎后,我們每個人都可以有自己在J2EE中的定位,比如有些開發(fā)人員可以考慮把時間花在商務邏輯層、另外一些喜歡花功夫在表示層,更有貪婪的家伙花在J2EE中所有的層。還有Web Services(J2EE 1.4 Specification的重點,估計2003年初推出,今后的重要發(fā)展方向)。
同時,大家要注意從軟件工程的角度考慮系統設計,實施,建議用用Together!!!要求大家對UML有足夠的了解。
Struts安裝配置
1、Struts的安裝比較簡單,下面的以Tomcat 4.1.24為例,講述安裝過程。 首先請到http://jakarta.apache.org/Struts下載Struts,建議使用release版,現在最高版本為1.1,下載后得到的是一個ZIP文件。 將ZIP包解開,可以看到這個目錄:lib和webapps,webapps下有一些WAR文件。 假設你的Tomcat裝在c:\Tomcat下,則將那些WAR文件拷貝到C:\Tomcat\webapps,重新啟動Tomcat即可。 打開瀏覽器,在地址欄中輸入:http://localhost:8080/Struts-example/index.jsp,若能見到“powered by Struts”的深藍色圖標,即說明成功了。這是Struts自帶的一個例子,附有詳細的說明文檔,可以做為初學者的入門教程。 另外,Struts還提供了一系統實用對象:XML處理、通過Java reflection APIs自動處理JavaBeans屬性、國際化的提示和消息等
2、關于Struts配置,由于我是采用Jbuilder9為開發(fā)工具,這里主要說一下Struts在Jbuilder中配置:Jbuilder本身自帶已經集成了Struts1.0,但目前的開發(fā)大部分都是在Struts1.1下,所以下面就介紹Struts1.1在Jbuilder中的配置:
1、下載 jakarta-struts-1.1.zip 包;jakarta-struts-1.1-src.zip包
2、將jakarta-struts-1.1.zip包解壓到C:\JBuilder9\thirdparty目錄下 jakarta-struts-1.1-src.zip包解壓到C:\JBuilder9\extras目錄下
3、啟動jbuilder9
4、配置Library (1)選擇菜單 tools\Configure Libraries (2)新建一個Library (3)在New Library Wizard對話框中, Name 輸入:struts1.1, location可選:User Home, Library paths:add加入C:\JBuilder9\thirdparty\jakarta-struts-1.1\lib\struts.jar (4)確定創(chuàng)建Library (5)選中struts1.1,修改Library Settings Class:C:\JBuilder9\thirdparty\jakarta-struts-1.1\lib\struts.jar Source:C:\JBuilder9\extras\jakarta-struts-1.1-src\src\share DocumentationC:\JBuilder9\thirdparty\jakarta-struts-1.1\webapps\struts-documentation.war\api Required Library:空 Framework:在Framework下拉框中,選擇struts,會自動出現6個taglib。 struts-bean struts-html struts-logic struts-template struts-tiles struts-nested (6)點擊OK,創(chuàng)建Library成功。
關于在其他工具上的配置,如Eclipse 網上有很多資料。
??? 3G的技術標準
??? 國際電信聯盟(ITU )在2000年5 月確定W —CDMA、CDMA2000和TDS —CDMA
三大主流無線接口標準,寫入3G技術指導性文件《2000年國際移動通訊計劃》
(簡稱IMT —2000)。
??? W —CDMA
??? 即WidebandCDMA,也稱為CDMADirectSpread,意為寬頻分碼多重存取,其支
持者主要是以GSM 系統為主的歐洲廠商,日本公司也或多或少參與其中,包括歐
美的愛立信、阿爾卡特、*** 、朗訊、北電,以及日本的NTT 、富士通、夏普等
廠商。這套系統能夠架設在現有的GSM 網絡上,對于系統提供商而言可以較輕易
地過渡,而GSM 系統相當普及的亞洲對這套新技術的接受度預料會相當高。因此
W —CDMA具有先天的市場優(yōu)勢。
??? CDMA2000
??? CDMA2000也稱為CDMAMulti —Carrier ,由美國高通北美公司為主導提出,
摩托羅拉、Lucent和后來加入的韓國*** 都有參與,韓國現在成為該標準的主導
者。這套系統是從窄頻CDMAOne 數字標準衍生出來的,可以從原有的CDMAOne 結
構直接升級到3G,建設成本低廉。但目前使用CDMA的地區(qū)只有日、韓和北美,所
以CDMA2000的支持者不如W —CDMA多。不過CDMA2000的研發(fā)技術卻是目前各標準
中進度最快的,許多3G手機已經率先面世。
??? TD—SCDMA
??? 該標準是由中國大陸獨自制定的3G標準,1999年6 月29日,中國原郵電部電
信科學技術研究院(大唐電信)向ITU 提出。該標準將智能無線、同步CDMA和軟
件無線電等當今國際領先技術融于其中,在頻譜利用率、對業(yè)務支持具有靈活性、
頻率靈活性及成本等方面的獨特優(yōu)勢。另外,由于中國內的龐大的市場,該標準
受到各大主要電信設備廠商的重視,全球一半以上的設備廠商都宣布可以支持TD
—SCDMA 標準。
??? 什么是2.5G
??? 目前已經進行商業(yè)應用的2.5G移動通信技術是從2G邁向3G的銜接性技術,由
于3G是個相當浩大的工程,所牽扯的層面多且復雜,要從目前的2G邁向3G不可能
一下就銜接得上,因此出現了介于2G和3G之間的2.5G.HSCSD、WAP 、EDGE、藍牙
(Bluetooth )、EPOC等技術都是2.5G技術。
??? HSCSD (高速電路交換數據服務)
??? 這是GSM 網絡的升級版本,HSCSD (HighSpeedCircuitSwitchedData)能夠
透過多重時分同時進行傳輸,而不是只有單一時分而已,因此能夠將傳輸速度大
幅提升到平常的二至三倍。目前新加坡M1與新加坡電訊的移動電話都采用HSCSD
系統,其傳輸速度能夠達到57.6kbps.
??? WAP (無線應用通訊協議)
??? WAP (WirelessApplicationProtocol )是移動通信與互聯網結合的第一階
段性產物。這項技術讓使用者可以用手機之類的無線裝置上網,透過小型屏幕遨
游在各個網站之間。而這些網站也必須以WML (無線標記語言)編寫,相當于國
際互聯網上的HTML(超文件標記語言)。
??? Bluetooth (藍牙)
??? 藍牙是一種短距的無線通訊技術,電子裝置彼此可以透過藍牙而連接起來,
傳統的電線在這里就毫無用武之地了。透過芯片上的無線接收器,配有藍牙技術
的電子產品能夠在十公尺的距離內彼此相通,傳輸速度可以達到每秒鐘1 兆字節(jié)。
以往紅外線接口的傳輸技術需要電子裝置在視線之內的距離,而現在有了藍牙技
術,這樣的麻煩也可以免除了。
??? 3G何時到來
??? 日本移動通訊巨人NTTDoCoMo 已于10月1 日開通全球第一個3G服務,該服務
基于WCDMA 標準。
??? 目前,亞洲成為3G發(fā)展最快的地區(qū),歐洲緊隨其次,美國由于不太熱心而在
技術準備上遠遠落后。除了動作最快的日本和韓國,泰國、香港也已經發(fā)出3G牌
照。臺灣即將發(fā)放3G牌照,預計內地在年底前發(fā)出3G牌照,市場預期將發(fā)行兩到
三個牌照
![]() 數據倉庫系統體系結構 |
·數據源:是數據倉庫系統的基礎,是整個系統的數據源泉。通常包括企業(yè)內部信息和外部信息。內部信息包括存放于RDBMS中的各種業(yè)務處理數據和各類文檔數據。外部信息包括各類法律法規(guī)、市場信息和競爭對手的信息等等; ·數據的存儲與管理:是整個數據倉庫系統的核心。數據倉庫的真正關鍵是數據的存儲和管理。數據倉庫的組織管理方式決定了它有別于傳統數據庫,同時也決定了其對外部數據的表現形式。要決定采用什么產品和技術來建立數據倉庫的核心,則需要從數據倉庫的技術特點著手分析。針對現有各業(yè)務系統的數據,進行抽取、清理,并有效集成,按照主題進行組織。數據倉庫按照數據的覆蓋范圍可以分為企業(yè)級數據倉庫和部門級數據倉庫(通常稱為數據集市)。 ·OLAP服務器:對分析需要的數據進行有效集成,按多維模型予以組織,以便進行多角度、多層次的分析,并發(fā)現趨勢。其具體實現可以分為:ROLAP、MOLAP和HOLAP。ROLAP基本數據和聚合數據均存放在RDBMS之中;MOLAP基本數據和聚合數據均存放于多維數據庫中;HOLAP基本數據存放于RDBMS之中,聚合數據存放于多維數據庫中。 ·前端工具:主要包括各種報表工具、查詢工具、數據分析工具、數據挖掘工具以及各種基于數據倉庫或數據集市的應用開發(fā)工具。其中數據分析工具主要針對OLAP服務器,報表工具、數據挖掘工具主要針對數據倉庫。 |
Overview ? | Package ? | ?Class? | Use ? | Tree ? | Deprecated ? | Index ? | Help ? |
execute
method. This is useful in cases where an HTML form has multiple submit buttons with the same name. The button name is specified by the parameter
property of the corresponding ActionMapping. To configure the use of this action in your struts-config.xml
file, create an entry like this:
<action path="/test"
??????type="org.example.MyAction"
??????name="MyForm"
??????scope="request"
??????input="/test.jsp"
??????parameter="method"/>
which will use the value of the request parameter named "method" to locate the corresponding key in ApplicationResources. For example, you might have the following ApplicationResources.properties:
button.add=Add Record button.delete=Delete Record
And your JSP would have the following format for submit buttons:
<html:form action="/test">
???<html:submit property="method">
??? <bean:message key="button.add"/>
</html:submit>
<html:submit property="method">
???<bean:message key="button.delete"/>
</html:submit> </html:form>
Your subclass must implement both getKeyMethodMap and the methods defined in the map. An example of such implementations are:
protected Map getKeyMethodMap() {
Map map = new HashMap();
map.put("button.add", "add");
map.put("button.delete", "delete");
return map;
}
public ActionForward add(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
// do add
return mapping.findForward("success");
}
public ActionForward delete(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
// do delete
return mapping.findForward("success");
}Notes - If duplicate values exist for the keys returned by getKeys,
only the first one found will be returned. If no corresponding key is found
then an exception will be thrown. You can override the methodunspecified
to
provide a custom handler. If the submit was cancelled (ahtml:cancel
button
was pressed), the custom handlercancelled
will be used instead.
Field Summary | |
protected ?java.util.Map | keyMethodMap ??????????Resource key to method name lookup. |
protected ?java.util.Map | localeMap ??????????Reverse lookup map from resource value to resource key. |
Fields inherited from class org.apache.struts.actions.DispatchAction |
clazz, log, messages, methods, types |
Fields inherited from class org.apache.struts.action.Action |
defaultLocale, servlet |
Constructor Summary | |
LookupDispatchAction() ??????????? |
Method Summary | |
?ActionForward | execute(ActionMapping?mapping, ActionForm?form, javax.servlet.http.HttpServletRequest?request, javax.servlet.http.HttpServletResponse?response) ??????????Process the specified HTTP request, and create the corresponding HTTP response (or forward to another web component that will create it). |
protected abstract ?java.util.Map | getKeyMethodMap() ??????????Provides the mapping from resource key to method name. |
protected ?java.lang.String | getLookupMapName(javax.servlet.http.HttpServletRequest?request, java.lang.String?keyName, ActionMapping?mapping) ??????????Lookup the method name corresponding to the client request's locale. |
protected ?java.lang.String | getMethodName(ActionMapping?mapping, ActionForm?form, javax.servlet.http.HttpServletRequest?request, javax.servlet.http.HttpServletResponse?response, java.lang.String?parameter) ??????????Returns the method name, given a parameter's value. |
private ?java.util.Map | initLookupMap(javax.servlet.http.HttpServletRequest?request, java.util.Locale?userLocale) ??????????This is the first time this Locale is used so build the reverse lookup Map. |
Methods inherited from class org.apache.struts.actions.DispatchAction |
cancelled, dispatchMethod, getMethod, unspecified |
Methods inherited from class org.apache.struts.action.Action |
addErrors, addMessages, execute, generateToken, getDataSource, getDataSource, getErrors, getLocale, getMessages, getResources, getResources, getServlet, isCancelled, isTokenValid, isTokenValid, resetToken, saveErrors, saveErrors, saveMessages, saveMessages, saveToken, setLocale, setServlet |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
protected java.util.Map localeMap
protected java.util.Map keyMethodMap
Constructor Detail |
public LookupDispatchAction()
Method Detail |
public ActionForwardexecute(ActionMapping?mapping,
ActionForm?form,
javax.servlet.http.HttpServletRequest?request,
javax.servlet.http.HttpServletResponse?response)
throws java.lang.Exception
ActionForward
instance describing where and how control should null
if the response has already been completed.execute
in class DispatchAction
mapping
- The ActionMapping used to select this instancerequest
- The HTTP request we are processingresponse
- The HTTP response we are creatingform
- The optional ActionForm bean for this request (if any)java.lang.Exception
- if an error occursprivate java.util.Map initLookupMap(
?????????????????????????????????javax.servlet.http.HttpServletRequest?request,
java.util.Locale?userLocale)
protected abstract java.util.Map getKeyMethodMap()
protected java.lang.String getLookupMapName(
????????????????????????javax.servlet.http.HttpServletRequest?request,
java.lang.String?keyName,
ActionMapping?mapping)
throws javax.servlet.ServletException
request
- The HTTP request we are processingkeyName
- The parameter name to use as the properties keymapping
- The ActionMapping used to select this instancejavax.servlet.ServletException
- if keyName cannot be resolvedprotected java.lang.String getMethodName(ActionMapping?mapping,
ActionForm?form,
javax.servlet.http.HttpServletRequest?request,
javax.servlet.http.HttpServletResponse?response,
java.lang.String?parameter)
throws java.lang.Exception
getMethodName
in class DispatchAction
mapping
- The ActionMapping used to select this instanceform
- The optional ActionForm bean for this request (if any)request
- The HTTP request we are processingresponse
- The HTTP response we are creatingparameter
- The ActionMapping
parameter's namejava.lang.Exception
| |||||||||||
?PREV CLASS? ?NEXT CLASS | FRAMES ? ?NO FRAMES ? ? All ClassesAll Classes | ||||||||||
SUMMARY:?NESTED?|?FIELD?|?CONSTR?|?METHOD | DETAIL:?FIELD?|?CONSTR?|?METHOD |
package onlyfun.caterpillar;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.actions.*;
public class EditAction extends LookupDispatchAction {
protected Map getKeyMethodMap() {
Map map = new HashMap();
map.put("button.save", "save");
map.put("button.preview", "preview");
map.put("button.reset", "reset");
return map;
}
public ActionForward save(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// ......
}
public ActionForward preview(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// ......
}
public ActionForward reset(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
// ......
}
}
button.save=Save
button.preview=Preview
button.reset=Reset
...
<action path="/edit"
type="onlyfun.caterpillar.EditAction"
parameter="method"
name="editForm"/>
...
button.save=存檔
button.preview=預覽
button.reset=重設
native2ascii messages_zh_TW.txt messages_zh_TW.properties |
An abstract Action that dispatches to the subclass mapped <action path="/test" type="org.example.MyAction" name="MyForm" scope="request" input="/test.jsp" parameter="method"/> which will use the value of the request parameter named "method" to locate the corresponding key in ApplicationResources. For example, you might have the following ApplicationResources.properties: button.add=Add Record button.delete=Delete Record And your JSP would have the following format for submit buttons: <html:form action="/test"> <html:submit property="method"> <bean:message key="button.add"/> </html:submit> <html:submit property="method"> <bean:message key="button.delete"/> </html:submit> </html:form> Your subclass must implement both getKeyMethodMap and the methods defined in the map. An example of such implementations are: protected Map getKeyMethodMap() { Map map = new HashMap(); map.put("button.add", "add"); map.put("button.delete", "delete"); return map; } public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // do add return mapping.findForward("success"); } public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // do delete return mapping.findForward("success"); } |
![]() 圖 1. 一個典型的商店應用程序的目錄結構 |
![]() |
![]() |
![]() 圖 2.基于不同的功能 JSP 被放置在不同的目錄下 |
![]() 圖 3. JSP存放在 WEB-INF 目錄下更為安全 |
![]() |
![]() |
![]() |
請注意第7行,這里定義了一個私有變量,該變量是一個Map類。
第9、13行分別定義了Getter和Setter方法,這里,Getter方法需要一個參數,用于傳遞表單域(即動態(tài)屬性)的名稱,Setter方法需要兩個參數,分別是表單域名稱和對應的值,這和傳統的ActionForm的Getter和Setter有很大分別。
然后創(chuàng)建Action類:TestAction
第8行,鑒于這是一個例子為了簡便起見使用了“*”代替了具體的類,編寫程序時還是需要培養(yǎng)良好的習慣引入相應的類,避免出現沖突。
這個類很簡單,只是把請求傳遞到一個在Struts中命名為“success”的forward對應的頁面,具體請看下面列出的struts-config.xml當中的配置。
然后是輸入表單的JSP頁面:input.jsp
第1行引入了Struts的html標簽庫
請注意第4、5行,如果使用傳統的ActionForm,property的值應該與ActionForm里面的一個私有屬性的名稱對應,但在這里,請回憶上述ActionForm中的Getter和Setter方法,分別帶有一個參數和兩個參數,這里的property會通過反射機制自動調用Setter方法,“value(a)”中的“value”就是ActionForm中Map的名稱,而括號當中的“a”,就是我們動態(tài)產生的表單域的名稱,它對應Getter方法中的第一個參數“key”,而用戶在表單輸入的值就對應Setter方法中的第二個參數“value”。
這里,我們分別動態(tài)創(chuàng)建了兩個名為“a”和“b”的表單域,存放到Map中。
然后,我們看看success.jsp即Action轉發(fā)到的頁面
第1行引入了Struts的bean標簽庫。
請注意第2行,引用了名為“test”的ActionForm(詳細設置請看struts-config.xml)。這標簽的作用是顯示輸出ActionForm的指定屬性值。請注意property,“value”就是ActionForm中Map的名稱,它通過反射機制自動調用ActionForm的Getter方法,請回憶上述ActionForm中的Getter方法,帶有一個參數“key”,這里的“a”,“b”實際上是對應剛才輸入頁面動態(tài)產生的兩個表單域屬性名。這里實際是要顯示名為“test”的ActionForm的名為“value”的Map類屬性中的“key”分別為“a”和“b”的對應的“value”。
通過這樣的設計,我們就完成了動態(tài)產生表單域屬性的功能,這個設計的好處是你并不需要修改ActionForm,就能隨意設計你的表單域屬性,也大大減少了ActionForm的編碼量。
最后,讓我們來看看struts-config.xml中的相應配置(只列出相關配置片斷):
?
?
2、“Cannot find bean XXX in any scope”
在Action里一般會request.setAttribute()一些對象,然后在轉向的jsp文件里(用tag或request.getAttribute()方法)得到這些對象并顯示出來。這個異常是說jsp要得到一個對象,但前面的Action里并沒有將對象設置到request(也可以是session、servletContext)里。
可能是名字錯了,請檢查jsp里的tag的一般是name屬性,或getAttribute()方法的參數值;或者是Action邏輯有問題沒有執(zhí)行setAttribute()方法就先轉向了。
還有另外一個可能,純粹是jsp文件的問題,例如<logic:iterate>會指定一個id值,然后在循環(huán)里<bean:write>使用這個值作為name的值,如果這兩個值不同,也會出現此異常。(都是一個道理,request里沒有對應的對象。)
3、“Missing message for key "XXX"”
缺少所需的資源,檢查ApplicationResources.properties文件里是否有jsp文件里需要的資源,例如:
<bean:message key="msg.name.prompt"/>
這行代碼會找msg.name.prompt資源,如果AppliationResources.properties里沒有這個資源就會出現本異常。在使用多模塊時,要注意在模塊的struts-config-xxx.xml里指定要使用的資源文件名稱,否則當然什么資源也找不到,這也是一個很容易犯的錯誤。
4、“No getter method for property XXX of bean teacher”
這條異常信息說得很明白,jsp里要取一個bean的屬性出來,但這個bean并沒有這個屬性。你應該檢查jsp中某個標簽的property屬性的值。例如下面代碼中的cade應該改為code才對:
<bean:write name="teacher" property="cade" filter="true"/>
5、“Cannot find ActionMappings or ActionFormBeans collection”
待解決。
6、“Cannot retrieve mapping for action XXX”
在.jsp的<form>標簽里指定action='/XXX',但這個Action并未在struts-config.xml里設置過。
7、HTTP Status 404 - /xxx/xxx.jsp
Forward的path屬性指向的jsp頁面不存在,請檢查路徑和模塊,對于同一模塊中的Action轉向,path中不應包含模塊名;模塊間轉向,記住使用contextRelative="true"。
8、沒有任何異常信息,顯示空白頁面
可能是Action里使用的forward與struts-config.xml里定義的forward名稱不匹配。
9、“The element type "XXX" must be terminated by the matching end-tag "XXX".”
這個是struts-config.xml文件的格式錯誤,仔細檢查它是否是良構的xml文件,關于xml文件的格式這里就不贅述了。
10、“Servlet.init() for servlet action threw exception”
一般出現這種異常在后面會顯示一個關于ActionServlet的異常堆棧信息,其中指出了異常具體出現在代碼的哪一行。我曾經遇到的一次提示如下:
java.lang.NullPointerException
at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:1003)
at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet.java:955)
為解決問題,先下載struts的源碼包,然后在ActionServlet.java的第1003行插入斷點,并對各變量進行監(jiān)視。很丟人,我竟然把struts-config.xml文件弄丟了,因此出現了上面的異常,應該是和CVS同步時不小心刪除的。
11、“Resources not defined for Validator”
這個是利用Validator插件做驗證時可能出現的異常,這時你要檢查validation.xml文件,看里面使用的資源是否確實有定義,form的名稱是否正確,等等。
來源:http://blog.csdn.net/jht2002/
ERP是英文Enterprise Resourse Planning的縮寫,中文意思是企業(yè)資源規(guī)劃。它是一個以管理會計為核心的信息系統,識別和規(guī)劃企業(yè)資源,從而獲取客戶訂單,完成加工和交付,最后得到客戶付款。換言之,ERP將企業(yè)內部所有資源整合在一起,對采購、生產、成本、庫存、分銷、運輸、財務、人力資源進行規(guī)劃,從而達到最佳資源組合,取得最佳效益。
企業(yè)資源規(guī)劃 ERP, Enterprise Resource Planning)的合理運用已經改變了企業(yè)運作的面貌。ERP通過運用最佳業(yè)務制度規(guī)范business practice以及集成企業(yè)關鍵業(yè)務流程business processes來發(fā)問和提高企業(yè)利潤,市場需求反應速度和企業(yè)。
同時,企業(yè)處在日新月異的市場機遇、價格和服務水平等的挑戰(zhàn)環(huán)境中,必須不斷改變、改善企業(yè)經營模式,提高企業(yè)競爭力。以往僅僅關注于企業(yè)內部的流程改善,產品開發(fā)和制造水平的提高已經不足以面對現時的市場環(huán)境。事實說明,處在現代競爭環(huán)境的企業(yè)要保持生存和持續(xù)發(fā)展必須與商業(yè)合作伙伴充分協調一以建立一個具有競爭優(yōu)勢的價值鏈。
1)客戶可以通過多種方式查詢,并且挑選網上圖書公司的所有出售書籍。通過在網上填寫并確認購書訂單的方式來購買圖書。
2)客戶可以管理自己的訂單信息,查詢匯款單信息,并且可以在網上留言反饋意見等。
3)企業(yè)可以對圖書信息進行管理。
4)企業(yè)可以對圖書的庫存、訂單和匯款單進行管理。
5)企業(yè)可以對客戶的訂單信息,匯款單信息進行審核,以確定是否發(fā)貨。
6)企業(yè)可以針對客戶意見錄入處理結果。
??????7)用戶通過個性化服務可以自助注冊和管理自己的個人信息Step-by-step procedure for integrating Tomcat 5 with JBuilder X
Details
Note:
This is not a supported or tested configuration. This is just a workaround to get the server running in JBuilder X. JSP debugging will not work with this solution.
Steps:
1. Tools | Configure Servers, select the Tomcat 4.1 server and click the Copy button. Change the name to Tomcat 5.0. Next, set the home directory to the root of the Tomcat 5.0 installation, and remove the entry in the Class list and add <TOMCAT_5.0_HOME>/bin/bootstrap.jar.
?
2. File | New Project. Set server to Tomcat 5.0 and create a web module. This will trigger generation of the Tomcat 5.0 Servlet library.
?
3. Tools | Configure Libraries. Edit the Tomcat 5.0 Servlet library and add the following jars :
<TOMCAT_5.0_HOME>/common/lib/jsp-api.jar
<TOMCAT_5.0_HOME>/common/lib/servlet-api.jar
<TOMCAT_5.0_HOME>/bin/commons-logging-api.jar
<TOMCAT_5.0_HOME>/common/lib/commons-el.jarMake a backup of this library (in your user home directory) as it gets regenerated when you create a new web module/JSP/servlet. Please make sure that you replace the library when you use any of the web gallery wizards.
?
4. Set server for the project to Tomcat 5.0.
?
5. If a "Tomcat" folder is not present under the project's root directory, create one (e.g. ../jbproject/untitled1/Tomcat). Next, create a directory named "conf" under this directory (e.g. ../jbproject/untitled1/Tomcat/conf). and create an XML file named server8080.xml. Sample server8080.xml is below. Please modify the appBase, docBase, and workDir, etc. according to your web module properties:
?
<?xml version="1.0" encoding="UTF-8"?>
<!--This comment marks this file as generated, so it may be deleted and regenerated at any time. To preserve manual changes to this file, delete this comment.-->
<Server debug="0" port="8081" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector acceptCount="10" connectionTimeout="60000" debug="0" maxThreads="75" minSpareThreads="5" port="8080"/>
<Engine debug="0" defaultHost="localhost" name="Catalina">
<Host appBase="C:Documents and Settings<user name>jbprojectuntitled1Tomcatwebapps" debug="0" name="localhost" unpackWARs="true">
<Context debug="0" docBase="C:Documents and Settings<user name>jbprojectuntitled1WebModule1" path="/WebModule1" reloadable="true" workDir="C:Documents and Settings<user name>jbprojectuntitled1TomcatworkWebModule1"/>
</Host>
</Engine>
</Service>
</Server>?
6. Start the server in JBuilder. This should use the modified server8080.xml
?
You should be able to compile JSPs using this workaround but not debug. You should be able to debug any java code. You will see a number of exceptions for the admin, manager, balancer services which do not get started when you normally run the server in JBuilder. Please ignore these exceptions. The server should function normally without these services.