使用 Rational 加速基於 XML 的 SOA 的 JSF 開發二

isoa發表於2009-05-05

場景

我們的場景擴充套件了第 1 部分 中開發的保險應用程式,使之包括建立、更新以及刪除功能,本地附加的變數,基本的轉換和 下拉式繫結的功能。在該場景中:

  • 我們假設 XYZ 保險公司有許多已註冊的代理人。
  • 每個代理人都有許多客戶,並且每個客戶都同代理人簽訂了許多策略。
  • 保險公司通過標準的 BrokerService 方案來展示代理人的服務(清單 1),並使用有效代服務 validCodesService schema(清單 2)進行檢索,例如有效的狀態碼。
  • 任何來自代理人的通訊就是一個 XML 請求/響應,它服從清單 1 和清單 2 中的 schema 定義。(這些清單同樣也在下載檔案xsd_sdo_soa_part2_listings.zip 中的提供。)

清單 1. BrokerService.xsd


	
		
   			Broker Service Schema for xyz.com.
   			Copyright 2004 ibm.com. All rights reserved.
  		
	
	
	
		
			
			
		
	
	
		
			
			
			
			
			
		
		
	
	
		
			
			
			
			
			
			
		
		
	
	
		
			
			
			
			
			
		
	
	
		
			
			
			
			
			
		
		
	
	
		
			
			
		
	
	
	



圖 1. BrokerService Schema 模型
BrokerService Schema 模型

清單 2. ValidCodesService.xsd


	
		
   			Valid Codes Service Schema for xyz.com.
   			Copyright 2004 ibm.com. All rights reserved.
  		
	
	
	
		
			
			
		
	
	
	
		
			
		
	
	
		
		
			
			
		
	
	
		
		
			
		
	
			
		
			
			
		
	
	



圖 2. ValidCodesService schema 模型
ValidCodesService schema 模型

BrokerUpdate 場景

該場景為現有的 brokerupdate.jsp JavaServer Faces JSP 頁增添了新的功能。該頁已經傳送請求以獲得代理人的詳細資料(第 1 部分 中的 brokerDetailRequest.xml),並且接收到了包含代理人的所有客戶和他們的策略的響應資訊(第 1 部分中的brokerDetailResponse.xml)。該頁也將會呼叫有效的程式碼服務來檢索有效的程式碼值作為一個 XML 響應(清單 5 中的 allValidCodesResponse.xml),同時也能夠建立、更新和刪除策略,還能夠演示除了用於基本轉換的來自已經生成的 SDO 的行為之外的操作行為。轉換作為 brokerUpdateRequest.xml (清單 3)傳送到該服務,對操作成功或者失敗的響應作為brokerUpdateResponse.xml (清單 4)接收。 brokersummary.jsp 頁在檢索來自服務更新後的改動之後將顯示出來。


圖 3. BrokerUpdate 請求/響應資訊流
圖 3. BrokerUpdate 請求/響應資訊流

Listing 3. brokerUpdateRequest.xml



	Narinder
	Makin
	
		Dan
		Moore
		1967-08-13
		
			113 Oak Pine St.
			Santa Clara
			LA
			91929
			US
		
		
			123 Demi Lane
			Cary
			NC
			22999
			US
		
		
			Life
			2004-01-01
			2005-01-01
			200000.00
			Life Insurance
		
		
		House
			2004-01-01
			2005-01-01
			20000.00
			Home Insurance
		
		
		Car 1
			2004-01-01
			2005-01-01
			15000.00
			Car Insurance - Ferrari 2004 - Primary Car 
		
		
		Car 2
			2004-01-01
			2005-01-01
			5000.00
			Car Insurance - Lexus 2003 - Secondary Car 
		
		
		Restaurant
			2004-01-01
			2005-01-01
			25000.00
			Business Insurance - Restaurant
		
		
		Golf Course
			2004-01-01
			2005-01-01
			25000.00
			Second Business Insurance - Golf Course
		
	
	
		Tom
		Cross
		1970-11-11
		
			113 Duke St.
			Shelton
			CT
			08989
			US
		
		
			123 Lex Lane
			Fairfield
			NY
			09833
			US
		
		
			Life
			2004-01-01
			2005-01-01
			100000.00
			Life Insurance
		
		
			House
			2004-01-01
			2005-01-01
			2000.00
			Home Insurance
		
		
			Car 1
			2004-01-01
			2005-01-01
			2000.00
			Car Insurance - Camry 2004 - Primary Car 
		
	


清單 4. brokerUpdateResponse.xml


	
	
		0
		Success: The changes have been successfully applied to the policy.
	


清單 5. allValidCodesResponse.xml


	
		
			CT
			Connecticut
		
		
			LA
			Los Angelas
		
		
			NC
			North Carolina
		
		
			CA
			California
		
		
			NH
			New Hampshire
		
		
			VA
			Virginia
		
	
	
		
			H
			House
		
		
			C
			Car
		
		
			B
			Business
		
		

應用程式設計流

圖 4 描繪了用於該場景的應用程式設計流。


圖 4. 應用程式設計流
應用程式設計流




回頁首

執行時架構

一旦頁請求到來,就會發生以下事件 (圖 5):

  1. JSF 執行時將呼叫 BrokerUpdateRoot bean。
  2. BrokerUpdateRoot 將向 BrokerService 傳送 brokerDetailRequest.xml 來預載入資料。
  3. BrokerService 將已經被傳送到 XMLTransformServiceFactory 的響應作為 brokerDetailResponse.xml 傳送。
  4. XML 被轉換為封裝在 BrokerUpdateRoot bean 中的 SDO。
  5. JSF 執行時將呼叫 ValidCodesServiceRoot bean。
  6. ValidCodesServiceRoot Java™ bean 將呼叫 ValidCodesService 來預裝載這些資料。
  7. ValidCodesService 已經被傳送到 XMLTransformServiceFactory 的響應作為 allValidCodesResponse.xml 傳送。
  8. XML 被轉換為封裝在 ValidCodesServiceRoot bean 中的 SDO。
  9. JSF 執行時移交資料的控制權。
  10. 從 bean 中呼叫 XMLTransformServiceFactory。SDO 例項會傳送到 XMLTransformServiceFactory,並轉變成傳送到 BrokerService 的 brokerUpdateRequest.xml
  11. brokerUpdateResponse.xml 作為響應接收,並傳送到封裝在 BrokerUpdateRoot bean 中的 SDO。


圖 5. 執行時架構
執行時架構 

實現解決方案

在下面的章節中詳細描述了實現該解決方案的步驟:

  1. 匯入專案轉換
  2. 從 XSD schema 建立 SDO 包
  3. 向已經生成的 SDO 增添附加的屬性和行為
  4. 新增新的根 bean 封裝器
  5. 更新現有的根 bean 封裝器
  6. 向頁程式碼中增添命令方法
  7. 將 bean 附加到頁面資料
  8. 將頁面上繫結的控制元件修改為頁面資料的 SDO 型別
  9. 執行 brokerdetail.jsp

  1. 匯入專案轉換

    將專案轉換 xsd_sdo_soa_xml_tutorial.zip 下載檔案 匯入到 Application Developer 的工作區中。因此,下面的專案將被匯入(圖 6):

    • XYZInsuranceEAR:以模組化或者有效性來包含所有其他專案的企業應用程式專案。
    • XYZInsuranceWeb:用於建立了所有 JSF JSP 頁的應用程式的動態 Web 專案。該專案的 WebContent 資料夾中的 Schema 資料夾中有 BrokerService.xsd schema 檔案和例項資料檔案。為簡化起見,本例中的 schema 和 SDO 包是的 WebProject 的一部分。如果使用者願意通過多個 Web 專案分享同一個 SDO,那麼使用者就能建立一個單獨的 Java 專案用於 SDO 包。SDO 包構建在存有 XML Schema 的同一個專案中。本例中已經建立了brokerupdate.jspbrokersummary.jspBrokerUpdateRoot.javaBrokerSummaryRoot.java 元件。
    • XYZInsuranceService:包含了用於代理人服務和有效程式碼服務的 Java 類實現。該服務載入並且傳送了合適的基於服務方法請求的 XML 響應。這種基本實現用來模擬服務行為,其實現方法已經超出本文講述的範圍。
    • XYZInsuranceServiceProxy:包括了用於呼叫代理人服務的 ServiceProxy 的基本實現。


    圖 6. 專案轉換的匯入指南
    專案轉換的匯入指南
  2. 建立來自 XSD 計劃的 SDO包

    在 Application Developer 中,在 ValidCodesService.xsd 上單擊右鍵,然後選擇 Create SDO Package(圖 7)。


    圖 7. 建立 SDO 包
    建立 SDO 包

    因此,將產生如圖 8 所示的情景。


    圖 8. 生成的 SDO 包
    生成的 SDO 包

    該包的名稱來自 targetNamespace,它在 XSD 宣告的 schema 中定義(圖 9)。


    圖 9. TargetNamespace 宣告
    TargetNamespace 宣告
  3. 向已經生成的 SDO 增添附加的屬性和行為

    使用者可以修改已經生成的 SDO,使之包含特定的變數或者行為。當再次生成該 SDO 以用於同一個 schema 的名稱空間時,任何沒有使用 @generated 標籤註解的方法或者變數將不能被替換。使用者也可以將這樣的檔案標記為 non-derived 型別,以便專案 "clean" 時刪除這些檔案。

    1. 向策略 SDO 介面中新增 get/set 方法,xyz.brokerservice.PolicyType

      /**
       * Get the value for selected
       */
      boolean getSelected();
      /**
       * Set the value for selected
       */
      void setSelected(boolean selected);



    2. 向策略 SDO 實現類中新增以下的屬性和方法,xyz.brokerservice.impl.PolicyTypeImpl

      /**
       * add selected attribute as local variable.
       */
      protected boolean selected = false;
      /**
       * Get the value for selected
       */
      public boolean getSelected(){
      	return selected;
        }
      /**
       * Set the value for selected
       */
      public void setSelected(boolean selected){
      	this.selected = selected;
        }



    3. 向客戶端 SDO 介面中新增獲取的方法,xyz.brokerservice.ClientType

      /**
       * TotalPolicyAmount is computed by summation of the client's Policy Amounts
       */
        double getTotalPolicyAmount();



    4. 向客戶端 SDO 介面中新增以下的方法,xyz.brokerservice.impl.ClientTypeImpl;以下的方法演示了基本的轉換能力:

      /**
       * totalPolicyAmount is computed by summation of the client's Policy Amounts
       */
      public double getTotalPolicyAmount(){
      	double totalPolicyAmount = 0.00;
      	for(int index=0; index < getPolicy().size(); ++index){
      		PolicyType policyType = (PolicyType)getPolicy().get(index);
      		if(policyType.getPolicyAmount() != null){
      			double temp = 0.00;
      			try{
      				temp = Double.parseDouble(policyType.getPolicyAmount());
      			}catch(NumberFormatException ex){
      			}
      			totalPolicyAmount += temp;
      		}
      	}
      	return totalPolicyAmount;
      }



    5. 將已經改動的檔案標記為 non-derived,以便在專案“clean”期間保留這些改動(圖 10)。


    圖 10. 更改派生屬性
    更改派生屬性
  4. 新增新的根 bean 封裝器

    ValidCodesServiceRoot.java 檔案包含了計劃名稱空間 URI 的註冊,用於有效程式碼服務的屬性和它的獲取/設定方法。通過呼叫這些有效的程式碼服務來慢慢地裝載所有有效的程式碼。在 brokerservice.root 包中新增 ValidCodesServiceRoot.java Java 類:

    package brokerservice.root;
    import org.eclipse.emf.ecore.EPackage;
    import proxy.ValidCodesServiceProxy;
    import xyz.validcodesservice.DocumentRoot;
    import xyz.validcodesservice.ValidCodesServiceType;
    import xyz.validcodesservice.ValidcodesservicePackage;
    import dw.ibm.etools.xsd.sdo.xmltransformservice.XMLTransformServiceFactory;
    public class ValidCodesServiceRoot extends BaseRoot{
    	protected ValidCodesServiceType validCodesServiceRoot;
    	static{
    		EPackage.Registry.INSTANCE.put(
    				ValidcodesservicePackage.eINSTANCE.getNsURI()
    				, ValidcodesservicePackage.eINSTANCE);
    	}
    	protected void loadValidCodesResponse(String response){
    		DocumentRoot docRoot=
    		 (DocumentRoot) XMLTransformServiceFactory.INSTANCE.load(response);
    		validCodesServiceRoot =  docRoot.getValidCodesService();
    	}
    	public ValidCodesServiceType getValidCodesServiceRoot() {
    		if(validCodesServiceRoot == null){
    			preLoadValidCodes();
    		}
    		return validCodesServiceRoot;
    	}
    	public void setValidCodesServiceRoot(
    			ValidCodesServiceType validCodesServicetRoot) {
    		this.validCodesServiceRoot = validCodesServicetRoot;
    	}
    	protected void preLoadValidCodes(){
    	    String response = ValidCodesServiceProxy.invoke(
    	    			ValidCodesServiceProxy.ALL_REQUEST);
    	    loadValidCodesResponse(response);
    	}
    }

  5. 更新現有的根 bean 封裝器

    更新 brokerservice.root 包中現有的BrokerUpdateRoot.java Java 類 ,該包提供了相關的下載檔案,或者更新帶有以下附加物的檔案:

    1. 下列方法通過使用框架 API 以將資料物件轉變為 XML 字串的方式向服務傳送這些更新,從而更新 broker 資訊。轉變 API 的第 2 個引數確保所有的空屬性將不屬於序列化 XML 的一部分。如果這樣的元素宣告被接收端的 XML 處理器接收,那麼使用者就可以使用轉變 API 的其他實現。

      public void applyPolicyChanges(){
      		//unset all the features that are empty
      	    String xmlData = XMLTransformServiceFactory.INSTANCE.convert((DataObject)brokerServiceRoot, true);
      	    String response =
      	    	BrokerServiceProxy.invoke(xmlData,
      	    			BrokerServiceProxy.BROKERUPDATE_REQUEST);
      	    loadBrokerDetailUpdateResponse(response);
      	}



    2. 使用裝載 API 呼叫來裝載從服務呼叫中返回的響應。建立 SDO 包時,所有不屬於計劃的元素將會通過裝載呼叫記錄下來。當該資料物件使用轉變 API 被序列化到 XML 時, 這些元素就會被寫回。

      protected void loadBrokerDetailUpdateResponse(String response){
      		DocumentRoot docRoot=
      		  (DocumentRoot) XMLTransformServiceFactory.INSTANCE.load(response);
      		BrokerServiceType brokerdetailUpdateRespRoot =  docRoot.getBrokerService();
      		//set the error type
      		brokerServiceRoot.setError(brokerdetailUpdateRespRoot.getError());
      	}



    3. 該方法向客戶端現有的策略清單中新增新的策略。ClientType 中的 createPolicy 方法建立新的 PolicyType 物件,並將其新增到現有 Policy 清單中。

      public void addNewPolicy(ClientType clientType){
      		clientType.createPolicy();
      	}



    4. 該方法刪除了客戶端現有策略清單中選中的策略。

      public void deleteSelectedPolicy(ClientType clientType){
                      for(int index=clientType.getPolicy().size()-1; index >= 0; --index){
                              PolicyType policyType = ((PolicyType)clientType.getPolicy().get(index));
                              if(policyType.getSelected()){
                                      clientType.getPolicy().remove(policyType);
                              }
                      }
              }



  6. 向頁程式碼中新增命令方法

    編輯 brokerupdate.jspBrokerupdate.java 頁程式碼檔案,並新增下列方法作為命令列為來使用。(這些方法中使用的控制資料訪問器在下一步中定義。)

    1. 該操作呼叫了 BrokerUpdateRoot.class 上的 addNewPolicy 方法以向現有的策略清單中新增新的策略行。當前的 Client 行是使用 Client 資料表的 rowData 檢索得到的。

      public String doAddNewPolicyAction(){
      		this.getVarBrokerUpdateRootBean().addNewPolicy((ClientType)getTable1().getRowData());
      		//returning empty string re-displays the page with same data binding
      		return "";
      	}
      



    2. 該操作呼叫了BrokerUpdateRoot.class上的 deleteSelectedPolicy 方法來刪除現有的策略清單上選中的策略。

      public String doDeleteSelectedPolicyAction(){
      		this.getVarBrokerUpdateRootBean().deleteSelectedPolicy((ClientType)getTable1().getRowData());
      		return "";
      	}
      



    3. 該操作反映了帶有任何資料改動的 Java bean,在此僅作演示之用。在實際的應用程式中,使用者在這裡可以進行一些資料處理,或者根本不需要這種方法。

      public String doUpdatePolicyAction(){
      		return "";
      	}
      



    4. 該操作呼叫了 BrokerUpdateRoot.class 上的 applyPolicyChanges 方法以將更新後的資料傳送給服務。varBrokerUpdateRootBean,會話的受 JSF 管理的會話範圍 bean,它將從該會話中移出,以便該 bean 從下一個呼叫的新資料中重新寫入。

      public String doApplyPolicyChangesAction(){
      		this.getVarBrokerUpdateRootBean().applyPolicyChanges();
      		this.sessionScope.remove("varBrokerUpdateRootBean");
      		//a navigation rule is defined for this return
      		return "applyChanges";
      	}
      



  7. 附加到頁資料的 Bean

    1. 在頁資料中配置 varBrokerUpdateRootBean 使其成為受 JSF 管理的 bean,並設定範圍為 session (圖 11)。這將使用者會話生命週期的 bean 例項。這樣有關策略的建立、更新或者刪除操作,將會繼續儲存在會話中,除非他們被應用到 Apply Changes 行為。
      圖 11. 配置頁資料中的 Java Bean
      配置頁資料中的 Java Bean
    2. 在頁資料中新增 varValidCodesRootBean 使其成為受 JSF 管理的 bean,並設定範圍為應用程式。這將快取應用程式例項生命週期的 bean 例項。
      圖 12. 配置頁資料中的 Java Bean
      配置頁資料中的 Java Bean

  8. 將頁上的控制繫結更新為頁資料中的 SDO 型別

    1. 選擇 Policy 資料表,並在其屬性中新增新列(圖 13)。將該列重新命名為 "Delete",並將其移動到列表的第一列。
      圖 13. 新增列
      新增列
    2. 從控制皮膚中拖動 checkbox,將其新增到新的表格列中(圖 14)。
      圖 14. 新增 Checkbox
      新增 Checkbox
    3. 從頁資料檢視中定義的策略 SDO 中拖動"selected"屬性,並且將其放到測量資料表中的 checkbox 上(圖 15)。
      圖 15. Checkbox 繫結
      Checkbox 繫結
    4. 向策略資料表中新增命令按鈕,並且將按鈕的標籤改為 "Add New Policy"(圖 16)。顯示出用於策略資料表的頁尾區,以便使用者能夠放置該命令按鈕。
      圖 16. 新增命令按鈕
      新增命令按鈕
    5. 將這個命令按鈕繫結到 doAddNewPolicyAction(圖 17)。如果沒有顯示 "action" 屬性,那麼就顯示資料表的所有屬性。
      圖 17. 將命令繫結到行為
      將命令繫結到行為
    6. 向策略資料表中新增命令按鈕,將該按鈕的標籤改為 "Delete Selected Policy"(圖 18),並將此按鈕繫結到 doDeleteSelectedPolicyAction(圖 19)。
      圖 18. 新增命令按鈕
      新增命令按鈕

      圖 19. 將命令繫結到行為
      將命令繫結到行為
    7. 向策略資料表中新增命令按鈕,將該按鈕的標籤改為 "Update Policy"(圖 20),並將該按鈕繫結到 doUpdatePolicyAction(圖 21)。
      圖 20. 新增命令按鈕
      新增命令按鈕

      圖 21. 將命令繫結到行為
      將命令繫結到行為
    8. 向客戶端資料表中新增命令按鈕,將該按鍵的標籤更改為 "Apply Changes"(圖 22),然後將此按鈕繫結到 doApplyPolicyChangesAction(圖 23)。(能顯示出表格的頁尾區來放置該命令按鈕。)
      圖 22. 新增命令按鈕
      新增命令按鈕

      圖 23. 將命令繫結到行為
      將命令繫結到行為
    9. 新增規則以轉到反映了這些策略改動的 brokersummary.jsp (圖 24)。
      圖 24. 新增結果規則
      新增結果規則
    10. 在客戶端資料表格中 "policy" 的前面新增新的 "TotalPolicyAmount" 列。拖動 JSF outputtext 控制,將其放到新列中(圖 25)。
      圖 25. 新增列
      新增列
    11. 從 varBrokerServiceRootBean 頁資料中拖動 totalPolicyAmount(圖 26),將其放到 outputtext 控制上(圖 27)。
      圖 26. 頁資料
      頁資料

      圖 27. 控制繫結
      控制繫結
    12. 在客戶端資料表中策略的前面新增新的 "State" 列。拖動 JSF dropdown 控制,將其放到新列中(圖 28)。
      圖 28. 新增 Dropdown
      新增 Dropdown
    13. 從頁資料裡的 varValidCodesRootBean 中拖動 fullName (圖 29),並且將其放到 dropdown 控制上(圖 30)。
      圖 29. 頁資料
      頁資料

      圖 30. Dropdown 繫結
      Dropdown 繫結

  9. 執行 brokerupdate.jsp

    1. 在 Application Developer 中,在 brokerupdate.jsp 上單擊右鍵,然後選擇 Run On Server。(如果沒有提示使用者啟動伺服器,那麼啟動伺服器後,然後在執行該頁之前將 XYZInsuranceEAR 專案新增到伺服器。)
    2. 測試容器中用於該頁的 URL 是(或者與之類似): http://localhost:9080/XYZInsuranceWeb/faces/brokerupdate.jsp.
      圖 31. brokerupdate.jsp
      brokerupdate.jsp
    3. 使用該頁上的多個按鈕來執行不同的操作(圖 32)。
      圖 32. brokerupdate.jsp
      brokerupdate.jsp

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14780828/viewspace-592653/,如需轉載,請註明出處,否則將追究法律責任。

相關文章