本文提出了加快基于 XML 的面向服务的体系结构(Service Oriented Architecture,SOA)应用程序表示开发的解决方案系列文章的第 2 部分。这种解决方案包括 Eclipse 功能,可以生成静态类型的用于 XSD Schema 的服务对象数据(Service Data Object,SDO),并提供了在表示元素数据与 XML 数据相互转换中使用 SDO 的运行框架。第 2 部分增强了在第 1 部分中开发的解决方案。
引言
这个由五部分组成的系列文章提出了能够加快基于 XML 的 SOA 应用程序表示开发的解决方案,这种解决方案包括 Eclipse 功能,可以生成静态类型的用于 XSD Schema 的服务对象数据(Service Data Object,SDO),并提供了在表示元素数据与 XML 数据相互转换中使用 SDO 的运行框架。在该系列文献的 第 1 部分 中,我们经历了通过使用提供的插件集来向每个指定的 XML schema 中的服务传递信息的简单 JSF 应用程序的整个开发过程,我们使用的应用程序场景进行了一次服务调用——发出一个 XML 请求及收到一个 XML 响应。这个应用程序说明了主从复合结构的数据对象视图,连同分页及分类的能力。
在第 2 部分中,我们将扩展在 第 1 部分 中开发的解决方案,使之包括创建、更新和删除功能,包括用本地附加的变量及基本的转换来自定义生成 SDO。该文章将举例说明多 schema 模型、对于单一页面中多个请求及响应的场景,并且说明绑定 XML 数据的 JSF 下拉式控制。
IBM® Rational® Application Developer V6 以及 Websphere® Application Server V6 需要利用这种转换功能。本文假定读者是精通 Rational Application Developer 的 JSF 页面设计师。
安装 XSD SDO 转换功能
为了安装 XSD SDO 的转换功能,请按照 第 1 部分 中的详细步骤操作。
场景
我们的场景扩展了第 1 部分 中开发的保险应用程序,使之包括创建、更新以及删除功能,本地附加的变量,基本的转换和 下拉式绑定的功能。在该场景中:
xsd_sdo_soa_part2_listings.zip
清单 1. BrokerService.xsd
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http:///xyz.brokerservice.ecore" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http:///xyz.brokerservice.ecore"> <xsd:annotation> <xsd:documentation xml:lang="en"> Broker Service Schema for xyz.com. Copyright 2004 ibm.com. All rights reserved. </xsd:documentation> </xsd:annotation> <xsd:element name="brokerService" type="brokerServiceType"/> <xsd:complexType name="brokerServiceType"> <xsd:sequence> <xsd:element minOccurs="0" name="broker" type="brokerType"/> <xsd:element minOccurs="0" name="error" type="errorType"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="brokerType"> <xsd:sequence> <xsd:element minOccurs="0" ref="firstName"/> <xsd:element minOccurs="0" ref="lastName"/> <xsd:element minOccurs="0" name="loginName" type="xsd:string"/> <xsd:element minOccurs="0" name="loginPassword" type="xsd:string"/> <xsd:element maxOccurs="unbounded" minOccurs="0" name="client" type="clientType"/> </xsd:sequence> <xsd:attribute name="brokerId" type="xsd:string" use="required"/> </xsd:complexType> <xsd:complexType name="clientType"> <xsd:sequence> <xsd:element minOccurs="0" ref="firstName"/> <xsd:element minOccurs="0" ref="lastName"/> <xsd:element minOccurs="0" name="dateOfBirth" type="xsd:date"/> <xsd:element minOccurs="0" name="currentAddress" type="addressType"/> <xsd:element minOccurs="0" name="permanentAddress" type="addressType"/> <xsd:element maxOccurs="unbounded" minOccurs="0" name="policy" type="policyType"/> </xsd:sequence> <xsd:attribute name="clientId" type="xsd:string" use="required"/> </xsd:complexType> <xsd:complexType name="addressType"> <xsd:sequence> <xsd:element name="street" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> <xsd:element name="state" type="xsd:string"/> <xsd:element name="zip" type="xsd:string"/> <xsd:element name="country" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="policyType"> <xsd:sequence> <xsd:element name="policyName" type="xsd:string"/> <xsd:element name="policyStartDate" type="xsd:date"/> <xsd:element name="policyEndDate" type="xsd:date"/> <xsd:element name="policyAmount" type="xsd:string"/> <xsd:element name="policyDescription" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="policyId" type="xsd:string" use="required"/> </xsd:complexType> <xsd:complexType name="errorType"> <xsd:sequence> <xsd:element name="errorCode" type="xsd:string"/> <xsd:element name="errorDescription" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:element name="firstName" type="xsd:string"/> <xsd:element name="lastName" type="xsd:string"/> </xsd:schema>
清单 2. ValidCodesService.xsd
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http:///xyz.validcodesservice.ecore" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http:///xyz.validcodesservice.ecore"> <xsd:annotation> <xsd:documentation xml:lang="en"> Valid Codes Service Schema for xyz.com. Copyright 2004 ibm.com. All rights reserved. </xsd:documentation> </xsd:annotation> <xsd:element name="validCodesService" type="validCodesServiceType"/> <xsd:complexType name="validCodesServiceType"> <xsd:sequence> <xsd:element minOccurs="0" name="stateList" type="stateListType"/> <xsd:element minOccurs="0" name="policyCodeList" type="policyCodeListType"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="stateListType"> <xsd:sequence> <xsd:element maxOccurs="unbounded" minOccurs="0" name="state" type="stateType"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="stateType"> <xsd:sequence> <xsd:element name="shortName" type="xsd:string"/> <xsd:element name="fullName" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="policyCodeListType"> <xsd:sequence> <xsd:element maxOccurs="unbounded" minOccurs="0" name="policyCode" type="policyCodeType"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="policyCodeType"> <xsd:sequence> <xsd:element name="shortName" type="xsd:string"/> <xsd:element name="fullName" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd: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 页在检索来自服务更新后的改动之后将显示出来。
brokerupdate.jsp
brokerDetailRequest.xml
brokerDetailResponse.xml
allValidCodesResponse.xml
brokerUpdateRequest.xml
brokerUpdateResponse.xml
brokersummary.jsp
Listing 3. brokerUpdateRequest.xml
<?xml version="1.0" encoding="UTF-8"?> <brokerService xmlns="http:///xyz.brokerservice.ecore" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > <broker brokerId="000-00-9999"> <firstName>Narinder</firstName> <lastName>Makin</lastName> <client clientId="001-00-9999"> <firstName>Dan</firstName> <lastName>Moore</lastName> <dateOfBirth>1967-08-13</dateOfBirth> <currentAddress> <street>113 Oak Pine St.</street> <city>Santa Clara</city> <state>LA</state> <zip>91929</zip> <country>US</country> </currentAddress> <permanentAddress> <street>123 Demi Lane</street> <city>Cary</city> <state>NC</state> <zip>22999</zip> <country>US</country> </permanentAddress> <policy policyId="L000000000"> <policyName>Life</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>200000.00</policyAmount> <policyDescription>Life Insurance</policyDescription> </policy> <policy policyId="H000000000"> <policyName>House</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>20000.00</policyAmount> <policyDescription>Home Insurance</policyDescription> </policy> <policy policyId="C000000001"> <policyName>Car 1</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>15000.00</policyAmount> <policyDescription>Car Insurance - Ferrari 2004 - Primary Car </policyDescription> </policy> <policy policyId="C000000002"> <policyName>Car 2</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>5000.00</policyAmount> <policyDescription>Car Insurance - Lexus 2003 - Secondary Car </policyDescription> </policy> <policy policyId="B000000002"> <policyName>Restaurant</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>25000.00</policyAmount> <policyDescription>Business Insurance - Restaurant</policyDescription> </policy> <policy policyId="B000000003"> <policyName>Golf Course</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>25000.00</policyAmount> <policyDescription>Second Business Insurance - Golf Course</policyDescription> </policy> </client> <client clientId="002-00-9999"> <firstName>Tom</firstName> <lastName>Cross</lastName> <dateOfBirth>1970-11-11</dateOfBirth> <currentAddress> <street>113 Duke St.</street> <city>Shelton</city> <state>CT</state> <zip>08989</zip> <country>US</country> </currentAddress> <permanentAddress> <street>123 Lex Lane</street> <city>Fairfield</city> <state>NY</state> <zip>09833</zip> <country>US</country> </permanentAddress> <policy policyId="L100000000"> <policyName>Life</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>100000.00</policyAmount> <policyDescription>Life Insurance</policyDescription> </policy> <policy policyId="H100000000"> <policyName>House</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>2000.00</policyAmount> <policyDescription>Home Insurance</policyDescription> </policy> <policy policyId="C100000001"> <policyName>Car 1</policyName> <policyStartDate>2004-01-01</policyStartDate> <policyEndDate>2005-01-01</policyEndDate> <policyAmount>2000.00</policyAmount> <policyDescription>Car Insurance - Camry 2004 - Primary Car </policyDescription> </policy> </client> </broker> </brokerService>
清单 4. brokerUpdateResponse.xml
<?xml version="1.0" encoding="UTF-8"?> <brokerService xmlns="http:///xyz.brokerservice.ecore" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <broker brokerId="099-99-9999"/> <error> <errorCode>0</errorCode> <errorDescription>Success: The changes have been successfully applied to the policy.</errorDescription> </error> </brokerService>
清单 5. allValidCodesResponse.xml
<?xml version="1.0" encoding="UTF-8"?> <validCodesService xmlns="http:///xyz.validcodesservice.ecore" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <stateList> <state> <shortName>CT</shortName> <fullName>Connecticut</fullName> </state> <state> <shortName>LA</shortName> <fullName>Los Angelas</fullName> </state> <state> <shortName>NC</shortName> <fullName>North Carolina</fullName> </state> <state> <shortName>CA</shortName> <fullName>California</fullName> </state> <state> <shortName>NH</shortName> <fullName>New Hampshire</fullName> </state> <state> <shortName>VA</shortName> <fullName>Virginia</fullName> </state> </stateList> <policyCodeList> <policyCode> <shortName>H</shortName> <fullName>House</fullName> </policyCode> <policyCode> <shortName>C</shortName> <fullName>Car</fullName> </policyCode> <policyCode> <shortName>B</shortName> <fullName>Business</fullName> </policyCode> </policyCodeList> </validCodesService>
应用程序设计流
图 4 描绘了用于该场景的应用程序设计流。
运行时架构
一旦页请求到来,就会发生以下事件 (图 5):
实现解决方案
在下面的章节中详细描述了实现该解决方案的步骤:
将项目转换 xsd_sdo_soa_xml_tutorial.zip 下载文件 导入到 Application Developer 的工作区中。因此,下面的项目将被导入(图 6):
xsd_sdo_soa_xml_tutorial.zip
BrokerService.xsd
BrokerUpdateRoot.java
BrokerSummaryRoot.java
在 Application Developer 中,在 ValidCodesService.xsd 上单击右键,然后选择 Create SDO Package(图 7)。
因此,将产生如图 8 所示的情景。
该包的名称来自 targetNamespace,它在 XSD 声明的 schema 中定义(图 9)。
用户可以修改已经生成的 SDO,使之包含特定的变量或者行为。当再次生成该 SDO 以用于同一个 schema 的命名空间时,任何没有使用 @generated 标签注解的方法或者变量将不能被替换。用户也可以将这样的文件标记为 non-derived 类型,以便项目 "clean" 时删除这些文件。
@generated
xyz.brokerservice.PolicyType
/** * Get the value for selected */ boolean getSelected(); /** * Set the value for selected */ void setSelected(boolean selected);
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; }
xyz.brokerservice.ClientType
/** * TotalPolicyAmount is computed by summation of the client's Policy Amounts */ double getTotalPolicyAmount();
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; }
ValidCodesServiceRoot.java 文件包含了计划命名空间 URI 的注册,用于有效代码服务的属性和它的获取/设置方法。通过调用这些有效的代码服务来慢慢地装载所有有效的代码。在 brokerservice.root 包中添加 ValidCodesServiceRoot.java Java 类:
ValidCodesServiceRoot.java
brokerservice.root
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); } }
更新 brokerservice.root 包中现有的BrokerUpdateRoot.java Java 类 ,该包提供了相关的下载文件,或者更新带有以下附加物的文件:
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); }
protected void loadBrokerDetailUpdateResponse(String response){ DocumentRoot docRoot= (DocumentRoot) XMLTransformServiceFactory.INSTANCE.load(response); BrokerServiceType brokerdetailUpdateRespRoot = docRoot.getBrokerService(); //set the error type brokerServiceRoot.setError(brokerdetailUpdateRespRoot.getError()); }
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 页代码文件,并添加下列方法作为命令行为来使用。(这些方法中使用的控制数据访问器在下一步中定义。)
Brokerupdate.java
BrokerUpdateRoot.class
public String doAddNewPolicyAction(){ this.getVarBrokerUpdateRootBean().addNewPolicy((ClientType)getTable1().getRowData()); //returning empty string re-displays the page with same data binding return ""; }
public String doDeleteSelectedPolicyAction(){ this.getVarBrokerUpdateRootBean().deleteSelectedPolicy((ClientType)getTable1().getRowData()); return ""; }
public String doUpdatePolicyAction(){ return ""; }
public String doApplyPolicyChangesAction(){ this.getVarBrokerUpdateRootBean().applyPolicyChanges(); this.sessionScope.remove("varBrokerUpdateRootBean"); //a navigation rule is defined for this return return "applyChanges"; }
http://localhost:9080/XYZInsuranceWeb/faces/brokerupdate.jsp
结束语
在该系列文章的第 2 部分中,我们描述了加速开发用于基于 XML 的应用程序的 JSF 的解决方案。这个解决方案提供了 Eclipse 功能以及框架工具,在设计时可用其将 XML Schema 转换成包括静态服务对象数据的 Java 包,在运行时可用其将 XML 实例文件与这些 SDO 相互转化。SDO 包装成 JavaBean,连同 JavaServer Faces 一起被用于表示开发。本文也提供了扩展保险应用程序的基本场景所需的通用步骤,该应用程序包括新建、更新以及删除的功能,本地附加的变量,基本的转换和下拉式绑定。这些增强实现了单一页面中多 schema 模型和多个请求及响应的场景。
在该系列文章中将介绍:
下载
posted on 2006-04-17 03:17 wsdfsdf 阅读(281) 评论(0) 编辑 收藏 引用 所属分类: 技术文章
Powered by: C++博客 Copyright © wsdfsdf