本文提出了加快基于 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 部分 中开发的保险应用程序,使之包括创建、更新以及删除功能,本地附加的变量,基本的转换和 下拉式绑定的功能。在该场景中:
- 我们假设 XYZ 保险公司有许多已注册的代理人。
- 每个代理人都有许多客户,并且每个客户都同代理人签订了许多策略。
- 保险公司通过标准的 BrokerService 方案来展示代理人的服务(清单 1),并使用有效代服务 validCodesService schema(清单 2)进行检索,例如有效的状态码。
- 任何来自代理人的通信就是一个 XML 请求/响应,它服从清单 1 和清单 2 中的 schema 定义。(这些清单同样也在下载文件的
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>
|
图 1. BrokerService 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>
|
图 2. 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 请求/响应信息流
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 描绘了用于该场景的应用程序设计流。
图 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. 更改派生属性
-
添加新的根 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

|
|
结束语
在该系列文章的第 2 部分中,我们描述了加速开发用于基于 XML 的应用程序的 JSF 的解决方案。这个解决方案提供了 Eclipse 功能以及框架工具,在设计时可用其将 XML Schema 转换成包括静态服务对象数据的 Java 包,在运行时可用其将 XML 实例文件与这些 SDO 相互转化。SDO 包装成 JavaBean,连同 JavaServer Faces 一起被用于表示开发。本文也提供了扩展保险应用程序的基本场景所需的通用步骤,该应用程序包括新建、更新以及删除的功能,本地附加的变量,基本的转换和下拉式绑定。这些增强实现了单一页面中多 schema 模型和多个请求及响应的场景。
在该系列文章中将介绍:
- 第 3 部分将描述操作已生成的 SDO 以及自定义 XML-SDO 转换器的高级技术。它也提供了聚集方法(sun、mean、average 等)的工具,这些方法是对SDO 对象及集合的一般操作。
- 第 4 部分重在使用 XSDO SDO 转换功能进行基于 XML 的 SOA 的 portlet 开发,为 JSR 168 portlet 新建的对象寻址、portlet 的参数传递,以及在任何其他 portlet 中的 portlet 动作上动态地设置对象 portlet 视图。
- 第 5 部分将讨论使用 XSDO SDO 转换功能使 JSF 及基于 XML 的 SOA 的 portlet 应用程序局部化,并且提出基于首选地点显示的静态及动态内容。
下载
描述 |
名字 |
大小 |
下载方法 |
Download file 1 |
xsd_sdo_soa_xml_sample.zip |
766 KB |
FTP | HTTP |
Download file 2 |
xsd_sdo_soa_xml_tutorial.zip |
738 KB |
FTP | HTTP |
Download file 3 |
xsdsdotransform-feature.zip |
50 KB |
FTP | HTTP |
Download file 4 |
XYZInsuranceEAR.zip |
764 KB |
FTP | HTTP |
Download file 5 |
xsd_sdo_soa_part1_listings.zip |
8 KB |
FTP | HTTP |