随笔 - 181, 文章 - 2, 评论 - 85, 引用 - 0
数据加载中……

使用 Rational Application Developer 和 WebSphere Application Server 来加速基于 XML 的 SOA 的 JSF 开发——第 2 部分

本文提出了加快基于 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 模型
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 模型
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

												
														<?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):

  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







结束语

在该系列文章的第 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

posted on 2006-04-17 03:17 wsdfsdf 阅读(273) 评论(0)  编辑 收藏 引用 所属分类: 技术文章


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理