Petstore原始碼記縱記(3)一矞業邏輯處理 By歐亘修renshaw@ms4hinet.net 前官 透過前面的介貂’我們能夠了解 Petstore中 Model、 Controller丶Ⅵiew是如 何相互合作·現在讓筆者來說明 Petstore矞業邏輯( Business logic)的處理方式 首先讓我們先了解爲什麼要將矞業邏輯與資料展現( Presentation分開如此做有 下列的好處 1.減少程式變動的衝墼∶矞業邏輯及資料展現彼此獨立’不因蔄業邏輯改變而影 響資料展現的程式碼,反之亦然。 2.易於雜護∶將矞業邏輯集中管理’一旦日後有修改·僅須修改一個地方。 3.重複使用∶矞業邏輯若與資料展現層程式混在一趄·如仳矞業邏輯只能服務 種使用者介面( Client)·若將兩者分離’我們可以很容易擴充第二種使用者介面 4各司其職∶資料展現的設計人員與矞業邏輯的設計人員通常是不一樣的·彼此 獨立讓術業有專攻’品質及效率皆能提升。 隱形角色 在追縱 Petstore矞業邏輯處理方式前·我們先來看看 Petstore中的隱形角 色’這些隱形魚色在伺服器(RⅠ)啓動時即默默凖備好·待適當畤機爲 Petstore中 藺業邏輯處理服務’所以筆者須先介紹它們 請開啓 Petstore home(註 ) srclapps'petstorelsrcldocrootlWEB-INF\web. xml,我們可以看到 filter>/第一個 Fliter Encoding Encoding Filter description>no description com. sun j2ee blueprints. encodingfilter web Encoding Filter encoding UTF-8 2.第二個 Filter
Petstore 原始碼記縱記(3)-商業邏輯處理 By 歐亘修 senshaw@ms4.hinet.net 前言 透過前面的介紹,我們能夠了解 Petstore 中 Model、Controller、View 是如 何相互合作,現在讓筆者來說明 Petstore 商業邏輯(Business Logic)的處理方式, 首先讓我們先了解為什麼要將商業邏輯與資料展現(Presentation)分開,如此做有 下列的好處: 1.減少程式變動的衝擊:商業邏輯及資料展現彼此獨立,不因商業邏輯改變而影 響資料展現的程式碼,反之亦然。 2.易於維護:將商業邏輯集中管理,一旦日後有修改,僅須修改一個地方。 3.重複使用:商業邏輯若與資料展現層程式混在一起,如此商業邏輯只能服務一 種使用者介面(Client),若將兩者分離,我們可以很容易擴充第二種使用者介面。 4.各司其職:資料展現的設計人員與商業邏輯的設計人員通常是不一樣的,彼此 獨立讓術業有專攻,品質及效率皆能提升。 隱形角色 在追縱 Petstore 商業邏輯處理方式前,我們先來看看 Petstore 中的隱形角 色,這些隱形角色在伺服器(RI)啟動時即默默準備好,待適當時機為 Petstore 中 商業邏輯處理服務,所以筆者須先介紹它們。 請開啟 Petstore_home(註 一)\src\apps\petstore\src\docroot\WEB-INF\web.xml,我們可以看到: //1.第一個 Fliter EncodingFilter EncodingFilter no description com.sun.j2ee.blueprints.encodingfilter.web.EncodingFilter encoding UTF-8 //2.第二個 Filter
SignOn Filter Sign ription-no on com.sun j2ee blueprints. signon web SignOn Filter 1第一個 Filter對應 Encoding Filter /* filter-mapping>∥第二個 Filter對應 SignOn Filter atter listener.>/3.第一個 Listerner com.sun j2ee blueprints. petstore controller. web. Petstore Compon entManager listener>/4.第二個 Listerner com. sun j2ee blueprints. petstore controller. web. SignOnNotifier Filter與 Listener是 Servlet2.3增加的功能, Filter可以在接受使用者的 Request 之後,做一些檢査處理·若沒問題則把使用者要求的 Response丟回給使用者 反之則丟回系锍預設的處理畫面’最常使用的情況就是登入·在網頁應用系統中
SignOnFilter SignOnFilter no description com.sun.j2ee.blueprints.signon.web.SignOnFilter //第一個 Filter 對應 EncodingFilter /* //第二個 Filter 對應 SignOnFilter /* //3.第一個 Listerner com.sun.j2ee.blueprints.petstore.controller.web.PetstoreCompon entManager //4.第二個 Listerner com.sun.j2ee.blueprints.petstore.controller.web.SignOnNotifier Filter與Listener是Servlet2.3增加的功能,Filter可以在接受使用者的Request 之後,做一些檢查處理,若沒問題則把使用者要求的 Response 丟回給使用者, 反之則丟回系統預設的處理畫面,最常使用的情況就是登入,在網頁應用系統中
有些功能是必須登入扌能使用·過去的做法我們會將登廴檢查寫在這些個別功能 上’如此會造成登廴檢查若要修正’則必須逐支修改’造成時間浪費’運用Fier 我們可將登廴檢査程式與其他程式獨立’日後容易雜護σ Listener則是増加對 Context. session生命週期的控制’例如我們能夠在 Session初始化時’將所需使 用的資料一起產生’並將 Reference存廴 Session, seesion關閉時可順便將相關 資源移除’如此資源集中控管’容易雜護 Encoding Filter 它的程式碼位置在 Petstore homelsrclcomponentslencodingfilter\\\sun j2eelblueprintslencodingfil terlweb\Encoding Filter. java,它會再讀取 web. xm(位置在 Petstore home\\\petstorelsrcldocrootIWEB- INF\web. xm)中的參數,決定編 碼方式再將其設入 Request中 Encoding Filter Encoding Filter description>no description com. sun. 2ee blueprints. encodingfilter web Encoding Filter /設定糯碼方式参數 encoding param-value>UTF-8 Encoding Filter. java public class Encoding Filter implements Filter i private Filter Config config=null ∥/ default to ascll private String targetEncoding="ASCII", 初始化時讀取参數 public void init(Filter Config config) throws Servlet Exception this config= confi
有些功能是必須登入才能使用,過去的做法我們會將登入檢查寫在這些個別功能 上,如此會造成登入檢查若要修正,則必須逐支修改,造成時間浪費,運用 Filter, 我們可將登入檢查程式與其他程式獨立,日後容易維護。Listener 則是增加對 Context,Session 生命週期的控制,例如我們能夠在 Session 初始化時,將所需使 用的資料一起產生,並將 Reference 存入 Session,Seesion 關閉時可順便將相關 資源移除,如此資源集中控管,容易維護。 Encoding Filter 它的程式碼位置在 Petstore_home\src\components\encodingfilter\src\com\sun\j2ee\blueprints\encodingfil ter\web\EncodingFilter.java,它會再讀取 web.xml(位置在 Petstore_home\src\apps\petstore\src\docroot\WEB-INF\web.xml)中的參數,決定編 碼方式再將其設入 Request 中: web.xml EncodingFilter EncodingFilter no description com.sun.j2ee.blueprints.encodingfilter.web.EncodingFilter //設定編碼方式參數 encoding UTF-8 EncodingFilter.java public class EncodingFilter implements Filter { private FilterConfig config = null; // default to ASCII private String targetEncoding = "ASCII"; //初始化時讀取參數 public void init(FilterConfig config) throws ServletException { this.config = config;
this target Encoding- config. getInitParameter("encoding") public void destroy( config= null target Encoding=null; /將糯碼方式参數存入 reqeust;結束此 Filter public void do Filter(ServletRequest srequest, ServletResponse response FilterChain chain) throws IOException, Servlet Exception t HttpservletrEquestrequest=(httpServletrequest)sreqUest; request. setCharacter Encoding(target Encoding) ∥/ move on to the next chain. doFilter(srequest, response) 筆者覺得這個 Filter滿有用的ν可以單獨運用在傳統 JSPHJavaBεas的web Application在 Tomcat3.2ⅹ·預設編碼是UTF-8·所以我們處理中文時’必須自 行在程式中處理·在存廴資料庫前須將中文字編碼由 Unicode轉成Big5;到了 Tomcat33x; Tomcat會從OS取得預設編碼方式’所以我們不必再自行處理;到 了 Tomcat4.0x之後,情況又回到與 Tomcat3.2.x一樣,筆者開發 Web application 就碰到這個情況·歴經三個版本的 Tomaα·程式改過來改過去的’儘做些白工 後來筆者改運用這個 Filter’就不需在存廴資料庫前須將中文字編碼由 Unicode 轉成Big5。 ComponentManager Listener 第二個 Filter主要掌管登入’與本次主題有密切關係’爲使流程順暢’所以 稍後再說明我們來看第一個 Listener,它的主要功能是作爲服務連結提供者 當使用者進入本系統時·應用伺服器( Application Sever)會在 Session產生時會建 置儲存服務連結容器’並將其置廴 Session·待後續程式服務產生後使用 Default Component Manager. java,原始碼在 Petstore homelsrclwaflsrclcontrollerIcomlsunlj2eelblueprintslwaf\controllerlweb
this.targetEncoding = config.getInitParameter("encoding"); } public void destroy() { config = null; targetEncoding = null; } //將編碼方式參數存入 reqeust,結束此 Filter public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)srequest; request.setCharacterEncoding(targetEncoding); // move on to the next chain.doFilter(srequest,sresponse); } } 筆者覺得這個 Filter 滿有用的,可以單獨運用在傳統 JSP+JavaBeans 的 Web Application,在 Tomcat3.2.x,預設編碼是 UTF-8,所以我們處理中文時,必須自 行在程式中處理,在存入資料庫前須將中文字編碼由 Unicode 轉成 Big5;到了 Tomcat3.3.x,Tomcat 會從 OS 取得預設編碼方式,所以我們不必再自行處理;到 了 Tomcat4.0.x 之後,情況又回到與 Tomcat3.2.x 一樣,筆者開發 Web Application 就碰到這個情況,歷經三個版本的 Tomcat,程式改過來改過去的,儘做些白工, 後來筆者改運用這個 Filter,就不需在存入資料庫前須將中文字編碼由 Unicode 轉成 Big5。 ComponentManager Listener 第二個 Filter 主要掌管登入,與本次主題有密切關係,為使流程順暢,所以 稍後再說明。我們來看第一個 Listener,它的主要功能是作為服務連結提供者, 當使用者進入本系統時,應用伺服器(Application Sever)會在 Session 產生時會建 置儲存服務連結容器,並將其置入 Session,待後續程式服務產生後使用。 DefaultComponentManager.java,原始碼在 Petstore_home\src\waf\src\controller\com\sun\j2ee\blueprints\waf\controller\web
oublicvoidsessioncreated(httpsessionEventse)i Httpsession session=se. getsessiono /產生服務連結容器 sl= ServiceLocator. getInstanceo /腐本 Listener存入 Session session.setAttribute( WebKeys COMPONENT MANAGER, this) ServiceLacator. java,原始碼在 Petstore homesrclcomponents\servicelocatorlsrcIcom\sun j2eeblueprintsserviceloca torlweb’此類別寫法滿特別的大家又可多學種程式設計技巧·追縱前輩原始 碼·除了能夠了解各種功能如何設計之外’程式碼分解( Refactor丶撰寫風格 設計技巧·對我們來說都是很重要的收穫! Servicelacator基本上它是一個BJB 及JMS資源連結服務提供者·且它的服務不因使用者不同而有所改變,所以它 使用 static寫法來達到這個效果。 public class ServiceLocator i private InitialContext ic; private Map cache; //used to hold references to EJBHomes/JMS Resources for private static Servicelocator me /初次宣告此物件時會執行初始化動作 me = new Servicelocator(; i catch(ServiceLocator Exception se)( System. err println(se); seprintStackTrace(System. err); /建構子產生JNDI連結及同步化 Hash Map容器 private ServicelocatorO throws ServiceLocator Exception ic= new InitialContexto cache= Collections. synchronizedMap(new HashMapo); i catch(Naming Exception ne)i
public void sessionCreated(HttpSessionEvent se) { HttpSession session = se.getSession(); //產生服務連結容器 sl = ServiceLocator.getInstance(); //將本 Listener 存入 Session session.setAttribute(WebKeys.COMPONENT_MANAGER, this); } ServiceLacator.java,原始碼在 Petstore_home\src\components\servicelocator\src\com\sun\j2ee\blueprints\serviceloca tor\web,此類別寫法滿特別的,大家又可多學一種程式設計技巧,追縱前輩原始 碼,除了能夠了解各種功能如何設計之外,程式碼分解(Refactor)、撰寫風格、 設計技巧,對我們來說都是很重要的收穫!ServiceLacator 基本上它是一個 EJB 及 JMS 資源連結服務提供者,且它的服務不因使用者不同而有所改變,所以它 使用 static 寫法來達到這個效果。 public class ServiceLocator { private InitialContext ic; private Map cache; //used to hold references to EJBHomes/JMS Resources for //re-use private static ServiceLocator me; //初次宣告此物件時會執行初始化動作 static { try { me = new ServiceLocator(); } catch(ServiceLocatorException se) { System.err.println(se); se.printStackTrace(System.err); } } //建構子,產生 JNDI 連結及同步化 HashMap 容器 private ServiceLocator() throws ServiceLocatorException { try { ic = new InitialContext(); cache = Collections.synchronizedMap(new HashMap()); } catch (NamingException ne) {
throw new ServiceLocator Exception(ne) i catch(Exception e)i throw new ServiceLocator Exception(e); /將本物件参考傳出 static public ServiceLocator getinstanceoi return me 以下略過. 上迒 Service locator建構子中運用 Collections的 Static Method(靜態函式) synchronizedMapo來產生 Hash Map容器依 J2SDK API文件說法’透過此函式 可產生出具同步化及安全執行緒的 HashMap容器 使用者基本資料瀏覽流程 現在讓我們進人主題- Petstore矞業邏輯’筆者以使用者基本資料瀏覽流程 爲例,請啓動 cloudscape資料庫 cloudscape-star C其rs产m2cmde \Documents and Settings \Adninistrator\ET>cloudscape -start Mon Sep 16 23: 21: 33 CST 2002: [RniJdbc] Starting Cloudscape RmiJdbc Server Versil Mon Sep 16 23: 21: 35 CST 2002: [RniJdbc 1 COM cloudscape core. JDBCDriver registere Mon Sep 16 23: 21: 35 CST 2002: [RniJdbc l Binding RmiJdbc Server Mon Sep 16 23: 21: 35 CST 2002: [RniJdbc No installation of RMI Security Manager Mon Sep 16 23: 21: 36 CST 2002: [RniJdbc l RmiJdbcServer bound in rmi registry
throw new ServiceLocatorException(ne); } catch (Exception e) { throw new ServiceLocatorException(e); } } //將本物件參考傳出 static public ServiceLocator getInstance() { return me; } 以下略過… } 上述 ServiceLocator 建構子中運用 Collections 的 Static Method(靜態函式) synchronizedMap()來產生 HashMap 容器,依 J2SDK API 文件說法,透過此函式 可產生出具同步化及安全執行緒的 HashMap 容器。 使用者基本資料瀏覽流程 現在讓我們進入主題-Petstore 商業邏輯,筆者以使用者基本資料瀏覽流程 為例,請啟動 cloudscape 資料庫: cloudscape –start
圖1啓動資料庫 接著啓動 RI Application Server(應用伺服器) j2ee-verbose Binding nane local/signOn Binding name:java:comp Binding nane: java:com l/Address Binding nane: java: comp/env local/U Binding nane: java: comp/env/jdbc/Catalog DB omp/env/url/CatalogDAOSQLUE reated Context :/petstore Binding nane:java:comp/enu/ejb/remote/OPCAdminFacade Binding name: java: comp/env/ejb/local/As ync Sender Iinfo]http--jax-rpcservletinit d Context :/admin Binding name: java: comp/env/param/xml/validation/Invo i Binding name java:comp/env/param/xml/Xs VAlidation Binding nane: 'java: comp/env/jns/topic/Invoice Topit Binding nane : 'java:comp/enu/url/EntityCatalogURL Binding nane: java: comp/env/jns/topic/Topic Connection Factory LinfOihttp--jax-rpc let: init eated Context :/opc J2EE server startup complete 圖2啓動RI Petstore系統啓動無誤後·請開啓瀏覽器’輸入 http://localhost:8080/petstore/index.jsp
圖 1 啟動資料庫 接著啟動 RI Application Server(應用伺服器): j2ee –verbose 圖 2 啟動 RI Petstore 系統啟動無誤後,請開啟瀏覽器,輸入 http://localhost:8080/petstore/index.jsp
我的桑爱守媒曾④·当三日 JavaTM Pet Store Demo 1.3.1 The Java TM Pet Store Demo i a sample applcation brought to you by the Java M BluePrints for the Enterpnse program at Java TM Software, Sun Microsystems Thas sample applicaton demonstrates how to use the capabilites of the J2EE platform to develop tenable, scalable, cross-platform e-busness applicahons. It ou can experiment with J2EETM technology and lean how to use it to buld your own enterpnse sohutionsomes sing this demo for the very first time, the demos database will be automatical populated (e prepared You may also forcefully repopulate the demos database (Be prepared to wat for a while as the database s populated. y ou can also use the adrmustraor chert About Java BluePrints for the Enterprise hitectural recommendatons for real-world applcaton scenarios to en Applicatians with the J2EBTX CheckouttheJavanBlueprintsfortheEnterpnseWebsteathttp://jsva,auntcom/blueprints/entecpriae Copynght e 2002 Sun Microsystems, Inc. All Rights Reserved. 圖3進入 Petstore系統 進入系統看到那大大的鸚鵡頭·請點選右上魚的ˆ Accoun'連結’進λ使用者登 入流程 输案副面棱概①我的最爱①)工具①明围 址①没 JavaTM Pet Store Search 2EE Blue Prints Sample Application 点CCQU Birds Rept les @ The Jara Pet Store Demo is a fictional sample application from the Java Blue Prints for the Emderpnse For more information. wisn the Java Blue Pints for the Enerprise Java blue Pnns forthe Ertemnse I aa Software Sun Microsystems e h Mocehoata0colpettomekctomerdo 近娱内部
圖 3 進入 Petstore 系統 進入系統看到那大大的鸚鵡頭,請點選右上角的”Account”連結,進入使用者登 入流程:
圖4 Petstore首頁 我們會看到登入畫面,疸接使用預設的使用者(2e)及密碼(2e)·點選' Sign ln 鈕 国棱概①我的最工具①明 中上一页·→·的国我的船景守媒(日 址httpmmocalHoStadedpestmecntamerd 令移至灌 JavaTM Pet Store J2EE BluePrints Sample Applicati Account I cartI Sonin Pets Are you a returning customer? Reptiles No. i would like to sign up for an Password Password Remember My User Name厂 Create New Account The Java Pet Store Demo is a fictional sample application t wsn the Java Blue Pnns for the enterpris ava Bhe Prints for the Entemnse I Jama Software I Sun Microsystems 22001 Sun Microsystems Inc. All rights reserved. Use is subject 圖5登入畫面 看到以下顯示個人資訊畫面就表示我們已登人成功啦
圖 4 Petstore 首頁 我們會看到登入畫面,直接使用預設的使用者(j2ee)及密碼(j2ee),點選”Sign In” 鈕: 圖 5 登入畫面 看到以下顯示個人資訊畫面就表示我們已登入成功啦!
httMocabostsceo-tpes:tbrekusthmerdo 移至洁 JavaTM Pet Store Your Account Information Contact Information Rattlesnake First Name xyz Last Name ABC Street Address 1234 Anywhere Street un555 City Palo Alt Postal Code 94303 Country USA number 565-565-5565 Card Type Meow Card Card Expiry Date 04/04 Profile Information 圖6個人資訊畫面 若此時我們按瀏覽器之”上一頁ˆ鈕返回首頁 aweto 「案面①我的鼎数)工具①明① 中上一·→·的②a国我的鼎要守媒普④日日 址①没 JavaTM Pet Store Search 2EE Blue Prints Sample Application Accoun CartI Sonin Birds Rept les @ The Jara Pet Store Demo is a fictional sample application from the Java Blue Prints for the Emderpnse For more information. wisn the Java Blue Pints for the Enerprise Java blue Pnns forthe Ertemnse I aa Software Sun Microsystems 近娱内部
圖 6 個人資訊畫面 若此時我們按瀏覽器之”上一頁”鈕返回首頁: