WebLogic Web サービス プログラマーズ ガイド
![]() |
![]() |
![]() |
![]() |
この章では、WebLogic Web サービスにおける非組み込みデータ型の使い方について説明します。
パラメータおよび戻り値に非組み込みデータ型が使用される WebLogic Web サービスを作成することができます。非組み込みデータ型は、サポートされている組み込みデータ型以外のデータ型として定義されます。例としては、int
や String
があります。組み込みデータ型の詳細なリストについては、「サポートされる組み込みデータ型」を参照してください。
WebLogic Server は、組み込みデータ型の XML 表現と Java 表現間の変換を透過的に処理します。Web サービスのオペレーションが非組み込みデータ型を使用する場合は、WebLogic Server によって変換が実行されるように、以下の情報を入力する必要があります。
web-services.xml
デプロイメント記述子ファイルにあるデータ型マッピング情報WebLogic Server には、servicegen
Ant タスクおよび autotype
Ant タスクが入っていて、作成した Web サービスのステートレス セッション EJB または Java クラス バックエンド コンポーネントを参照することにより、前述のコンポーネントを自動的に生成します。これらの Ant タスクは、さまざまな非組み込みデータ型を処理できるので、一般的には、プログラマが手動でコンポーネントを作成する必要はありません。
非組み込みデータ型コンポーネントを手動で作成しなければならない場合もあります。データ型が複雑すぎて、Ant タスクが正しくコンポーネントを生成できないことがあります。あるいは、データの XML 表現と Java 表現間の変換方法に対して、WebLogic Server が使用するデフォルトの変換プロシージャに依存せず、より強力なコントロールを実装したいという場合もあるでしょう。
サポートされている非組み込みデータ型の詳細なリストは、「servicegen および autotype Ant タスクでサポートされる非組み込みデータ型」を参照してください。
servicegen
および autotype
の使い方の手順については、「Ant タスクを使用した WebLogic Web サービスのアセンブル」を参照してください。リファレンス情報については、「Web サービス Ant タスクとコマンドライン ユーティリティ」を参照してください。
次の手順は、非組み込みデータ型の作成方法と、servicegen
Ant タスクを使用したデプロイ可能な Web サービスの作成方法を示しています。
servicegen
Ant タスクを使用して Web サービスをアセンブルします。servicegen
Ant タスクを呼び出す build.xml
ファイルを作成する場合は、必ず、servicegen
の typeMappingFile
属性を指定し、それを前の手順で作成したデータ型マッピング ファイルの名前に設定してください。EAR ファイルではなく、.ear
サフィックスを持たない値を servicegen
の destEar
属性に指定して展開ディレクトリを作成することをお勧めします。その展開ディレクトリは、後で、Web サービスがデプロイできる状態になったときに EAR ファイルにパッケージ化できます。
servicegen
Ant タスクで生成された) web-services.xml
ファイルを更新します。「XML スキーマ情報で web-services.xml ファイルを更新する」を参照してください。clientgen
Ant タスクを使用して Java クライアントを生成する必要がある場合は、「clientgen Ant タスクを実行する」の手順に従います。ただし、clientgen
を呼び出す build.xml
ファイルについては以下のことを行います。Web サービスは、サービスとそのサービスを呼び出すクライアント アプリケーション間のデータ送信のメッセージ フォーマットとして SOAP を使用します。SOAP は、XML ベースのプロトコルなので、Web サービスのオペレーションが使用する非組み込みデータ型の構造を記述するには、XML スキーマ表記法が必要です。
警告 :XML スキーマは、強力かつ複雑なデータ記述言語であり、気の弱い方にはお勧めできません。
次の例では、EmployBean
という非組み込みデータ型を記述する XML スキーマを示しています。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:stns="java:examples.newTypes"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="java:examples.newTypes">
<xsd:complexType name="EmployeeBean">
<xsd:sequence>
<xsd:element name="name"
type="xsd:string"
nillable="true"
minOccurs="1"
maxOccurs="1">
</xsd:element>
<xsd:element name="id"
type="xsd:int"
minOccurs="1"
maxOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
次の XML は、EmployeeBean
データ型のインスタンスを示しています。
<EmployeeBean>
<name>Beverley Talbott</name>
<id>1234</id>
</EmployeeBean>
XML スキーマ表記法で非組み込みデータ型を記述する方法の詳細については、「XML スキーマ仕様」を参照してください。
非組み込みデータ型の Java 表現は、Web サービスのオペレーションを実装する EJB または Java クラスで使用します。
以下は、前節でその XML 表現を説明した EmployeeBean
データ型の Java 表現の例です。
package examples.newTypes;
/**
* @author Copyright (c) 2002 by BEA Systems.All Rights Reserved.
*/
public final class EmployeeBean {
private String name = "John Doe";
private int id = -1;
public EmployeeBean() {
}
public EmployeeBean(String n, int i) {
name = n;
id = i;
}
public String getName() {
return name;
}
public void setName(String v) {
this.name = v;
}
public int getId() {
return id;
}
public void setId(int v) {
this.id = v;
}
public boolean equals(Object obj) {
if (obj instanceof EmployeeBean) {
EmployeeBean e = (EmployeeBean) obj;
return (e.name.equals(name) && (e.id == id));
}
return false;
}
}
シリアライゼーション クラスは、データを XML 表現と Java 表現間で実際に変換するクラスです。データをシリアライズまたはデシリアライズするメソッドの入ったクラスを 1 つのみ記述します。このクラスでは、WebLogic XML Streaming API を使用して XML データを処理します。
WebLogic XML Streaming API は、XML ドキュメントの消費および生成を行う簡単で直観的な手段となります。この API により、一定の手順に従ったストリームベースの XML ドキュメントの扱いが可能になります。
WebLogic XML Streaming API の使い方の詳細については、『WebLogic XML プログラマーズ ガイド』を参照してください。
この節で使用した WebLogic Web サービスと XML API の詳細については、「Javadoc」を参照してください。
次の例は、XML Streaming API を使用して、「XML スキーマ データ型表現を記述する」および「Java データ型表現を記述する」で説明したデータ型をシリアライズおよびデシリアライズするクラスを示しています。この例を記したリストの後に、このようなクラスを作成する主な手順を示します。
package examples.newTypes;
import weblogic.webservice.encoding.AbstractCodec;
import weblogic.xml.schema.binding.DeserializationContext;
import weblogic.xml.schema.binding.DeserializationException;
import weblogic.xml.schema.binding.Deserializer;
import weblogic.xml.schema.binding.SerializationContext;
import weblogic.xml.schema.binding.SerializationException;
import weblogic.xml.schema.binding.Serializer;
import weblogic.xml.stream.Attribute;
import weblogic.xml.stream.CharacterData;
import weblogic.xml.stream.ElementFactory;
import weblogic.xml.stream.EndElement;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLName;
import weblogic.xml.stream.XMLOutputStream;
import weblogic.xml.stream.XMLStreamException;
public final class EmployeeBeanCodec extends
weblogic.webservice.encoding.AbstractCodec
{
public void serialize(Object obj,
XMLName name,
XMLOutputStream writer,
SerializationContext context)
throws SerializationException
{
EmployeeBean emp = (EmployeeBean) obj;
try {
// 外部開始要素
writer.add(ElementFactory.createStartElement(name));
// 従業員名要素
writer.add(ElementFactory.createStartElement("name"));
writer.add(ElementFactory.createCharacterData(emp.getName()));
writer.add(ElementFactory.createEndElement("name"));
// 従業員 ID 要素
writer.add(ElementFactory.createStartElement("id"));
String id_string = Integer.toString(emp.getId());
writer.add(ElementFactory.createCharacterData(id_string));
writer.add(ElementFactory.createEndElement("id"));
// 外部終了要素
writer.add(ElementFactory.createEndElement(name));
} catch(XMLStreamException xse) {
throw new SerializationException("stream error", xse);
}
}
public Object deserialize(XMLName name,
XMLInputStream reader,
DeserializationContext context)
throws DeserializationException
{
// リーダーから必要な情報を抽出
// このデータ型を表現する要素全体を消費する
// オブジェクトを作成して返す
EmployeeBean employee = new EmployeeBean();
try {
if (reader.skip(name, XMLEvent.START_ELEMENT)) {
StartElement top = (StartElement)reader.next();
// 次の開始要素は従業員名
if (reader.skip(XMLEvent.START_ELEMENT)) {
StartElement emp_name = (StartElement)reader.next();
// 次の要素は名前の文字データとする
CharacterData cdata = (CharacterData) reader.next();
employee.setName(cdata.getContent());
} else {
throw new DeserializationException("employee name not found");
}
// 次の開始要素は従業員 ID
if (reader.skip(XMLEvent.START_ELEMENT)) {
StartElement emp_id = (StartElement)reader.next();
// 次の要素は ID の文字データとする
CharacterData cdata = (CharacterData) reader.next();
employee.setId(Integer.parseInt(cdata.getContent()));
} else {
throw new DeserializationException("employee id not found");
}
// 要素全体を消費しなければ
// このストリームを良好な状態で終了してその他のデシリアライザに移動できない
if (reader.skip(name, XMLEvent.END_ELEMENT)) {
XMLEvent end = reader.next();
} else {
throw new DeserializationException("expected end element not found");
}
} else {
throw new DeserializationException("expected start element not found");
}
} catch (XMLStreamException xse) {
throw new DeserializationException("stream error", xse);
}
return employee;
}
public Object deserialize(XMLName name,
Attribute att,
DeserializationContext context)
throws DeserializationException
{
// 注意 : この例では使用していない
// 属性から必要な情報を抽出
// このデータ型を表現する要素全体を消費する
// オブジェクトを作成して返す
return new EmployeeBean();
}
}
WebLogic XML Streaming API を使用してシリアライゼーション クラスを作成するには、次の手順に従います。
import weblogic.webservice.encoding.AbstractCodec;
import weblogic.xml.schema.binding.DeserializationContext;
import weblogic.xml.schema.binding.DeserializationException;
import weblogic.xml.schema.binding.Deserializer;
import weblogic.xml.schema.binding.SerializationContext;
import weblogic.xml.schema.binding.SerializationException;
import weblogic.xml.schema.binding.Serializer;
import weblogic.xml.stream.Attribute;
import weblogic.xml.stream.CharacterData;
import weblogic.xml.stream.ElementFactory;
import weblogic.xml.stream.EndElement;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLName;
import weblogic.xml.stream.XMLOutputStream;
import weblogic.xml.stream.XMLStreamException;
weblogic.webservice.encoding.AbstractCodec
JAX-RPC では、XML にアクセスするための標準メカニズムが定義されていないため、AbstractCodec
クラスでは、ユーザが記述したシリアライゼーション クラスを WebLogic Web サービスの実行時に使用できるように「接着剤」が提供されます。
void serialize(Object obj,
XMLName name,
XMLOutputStream writer,
SerializationContext context)
throws SerializationException;
作成した Java オブジェクトは、Object
パラメータに格納されます。XML Streaming API を使用して、Java オブジェクトを XMLOutputStream
パラメータに記述します。結果として作成された要素の名前として、XMLName
パラメータを使用します。
Object deserialize(XMLName name,
XMLInputStream reader,
DeserializationContext context)
throws DeserializationException;
デシリアライズする XML は、XMLInputStream
パラメータにあります。WebLogic XML Streaming API を使用してこの XML を解析し、返される Object
に変換します。XMLName
パラメータには、この XML 要素名として予想される名前が格納されています。
deserialize()
メソッドを再帰的に呼び出して、格納されている Object
を構築します。
XML Streaming API を使用して XML ドキュメントを構成するイベントのストリームを読み込む際は、必ず、1 つの要素をその EndElement
イベントまで完全に読み込んでください。実際のデータの終わりで読み込みを終了しないでください。EndElement
イベントの手前で読み込みを終了すると、以降の要素のデシリアライゼーションが失敗するおそれがあります。
Object deserialize(XMLName name,
Attribute att,
DeserializationContext context)
throws DeserializationException;
データ型マッピング ファイルは、web-services.xml
デプロイメント記述子ファイルの一要素です。このファイルによって、非組み込みデータ型に関する情報の一部が 1 つの場所にまとめられます。たとえば、データの Java 表現を記述する Java クラスの名前や、XML と Java の間でデータを変換するシリアライゼーション クラスの名前などです。servicegen
Ant タスクでは、非組み込みデータ型を使用する WebLogic Web サービスの web-services.xml
デプロイメント記述子を作成するときにこのデータ型マッピング ファイルが使用されます。
データ型マッピング ファイルを作成するときには、次の手順に従います。
<type-mapping>
...
</type-mapping>
xmlns:
name
- ネームスペースを宣言します。class-name
- Java クラスの完全修飾名を指定します。type
- このデータ型マッピング エントリが適用される XML スキーマ型を指定します。 serializer
- データを Java 表現から XML 表現へ変換するシリアライゼーション クラスの完全修飾名です。このクラスを作成する方法の詳細については、「シリアライゼーション クラスを記述する」を参照してください。deserializer
- データを XML 表現から Java 表現へ変換するシリアライゼーション クラスの完全修飾名です。このクラスを作成する方法の詳細については、「シリアライゼーション クラスを記述する」を参照してください。次の例は、「XML スキーマ情報で web-services.xml ファイルを更新する」に示す XML スキーマ データ型用に <type-mapping>
エントリが 1 つ追加されたデータ型マッピング ファイルを示しています。
<type-mapping>
<type-mapping-entry
xmlns:p2="java:examples.newTypes"
class-name="examples.newTypes.EmployeeBean"
type="p2:EmployeeBean"
serializer="examples.newTypes.EmployeeBeanCodec">
deserializer="examples.newTypes.EmployeeBeanCodec"
</type-mapping-entry>
</type-mapping>
servicegen
で生成された web-services.xml
ファイルには、独自にカスタム シリアライゼーション クラスを作成した非組み込みデータ型の XML スキーマ情報が格納されません。したがって、次の手順に従って、XML スキーマ情報を手動でデプロイメント記述子に追加する必要があります。
<types>
...
</types>
<types>
要素内の既存の情報にマージします。
<types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:stns="java:examples.newTypes"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="java:examples.newTypes">
<xsd:complexType name="EmployeeBean">
<xsd:sequence>
<xsd:element name="name"
type="xsd:string"
nillable="true"
minOccurs="1"
maxOccurs="1">
</xsd:element>
<xsd:element name="id"
type="xsd:int"
minOccurs="1"
maxOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</types>
![]() ![]() |
![]() |
![]() |