このサンプルで、HTML データ・ハンドラーは着信 HTML 照会ストリングを IBM WebSphere Business Integration Server Express and Express Plus ビジネス・オブジェクトに変換します。IBM WebSphere データ・ハンドラー機能の詳細については、「IBM WebSphere Business Integration Server Express and Express Plus データ・ハンドラー・ガイド」を参照してください。次に、データ・ハンドラー・コンポーネントのうち、特に重要な機能を示します。
図 10 に、クライアント・ブラウザー上に表示された HTML ページを示します。HTML データ・ハンドラーは、このページのテキスト・ボックスに関連付けられたプロパティーに依存します。
図 10 で、それぞれのテキスト・ボックスには、HTML プロパティーが関連付けられています。HTML テキスト・ボックス・プロパティーには、IBM WebSphere Business Integration Server Express and Express Plus ビジネス・オブジェクト文法が格納されています。この文法に従って、HTML データ・ハンドラーは、プロパティーに関連付けられたデータをビジネス・オブジェクトに変換することができます。
例えば、最初の品目に関連付けられたプロパティーは、次のとおりです。
図 11 に示すように、データ・ハンドラーは HTML ページ上のデータを、子 (orderQty、deliveryDate など) ビジネス・オブジェクト付きの階層型 SalesQuote ビジネス・オブジェクトに変換します。
IBM WebSphere Business Integration Server Express and Express Plus ソフトウェアでは、2 つのトップレベル・データ・ハンドラー・メタオブジェクトが提供されます。1 つはサーバー用で、1 つはコネクター用です。さらに、それぞれのデータ・ハンドラーごとに子メタオブジェクトが用意されています。この子メタオブジェクトのいくつかは、IBM WebSphere Business Integration Server Express and Express Plus ソフトウェアに添付されています。環境を構成するとき、次を行うことができます。
サーバー・アクセスのコンテキストで呼び出されるデータ・ハンドラーで使用されるトップレベル・データ・ハンドラー・メタオブジェクトは、MO_Server_DataHandler です。
トップレベル・メタオブジェクトの属性を、MIME タイプ、およびサポートを希望する任意のサブタイプ (BOPrefix) 用に定義します。この属性は子メタオブジェクトを表します。この子メタオブジェクトには、その作業を行うのにデータ・ハンドラーが必要とする、クラス名と構成プロパティーを提供する属性があります。
図 12 に、2 つのメタオブジェクトのテキスト・フォーマットを示します。
このメタオブジェクトには、HTML データ・ハンドラー (text.html) によってサポートされる MIME 用に名前付けされた属性が格納されています。この属性は、HTML データ・ハンドラー MO_DataHandler_DefaultHtmlConfig 用の子データ・ハンドラー・メタオブジェクトを表します。
子メタオブジェクトは ClassName 属性を宣言します。この属性の DefaultValue 属性プロパティーには、HTML データ・ハンドラーの起動に使用するデータ・ハンドラー・クラス (com.crossworlds.DataHandlers.Html.HtmlDataHandler) の名前がリストされます。
図 12. HTML メタオブジェクトのテキスト・フォーマット
[BusinessObjectDefinition] Name = MO_Server_DataHandler Version = 1.0.0 [Attribute] Name = text.html Type = MO_DataHandler_DefaultHtmlConfig ContainedObjectVersion = 1.0.0 Relationship = Containment Cardinality = 1 MaxLength = 1 IsKey = true IsForeignKey = false IsRequired = false IsRequiredServerBound = false [End] [Attribute] Name = ObjectEventId Type = String MaxLength = 255 IsKey = false IsForeignKey = false IsRequired = false IsRequiredServerBound = false [End] [Verb] Name = Create [End] [Verb] Name = Delete [End] [Verb] Name = Retrieve [End] [Verb] Name = Update [End] [End]
<?xml version="1.0" encoding="utf-8" standalone="no"?> <xsd:schema elementFormDefault="qualified" targetNamespace="http://www.ibm.com/websphere" xmlns:bx="http://www.ibm.com/websphere" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:annotation><xsd:documentation>
Tue Mar 11 14:25:46 PST 2003
</xsd:documentation>
</xsd:annotation>
<xsd:element name="TestChildBO">d <xsd:annotation> <xsd:appinfo> <bx:boDefinition version="3.0.0" /> </xsd:appinfo> </xsd:annotation> <xsd:complexType><xsd:sequence> <xsd:element name="FirstName" minOccurs="0"> <xsd:annotation> <xsd:appinfo> <bx:boAttribute> <bx:attributeInfo isForeignKey="false" isKey="false" /> </bx:boAttribute> </xsd:appinfo> </xsd:annotation> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:maxLength value="255" /> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="LastName" minOccurs="1"> <xsd:annotation> <xsd:appinfo><bx:boAttribute> <bx:attributeInfo isForeignKey="false" isKey="true" /> </bx:boAttribute> |</xsd:appinfo> </xsd:annotation> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:maxLength value="255" /> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="ObjectEventId" type="xsd:string" minOccurs="0" /> </xsd:sequence> <xsd:attribute name="version" type="xsd:token" default="0.0.0" /> <xsd:attribute name="delta" type="xsd:boolean" default="false" /> <xsd:attribute name="verb" use="required"><xsd:simpleType> <xsd:restriction base="xsd:NMTOKEN"> <xsd:enumeration value="Create" /> <xsd:enumeration value="Delete" /> <xsd:enumeration value="Retrieve" /> <xsd:enumeration value="Update" /> </xsd:restriction> </xsd:simpleType> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:schema>
以下は HTML データ・ハンドラーの Java コード・サンプルです。
/** * @(#) HtmlDataHandler.java * * Copyright (c) 1997-2000 CrossWorlds Software, Inc. * All rights reserved. * * This software is the confidential and proprietary information of IBM, Inc. * You shall not disclose such Confidential information and shall * use it only in accordance with the terms of the license agreement you entered into * with CrossWorlds Software. */ import com.crossworlds.DataHandlers.*; import com.crossworlds.DataHandlers.Exceptions.*; import AppSide_Connector.JavaConnectorUtil; import CxCommon.BusinessObjectInterface; // java classes import java.util.*; import java.io.*; /** ** This is a html data handler which converts a html query ** string to a Crossworlds Business object. This example is ** assumes the incoming html query is structured in a specific ** format as explained in the program below. See the comments ** associated with the method parse() in this class. */ public class HtmlDataHandler extends DataHandler { /* ** A utility method to convert a HTML query string into a crossworlds BO. ** See comments associated with the parse() method for a detailed explanation ** @param String serializeddata ** @param Object the incoming mime type */ public BusinessObjectInterface getBO(String serializedData, Object config) throws Exception { HashMap nameValuePairs = parse((String) serializedData); /* ** Get the BO to be created from the hidden tag BusObjName */ String boName = (String) nameValuePairs.get("BusObjName"); if (boName == null) throw new Exception("Unable to find business object name in " + "serialized business object"); BusinessObjectInterface bo = JavaConnectorUtil.createBusinessObject(boName); String verb = (String) nameValuePairs.get("Verb"); if (verb == null) throw new Exception("Unable to find verb in serialized business object"); bo.setVerb(verb); /* ** Get the elements from the HashMap and set it into the BO */ setValues(bo, nameValuePairs); return bo; } /* ** Parse an HTML query string looking for tokens of the form &name=value. ** The format of the incoming query string must conform to the &name=value ** format as well as the following semantics: ** if name does not contain syntax of the form name[X].attribute it is ** assumed to be the name of an attribute in the parent object otherwise ** the expression will be used AS IS to set the value of a child object ** and attribute. ** ** For example, the following query string can be successfully parsed by ** this method: ** ** CustomerID=&items[0].itemID=44&items[0].orderQty=25&items[0]. ** deliveryDate1=12/12/00 ** &items[1].itemID=67&items[1].orderQty=2&items[1]. ** deliveryDate=12/12/00&Verb=Retrieve& ** BusObjName=SalesQuote&SubObjName=CwItem ** ** ** @param String query sent from the webserver to be parsed ** @return HashMap a hash map containing the name value pairs */ private HashMap parse(String queryString) { HashMap nameValuePairs = new HashMap(); String content = queryString.replace('+', ' '); StringTokenizer st = new StringTokenizer(content,"&"); while (st.hasMoreTokens()) { String token = st.nextToken(); int i = token.indexOf("="); String name = token.substring(0, i); String value = token.substring(i+1); /* ** HTTP will encode certain ASCII values as their hex equivalents. ** Convert any of these encodings back to ASCII for both the name ** and the value strings (i.e. right hand side of = and left hand ** side of =) */ name = replaceHexEncodedWithAscii(name); value = replaceHexEncodedWithAscii(value); /* ** Store these value in the hashmap so that our caller can look ** them up. */ nameValuePairs.put(name, value); } return(nameValuePairs); } /* * Given a Hashmap of name/value pairs, enumerate through the business * object and set each attribute in the BO with the corresponding * value from the Hashtable * @param IBusinessObject target of the set * @param Hashmap contains the name/value pairs */ private void setValues(BusinessObjectInterface bo, HashMap nameValuePairs) throws Exception { String SubObjName = null; Iterator aIterator = nameValuePairs.keySet().iterator(); // Save the SubObject name so we need to save it while (aIterator.hasNext()) { String name = (String) aIterator.next(); /* ** Ignore any hidden keywords that we parsed out of the HTML and ** stored in the hash map */ if (name.equalsIgnoreCase("BusObjName") || name.equalsIgnoreCase("Verb") || name.equalsIgnoreCase("SubObjName") || name.equalsIgnoreCase("ContainerAttrName")) { System.out.println("Skipping Item : " + name); continue; } /* ** All subobjects have a grammar in the form of object[X].attribute ** where X is the index of the contained subobject. Therefore, if ** the name does not have this embedded string, it's an attribute ** of the parent object */ if (name.indexOf("[") == -1) bo.setAttrValue(name, (String) nameValuePairs.get(name)); else bo.setAttributeWithCreate(name, (String) nameValuePairs.get(name)); } } /* * Replace any hex encoded bytes with the ASCII char equivalent and return * the new string to the caller. * @param name The string to convert. */ private String replaceHexEncodedWithAscii(String name) { int nameLength = name.length(); /* ** Replace any hex values (HTTP may send over a hex value int ** the form of %XX for certain characters) with their ** corresponding char equivalents */ StringBuffer nameBuffer = new StringBuffer(); for (int i = 0; i < nameLength; ++i) { char c = name.charAt(i); switch (c) { case '%': byte[] b = { Byte.parseByte(name.substring(i+1, i+3), 16) }; nameBuffer.append(new String(b)); i += 2; break; default: nameBuffer.append(c); } } return(nameBuffer.toString()); } /** ** Implementation of abstract methods in the Data Handler class ** @param BusinessObjectInterface the actual business object ** @param Object config ** @return String string representation of the BO */ public String getStringFromBO(BusinessObjectInterface theObj, Object config) throws Exception { throw new Exception("Not implemented"); } /** ** Implementation of abstract methods in the Data Handler class * @param Reader actual data * @param BusinessObjectInterface the actual business object * @param Object config */ public void getBO(Reader serializedData, BusinessObjectInterface theObj, Object config) throws Exception { throw new Exception("Not Implemented"); } /** ** Implementation of abstract methods in the Data Handler class * @param String actual data * @param BusinessObjectInterface the actual business object * @param Object config */ public void getBO(String serializedData, BusinessObjectInterface theObj, Object config) throws Exception { throw new Exception("Not Implemented"); } /** ** Implementation of abstract methods in the Data Handler class * @param BusinessObjectInterface the actual business object * @return InputStream a handle to the stream */ public InputStream getStreamFromBO(BusinessObjectInterface theObj, Object config) throws Exception { throw new Exception("Not Implemented"); } /** ** Implementation of abstract methods in the Data Handler class * @param Reader actual data * @param BusinessObjectInterface the actual business object * @return BusinessObjectInterface the translated BO */ public BusinessObjectInterface getBO(Reader serializedData, Object config) throws Exception { throw new Exception("Not Implemented"); } }