使用 Rational 加速基於 XML 的 SOA 的 JSF 開發二
我們的場景擴充套件了第 1 部分 中開發的保險應用程式,使之包括建立、更新以及刪除功能,本地附加的變數,基本的轉換和 下拉式繫結的功能。在該場景中:
- 我們假設 XYZ 保險公司有許多已註冊的代理人。
- 每個代理人都有許多客戶,並且每個客戶都同代理人簽訂了許多策略。
- 保險公司通過標準的 BrokerService 方案來展示代理人的服務(清單 1),並使用有效代服務 validCodesService schema(清單 2)進行檢索,例如有效的狀態碼。
- 任何來自代理人的通訊就是一個 XML 請求/響應,它服從清單 1 和清單 2 中的 schema 定義。(這些清單同樣也在下載檔案的 xsd_sdo_soa_part2_listings.zip 中的提供。)
清單 1. BrokerService.xsd
|
圖 1. BrokerService Schema 模型
清單 2. ValidCodesService.xsd
|
圖 2. ValidCodesService schema 模型
該場景為現有的 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 請求/響應資訊流
Listing 3. brokerUpdateRequest.xml
|
清單 4. brokerUpdateResponse.xml
|
清單 5. allValidCodesResponse.xml
|
圖 4 描繪了用於該場景的應用程式設計流。
圖 4. 應用程式設計流
|
一旦頁請求到來,就會發生以下事件 (圖 5):
- JSF 執行時將呼叫 BrokerUpdateRoot bean。
- BrokerUpdateRoot 將向 BrokerService 傳送 brokerDetailRequest.xml 來預載入資料。
- BrokerService 將已經被傳送到 XMLTransformServiceFactory 的響應作為 brokerDetailResponse.xml 傳送。
- XML 被轉換為封裝在 BrokerUpdateRoot bean 中的 SDO。
- JSF 執行時將呼叫 ValidCodesServiceRoot bean。
- ValidCodesServiceRoot Java™ bean 將呼叫 ValidCodesService 來預裝載這些資料。
- ValidCodesService 已經被傳送到 XMLTransformServiceFactory 的響應作為 allValidCodesResponse.xml 傳送。
- XML 被轉換為封裝在 ValidCodesServiceRoot bean 中的 SDO。
- JSF 執行時移交資料的控制權。
- 從 bean 中呼叫 XMLTransformServiceFactory。SDO 例項會傳送到 XMLTransformServiceFactory,並轉變成傳送到 BrokerService 的 brokerUpdateRequest.xml。
- 將 brokerUpdateResponse.xml 作為響應接收,並傳送到封裝在 BrokerUpdateRoot bean 中的 SDO。
圖 5. 執行時架構
在下面的章節中詳細描述了實現該解決方案的步驟:
- 匯入專案轉換
- 從 XSD schema 建立 SDO 包
- 向已經生成的 SDO 增添附加的屬性和行為
- 新增新的根 bean 封裝器
- 更新現有的根 bean 封裝器
- 向頁程式碼中增添命令方法
- 將 bean 附加到頁面資料
- 將頁面上繫結的控制元件修改為頁面資料的 SDO 型別
- 執行 brokerdetail.jsp。
- 匯入專案轉換
將專案轉換 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.jsp、brokersummary.jsp、BrokerUpdateRoot.java 和BrokerSummaryRoot.java 元件。
- XYZInsuranceService:包含了用於代理人服務和有效程式碼服務的 Java 類實現。該服務載入並且傳送了合適的基於服務方法請求的 XML 響應。這種基本實現用來模擬服務行為,其實現方法已經超出本文講述的範圍。
- XYZInsuranceServiceProxy:包括了用於呼叫代理人服務的 ServiceProxy 的基本實現。
圖 6. 專案轉換的匯入指南
- 建立來自 XSD 計劃的 SDO包
在 Application Developer 中,在 ValidCodesService.xsd 上單擊右鍵,然後選擇 Create SDO Package(圖 7)。
圖 7. 建立 SDO 包
因此,將產生如圖 8 所示的情景。
圖 8. 生成的 SDO 包
該包的名稱來自 targetNamespace,它在 XSD 宣告的 schema 中定義(圖 9)。
圖 9. TargetNamespace 宣告
- 向已經生成的 SDO 增添附加的屬性和行為
使用者可以修改已經生成的 SDO,使之包含特定的變數或者行為。當再次生成該 SDO 以用於同一個 schema 的名稱空間時,任何沒有使用 @generated 標籤註解的方法或者變數將不能被替換。使用者也可以將這樣的檔案標記為 non-derived 型別,以便專案 "clean" 時刪除這些檔案。
- 向策略 SDO 介面中新增 get/set 方法,xyz.brokerservice.PolicyType:
/** * Get the value for selected */ boolean getSelected(); /** * Set the value for selected */ void setSelected(boolean selected);
- 向策略 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; }
- 向客戶端 SDO 介面中新增獲取的方法,xyz.brokerservice.ClientType:
/** * TotalPolicyAmount is computed by summation of the client's Policy Amounts */ double getTotalPolicyAmount();
- 向客戶端 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; }
- 將已經改動的檔案標記為 non-derived,以便在專案“clean”期間保留這些改動(圖 10)。
圖 10. 更改派生屬性
- 向策略 SDO 介面中新增 get/set 方法,xyz.brokerservice.PolicyType:
- 新增新的根 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); } }
- 更新現有的根 bean 封裝器
更新 brokerservice.root 包中現有的BrokerUpdateRoot.java Java 類 ,該包提供了相關的下載檔案,或者更新帶有以下附加物的檔案:
- 下列方法通過使用框架 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); }
- 使用裝載 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()); }
- 該方法向客戶端現有的策略清單中新增新的策略。ClientType 中的 createPolicy 方法建立新的 PolicyType 物件,並將其新增到現有 Policy 清單中。
public void addNewPolicy(ClientType clientType){ clientType.createPolicy(); }
- 該方法刪除了客戶端現有策略清單中選中的策略。
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); } } }
- 向頁程式碼中新增命令方法
編輯 brokerupdate.jsp 的 Brokerupdate.java 頁程式碼檔案,並新增下列方法作為命令列為來使用。(這些方法中使用的控制資料訪問器在下一步中定義。)
- 該操作呼叫了 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 ""; }
- 該操作呼叫了BrokerUpdateRoot.class上的 deleteSelectedPolicy 方法來刪除現有的策略清單上選中的策略。
public String doDeleteSelectedPolicyAction(){ this.getVarBrokerUpdateRootBean().deleteSelectedPolicy((ClientType)getTable1().getRowData()); return ""; }
- 該操作反映了帶有任何資料改動的 Java bean,在此僅作演示之用。在實際的應用程式中,使用者在這裡可以進行一些資料處理,或者根本不需要這種方法。
public String doUpdatePolicyAction(){ return ""; }
- 該操作呼叫了 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"; }
- 附加到頁資料的 Bean
- 在頁資料中配置 varBrokerUpdateRootBean 使其成為受 JSF 管理的 bean,並設定範圍為 session (圖 11)。這將使用者會話生命週期的 bean 例項。這樣有關策略的建立、更新或者刪除操作,將會繼續儲存在會話中,除非他們被應用到 Apply Changes 行為。
圖 11. 配置頁資料中的 Java Bean
- 在頁資料中新增 varValidCodesRootBean 使其成為受 JSF 管理的 bean,並設定範圍為應用程式。這將快取應用程式例項生命週期的 bean 例項。
圖 12. 配置頁資料中的 Java Bean
- 將頁上的控制繫結更新為頁資料中的 SDO 型別
- 選擇 Policy 資料表,並在其屬性中新增新列(圖 13)。將該列重新命名為 "Delete",並將其移動到列表的第一列。
圖 13. 新增列
- 從控制皮膚中拖動 checkbox,將其新增到新的表格列中(圖 14)。
圖 14. 新增 Checkbox
- 從頁資料檢視中定義的策略 SDO 中拖動"selected"屬性,並且將其放到測量資料表中的 checkbox 上(圖 15)。
圖 15. Checkbox 繫結
- 向策略資料表中新增命令按鈕,並且將按鈕的標籤改為 "Add New Policy"(圖 16)。顯示出用於策略資料表的頁尾區,以便使用者能夠放置該命令按鈕。
圖 16. 新增命令按鈕
- 將這個命令按鈕繫結到 doAddNewPolicyAction(圖 17)。如果沒有顯示 "action" 屬性,那麼就顯示資料表的所有屬性。
圖 17. 將命令繫結到行為
- 向策略資料表中新增命令按鈕,將該按鈕的標籤改為 "Delete Selected Policy"(圖 18),並將此按鈕繫結到 doDeleteSelectedPolicyAction(圖 19)。
圖 18. 新增命令按鈕
圖 19. 將命令繫結到行為
- 向策略資料表中新增命令按鈕,將該按鈕的標籤改為 "Update Policy"(圖 20),並將該按鈕繫結到 doUpdatePolicyAction(圖 21)。
圖 20. 新增命令按鈕
圖 21. 將命令繫結到行為
- 向客戶端資料表中新增命令按鈕,將該按鍵的標籤更改為 "Apply Changes"(圖 22),然後將此按鈕繫結到 doApplyPolicyChangesAction(圖 23)。(能顯示出表格的頁尾區來放置該命令按鈕。)
圖 22. 新增命令按鈕
圖 23. 將命令繫結到行為
- 新增規則以轉到反映了這些策略改動的 brokersummary.jsp (圖 24)。
圖 24. 新增結果規則
- 在客戶端資料表格中 "policy" 的前面新增新的 "TotalPolicyAmount" 列。拖動 JSF outputtext 控制,將其放到新列中(圖 25)。
圖 25. 新增列
- 從 varBrokerServiceRootBean 頁資料中拖動 totalPolicyAmount(圖 26),將其放到 outputtext 控制上(圖 27)。
圖 26. 頁資料
圖 27. 控制繫結
- 在客戶端資料表中策略的前面新增新的 "State" 列。拖動 JSF dropdown 控制,將其放到新列中(圖 28)。
圖 28. 新增 Dropdown
- 從頁資料裡的 varValidCodesRootBean 中拖動 fullName (圖 29),並且將其放到 dropdown 控制上(圖 30)。
圖 29. 頁資料
圖 30. Dropdown 繫結
- 執行 brokerupdate.jsp
- 在 Application Developer 中,在 brokerupdate.jsp 上單擊右鍵,然後選擇 Run On Server。(如果沒有提示使用者啟動伺服器,那麼啟動伺服器後,然後在執行該頁之前將 XYZInsuranceEAR 專案新增到伺服器。)
- 測試容器中用於該頁的 URL 是(或者與之類似): http://localhost:9080/XYZInsuranceWeb/faces/brokerupdate.jsp.
圖 31. brokerupdate.jsp
- 使用該頁上的多個按鈕來執行不同的操作(圖 32)。
圖 32. brokerupdate.jsp
- 下列方法通過使用框架 API 以將資料物件轉變為 XML 字串的方式向服務傳送這些更新,從而更新 broker 資訊。轉變 API 的第 2 個引數確保所有的空屬性將不屬於序列化 XML 的一部分。如果這樣的元素宣告被接收端的 XML 處理器接收,那麼使用者就可以使用轉變 API 的其他實現。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14780828/viewspace-592653/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spring基於XML方式的使用SpringXML
- 基於ecshop的二次開發
- 基於SOA 的儲存管理
- IOS 特定於裝置的開發:基於加速計的滾動檢視iOS
- 基於gin的golang web開發:路由二GolangWeb路由
- IOS 特定於裝置的開發:使用加速能力“向上定位”iOS
- 使用 TreeQL 加速你的 API 開發API
- 基於 SOA 的工作流(WF)整合
- 基於事件的 SOA 治理解決方案事件
- SharePoint Framework 基於團隊的開發(二)Framework
- 基於 solox 二次開發
- 基於 SOA 的未來保險運營模式模式
- 如何開發一個基於 Vue 的 ui 元件庫(二)VueUI元件
- 基於c++的排雷小遊戲二次開發C++遊戲
- ERP與SOA結合:基於SOA的ERP體系架構架構
- 基於 Hyperf 開發的商城
- 基於Github的敏捷開發Github敏捷
- 基於TODO的開發方法
- Gavin King真正走上EJB路線,推出基於JSF/EJB3的快速開發框架JBoss SeamJS框架
- IOS 特定於裝置的開發:使用加速器啟動螢幕上的物件iOS物件
- 基於SRAM的方法可加速AI推理AI
- MyBatis基於xml檔案的 CURD案例MyBatisXML
- 基於 DOM 的 XML 檔案解析類XML
- 自定義基於XML的驗證器XML
- 基於xml的Spring多資料來源配置和使用XMLSpring
- 基於Chappie-II的二次開發日誌-1APP
- 基於Chappie-II的二次開發日誌-2APP
- 使用 Flutter 加速應用開發Flutter
- 基於WDF的驅動開發
- Web快速開發平臺,基於二次開發平臺Web
- Jmeter二次開發——基於Java請求JMeterJava
- 使用 SOA 技術實現既有資產的開發和重組(上)
- 使用 SOA 技術實現既有資產的開發和重組(下)
- 基於XML的購物車的實現(轉)XML
- 面向構件的開發:SCA還是SOA?
- 基於 CruiseControl 和 Rational 統一變更管理實現的軟體開發中的自動化持續構建UI
- 一個基於django框架的SQL 稽核系統二次開發Django框架SQL
- 基於Gin框架的web後端開發(二): JSON資料生成框架Web後端JSON