ここでは、Webサービスの通信での利用がサポートされているデータ型について説明します。Java EEのWebサービスアプリケーションではJavaとXMLの間のデータ変換には、JAXBが使用されます。ここでは、利用できるデータ型として以下を説明します。ここで説明していないデータ型や、変換の詳細についてはJAX-WSおよびJAXBのドキュメントを参照してください。
注意
受信したメッセージに含まれるデータの形式に異常がある場合、該当するJavaの値は言語仕様で定められた各データ型の初期値としてアプリケーションに渡される場合があります。
Javaの参照型(クラス型、インタフェース型、配列型。本項で説明している、Bean型、配列・コレクション型、添付ファイル型、およびプリミティブ型をラップするjava.langパッケージのクラスは該当します)では、初期値であるnullをアプリケーションで受け取った場合には、送信元がnullを意図して送信したのではなく、データ異常が発生している可能性もあります。そのため、アプリケーションおよびシステムの設計として、nullを正常値とせず異常値として扱うことをお勧めします。
また、下記の各節固有の注意事項も参照してください。
参考
本項で説明に使用しているXMLデータ型のprefixに対応するネームスペースは、以下のとおりです。アプリケーションやコマンドの実行時には、本項で説明するネームスペースに対して下記以外のprefixが使用されることがあります。
prefix | ネームスペース |
---|---|
xs | http://www.w3.org/2001/XMLSchema |
xsi | http://www.w3.org/2001/XMLSchema-instance |
wsi | http://ws-i.org/profiles/basic/1.1/xsd |
Javaの基本データ型とXMLデータ型
Webサービスアプリケーションのパラメタ(引数、返り値)で使用できる基本的なデータ型と、それに対応してXMLで使用される型を以下に示します。
Javaのデータ型 | XMLで使用されるデータ型 |
---|---|
int | xs:int |
short | xs:short |
long | xs:long |
byte | xs:byte |
float | xs:float |
double | xs:double |
boolean | xs:boolean |
java.lang.Integer | xs:int |
java.lang.Short | xs:short |
java.lang.Long | xs:long |
java.lang.Byte | xs:byte |
java.lang.Float | xs:float |
java.lang.Double | xs:double |
java.lang.Boolean | xs:boolean |
java.lang.String | xs:string |
java.math.BigDecimal | xs:decimal |
java.math.BigInteger | xs:integer |
java.util.Calendar | xs:dateTime |
javax.xml.namespace.QName | xs:QName |
java.net.URI | xs:string |
byte[] | xs:base64Binary |
注意
基本データ型の注意事項
byte[]型に対してJAXBの@javax.xml.bind.annotation.XmlSchemaTypeアノテーションを使用してxs:hexBinaryにマップするようにマッピングをカスタマイズする場合は、同時に@javax.xml.bind.annotation.XmlTypeAdapterアノテーションも使用してパラメタにjavax.xml.bind.annotation.adapters.HexBinaryAdapterのクラスオブジェクトを指定してください。
本項冒頭記載の仕様により、Javaのプリミティブ型(int、short、long、byte、float、double、boolean)では、0や0.0,falseなどの各データ型の初期値をアプリケーションで受け取った場合には、送信元がその値を意図して送信したのではなく、受信したメッセージに含まれるデータの形式に異常が発生している可能性があります。そのため、アプリケーションおよびシステムの設計として、Javaのプリミティブ型については元から設定されていた値や0や0.0,falseなどの各データ型の初期値を正常値として使用しない事をお勧めします。または、Javaのプリミティブ型は使用せず、代わりにプリミティブ型をラップするjava.langパッケージのクラス(Integer、Short、Long、Byte、Float、Double、Boolean)を使用してnullを異常値として扱う事をお勧めします。
java.lang.Stringでは、アプリケーションに渡される値として空文字列("")とnullは区別されません。そのため、アプリケーションおよびシステムの設計として、nullと共に空文字列を正常値として使用しない事をお勧めします。
Bean型
ユーザ定義のJavaクラス(Bean型)をWebサービスの通信で利用できます。Bean型のpublicフィールドやプロパティに、サポートされているデータ型を使用することで、より複雑な構造を持ったデータをWebサービスの通信で利用できます。
Bean型は、次の条件を満たすpublicクラスとして定義します。
publicデフォルトコンストラクタを持つ
以下のいずれかのデータ型として、サポートされているデータ型を使用している
publicフィールド
プロパティのsetter/getter
参照
プロパティの詳細については、JavaBeansのドキュメントを参照してください。
Bean型はWSDL定義ではxs:sequenceを内容とするxs:complexTypeとして表現されます。また、Bean型のpublicフィールドやプロパティは、いずれもxs:sequenceの子要素のxs:elementとして表現されます。
例
Bean型の定義例
package com.example; // パッケージ名 public class PersonBean { // public フィールド"age"の宣言 public int age; // プロパティ"name"の宣言 private String name; public void setName(String name) { this.name = name; } //プロパティのsetter public String getName() { return this.name; } //プロパティのgetter }
上記のJavaに対応する、XMLのデータ型のWSDL定義例を以下に示します。
<xs:complexType name="PersonBean"> <xs:sequence> <xs:element name="age" type="xs:int"/> <xs:element name="name" type="xs:string"/> </xs:sequence> </xs:complexType>
アノテーションを使用して定義をカスタマイズする場合には、次のように宣言します。プロパティに対しては、getterメソッドにアノテーションを宣言してください。
例
アノテーションを使用したBean型の定義例
package com.example; // パッケージ名 import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlElement; @XmlType(name="Person") //アノテーションによるXMLデータ型名の指定 public class PersonBean { // public フィールド"age"の宣言 @XmlElement(name="personAge") //アノテーションによるXML要素名の指定 public int age; // プロパティ"name"の宣言 private String name; public void setName(String name) { this.name = name; } //プロパティのsetter @XmlElement(name="personName") //アノテーションによるXML要素名の指定 public String getName() { return this.name; } //プロパティのgetter }
上記のJavaに対応する、XMLのデータ型のWSDL定義例を以下に示します。
<xs:complexType name="Person"> <xs:sequence> <xs:element name="personAge" type="xs:int"/> <xs:element name="personName" type="xs:string"/> </xs:sequence> </xs:complexType>
注意
Bean型の注意事項
Bean型を使用する場合は、クラス内でプロパティ名とpublicフィールド名が大小文字の区別にかかわりなく重複しないように定義してください。
Bean型のpublicフィールドまたはプロパティで @javax.xml.bind.annotation.XmlElementアノテーションのnillableパラメタにtrueを指定する場合は、同時にtargetNamespaceパラメタを指定しないでください。
Bean型のプロパティにアノテーションを付与する場合は、getterだけに付与し、setterやプロパティによってカプセル化されたprivateフィールドなどには付与しないでください。
配列・コレクション型
値を複数個持つパラメタを表現するために、配列やjava.util.Collectionインタフェースを実装したコレクションクラスを使用して、サポートされているデータ型をWebサービスの送受信に利用できます。コレクションクラスを利用する場合は、java.util.List<String>などのように、型パラメタを宣言することでコレクションの内容となるデータ型を明示できます。
例
String[]、およびjava.util.List<String>に対応するXMLデータ型のWSDL定義例
<xs:element name="array" type="xs:string" nillable="true" minOccurs="0" maxOccurs="unbounded" />
注意
配列・コレクション型の注意事項
nullでの送信について
アプリケーション上で配列やListのパラメタをnullで送信した場合、受信側で要素数0の配列やListとして取得される場合があります。
要素数0の配列やListでの送信について
アプリケーション上で配列やListのパラメタを要素数0で送信した場合、受信側でnullとして取得される場合があります。
コレクションクラスの型パラメタを指定しない場合、対応するXMLデータ型はxs:anyTypeとなり、通信に使用されるデータ型は実行時のオブジェクトによって決まります。実行時にサポートされていないJavaデータ型を使用した場合は正常に通信が行えない場合があります。
Bean型のpublicフィールドまたはプロパティで配列型を使用する場合、@javax.xml.bind.annotation.XmlElement (nillable=true)を必ず指定してください。
Webサービスエンドポイントの引数または返り値で配列型を使用する場合、@javax.jws.WebParamアノテーションのtargetNamespaceパラメタは指定しないでください。
java.lang.Integerなどの数値を表す型で配列型を定義する場合、要素にはnullを使用できません。
コレクション型の型パラメタには配列またはコレクション型を指定しないでください。
Javaの配列では、受信したメッセージに含まれるデータの形式に異常がある場合、該当する要素を除外して短縮された配列としてアプリケーションに渡される場合があります。通常は、配列ではなくコレクション型を使用することをお勧めします。
rpc/literal形式またはdocument/literal形式でparameterStyle属性にBAREを指定したWebサービスでは、コレクション型(java.util.Collectionまたはそのサブクラス)をWebサービスの通信に使用することはできません。使用している場合は、コレクション型以外のデータ型に変更するか、または、Webサービスをdocument/literal形式(デフォルト)かつparameterStyle属性WRAPPED(デフォルト)に変更してください。
添付ファイル型
primitive型やStringなどのような値を扱うデータ型の他に、ファイルなどのバイナリデータをWebサービスで利用できます。この場合、バイナリデータをXMLに変換してSOAPメッセージ本体に含めるのではなく、SOAPメッセージに付随した添付ファイルとして扱うことで、サイズの大きいバイナリデータでも効率よく処理できます。
Webサービスアプリケーションで添付ファイルを使用するには、javax.activation.DataHandlerクラスを使用します。通常のデータ型と同様に、Webサービスアプリケーションのパラメタ(引数、返り値)、Bean型のフィールド、プロパティなどに宣言できます。
Webサービスアプリケーションで添付ファイルを利用する場合、以下の2つの方式を利用できます。いずれもバイナリデータをSOAPメッセージの添付ファイルとするために、MIMEマルチパート構造を利用しますが、MIMEパートへのエンコード方法が異なります。
MTOM
WS-I Attachments Profile
MTOM方式の場合のアプリケーション作成方法
Webサービスアプリケーションでは、以下を行います。
Webサービスアプリケーションのクラスに@javax.xml.ws.soap.MTOMアノテーションを宣言して、MTOMを有効にします。
MTOMで送信するDataHandlerクラスのパラメタまたはプロパティの宣言に@ javax.xml.bind.annotation.XmlMimeTypeアノテーションを宣言し、アノテーションの引数にMIMEタイプを指定します。特定のMIMEタイプに限定させる必要がなければ「*/*」を指定します。
Webサービスクライアントでは、以下を行います。
サービスオブジェクトからスタブオブジェクトを取得する際に、javax.xml.ws.soap.MTOMFeatureオブジェクトを渡します。
例
MTOM方式で添付ファイルを利用するWebサービスアプリケーションの作成例
@MTOM @WebService public class Hello { @WebMethod public void upLoad(String saveFileName, @XmlMimeType("*/*") DataHandler data) { : } }
例
MTOM方式で添付ファイルを利用するWebサービスクライアントの作成例
DataHandler dataHandler = new DataHandler(new javax.activation.FileDataSource("./myFile.doc"); Hello port = new HelloService.getHelloPort(new MTOMFeature()); port.upLoad("myFile.doc", dataHandler);
WS-I Attachments Profile方式の場合のアプリケーション作成方法
Webサービスアプリケーションでは、以下を行います
DataHandlerクラスの宣言に@javax.xml.bind.annotation.XmlAttachmentRefアノテーションを宣言します。
Webサービスクライアントでは、特に必要な処理や宣言はありません。DataHandlerオブジェクトを通常のパラメタまたはプロパティと同様に利用してください。
例
WS-I Attachments方式で添付ファイルを利用するWebサービスアプリケーションの作成例
@WebService public class Hello { @WebMethod public void upLoad(String saveFileName, @XmlAttachmentRef DataHandler data) { : } }
例
WS-I Attachments方式で添付ファイルを利用するWebサービスクライアントの作成例
DataHandler dataHandler = new DataHandler(new javax.activation.FileDataSource("./myFile.doc"); Hello port = new HelloService.getHelloPort(); port.upLoad("myFile.doc", dataHandler);
Webサービスクライアントから大きいサイズの添付ファイルを送信する場合
Webサービスクライアントからの添付ファイルの送信では、デフォルトでは添付データに対して内部バッファ処理を行ってから送信処理を行う場合があります。この方法は、通信データが小さい場合に効率よく転送処理を行えますが、メモリ内に十分なサイズのバッファが必要となります。
数MByteを超える大きなサイズの添付ファイルをWebサービスクライアントから送信する場合は、クライアントアプリケーション内で以下のようにして添付ファイルをストリーミングモードで送信するように設定してください。
取得したスタブオブジェクトをjavax.xml.ws.BindingProviderクラスにキャストする。
キャストしたスタブオブジェクトのgetRequestContextメソッドを呼び、返却されたMapオブジェクトに対してputメソッドで以下の値をセットする。
キー | 値 |
---|---|
"com.sun.xml.ws.transport.http.client.streaming.chunk.size" | 値が0のjava.lang.Integerオブジェクト |
例
添付ファイルをストリーミングモードで送信するWebサービスクライアントの作成例(MTOM方式)
DataHandler dataHandler = new DataHandler(new javax.activation.FileDataSource("./myFile.doc"); Hello port = new HelloService.getHelloPort(new MTOMFeature()); BindingProvider provider = (BindingProvider) port; provider.getRequestContext().put( "com.sun.xml.ws.transport.http.client.streaming.chunk.size", new Integer(0)); port.upLoad("myFile.doc", dataHandler);
注意
添付ファイルの注意事項
MTOMとWS-I Attachments Profileは、互いに互換性のない方式です。1つのWebサービスアプリケーション内で2つの方式を混在させないでください。
Interstage Java EE 6 DASサービスでは、javax.activation.DataHandler以外のJAXB の添付ファイル型もサポートしていますが、クラスの仕様上、DataHandler以外のクラスではバイナリデータからJavaオブジェクトへの変換が行われるなど、オリジナルのバイナリデータが正確に保持されない場合があります。本製品では、これらのクラスの利用を推奨していません。
受信した添付ファイルのDataHandlerオブジェクトから取得できるInputStreamは、ブロックなしにデータを読み出せる場合もavailable()メソッドが0を返し続けることがあります。
@XmlMimeTypeや@XmlAttachmentRefアノテーションは、2次元以上の配列またはコレクションに直接付与しないでください。代わりに、上記アノテーションを付与したpublicフィールドまたはプロパティを持つBean型のクラスを作成し、作成したクラスを任意の次元数の配列やコレクションで送受信してください。
ストリーミングモードの設定時にMapオブジェクトに設定するInterger値には、0以外の値を指定しないでください。
Webサービスアプリケーションの例外オブジェクトの内容として、添付ファイルをMTOM/ WS-I Attachments Profile形式で送信することはできません。この場合、javax.activation.DataHandlerなどのオブジェクトに含まれるバイナリデータは、xs:base64Binary型のデータとしてSOAPエンベロープに含まれて送信されます。
rpc/literal形式の場合、またはdocument/literal形式でparameterStyle属性にBAREを指定した場合は、サービスエンドポイントのメソッド引数や返り値に直接DataHandlerなどのクラスを宣言せずに、Bean型のメンバとして添付ファイルを送受信してください。サービスエンドポイントのメソッド引数や返り値に直接宣言した場合は、オブジェクトに含まれるバイナリデータはxs:base64Binary型のデータとしてSOAPエンベロープに含まれて送信されます。
1Mバイト以上の添付ファイルを受信する場合、メモリ節約のため内部的に一時ファイルが作成されます。一時ファイルは、システムプロパティjava.io.tmpdirにセットされたディレクトリに次の命名規則で生成されます。
MIME*****.tmp
*****の部分は任意の数字です。
一時ファイルの作成場所には、呼量と添付ファイルの上限値に応じて十分なディスク容量を確保してください。
通常、一時ファイルは添付ファイルデータのオブジェクトがGCによって回収される際やJava VMの終了時に削除されますが、Javaプロセスが異常終了した場合、ファイルは削除されずに残ることがあります。その場合は、上記ファイルがどのプロセスからも使用されていないことを確認後、手動で削除してください。
また、java.io.tmpdirをデフォルトの値から変更してアプリケーションを実行する場合は、Webサービスを実行するInterstage Java EE 6 DASサービスやWebサービスクライアントの実行ユーザに書き込み権限があることを確認してください。
WebサービスアプリケーションがWS-I Attachments方式で添付ファイルを利用する場合、配備後に公開されるWSDLファイルはインターネット外部ページへの参照を含んでいる場合があります。
out/inoutパラメタとしての利用
サポートされているデータ型を、outパラメタまたはinoutパラメタとして利用する場合、Webサービスアプリケーションのメソッドでjavax.xml.ws.Holderクラスを使用して引数を宣言してください。
ポイント
out/inoutパラメタについて
outパラメタとは、クライアントからは値を送信せず、サーバから値が返信される引数です。
inoutパラメタとは、クライアントから値を送信するとともに、サーバからも値が返信される引数です。
Webサービスアプリケーション、Webサービスクライアントでは、out/inoutパラメタに対応するJava上の引数として、Holderクラスを使用します。
Holderクラスの変数の宣言方法
Holder<サポートされているデータ型のクラス名> 変数名 |
HolderクラスをWebサービスアプリケーションのメソッド引数に宣言する場合は、型パラメタとしてサポートされているデータ型のクラス名を指定してください。型パラメタに指定したクラスは、Holderオブジェクトのpublicフィールド「value」のフィールド型として使用されます。
Holderクラスの引数には、@javax.jws.WebParamアノテーションのmodeメンバを使用して、INOUTやOUTを指定できます。指定がない場合、Holderクラスで宣言した引数はINOUTのパラメタとして使用されます。
Webサービスクライアントアプリケーションにおいても、スタブオブジェクトのメソッドに引数として渡すHolderオブジェクトを宣言、生成する場合には、型パラメタを指定してください。
Holderクラスの変数の利用方法
Webサービスアプリケーションでは、引数で受け取ったHolderオブジェクトのvalueフィールドに値を設定することで、その値がoutパラメタとしてWebサービスクライアントへ返信されます。
Webサービスクライアントでは、Webサービス呼出しから復帰すると、引数に使用したHolderオブジェクトのvalueフィールドに、Webサービスアプリケーションがoutパラメタとして返信した値が設定されています。
例
Holderクラスの使用例(Webサービスアプリケーションのメソッド)
@WebMethod public int serverMethod(int inParam, @WebParam(mode=WebParam.Mode.INOUT) Holder<Integer> inoutParam, @WebParam(mode=WebParam.Mode.OUT) Holder<String> outParam) { //inoutパラメタは入力値を参照し必要な処理を行う int number = inoutParam.value.intValue(); : //out/inoutパラメタのvalueフィールドにクライアントに送信する値を代入 inoutParam.value = new Integer(10); outParam.value = "abc"; return 0; }
例
Holderクラスの使用例(Webサービスクライアント)
//パラメタの準備 int inParam = 123; Holder<Integer> inoutParam = new Holder<Integer>(); inoutParam.value = new Integer(987); Holder<String> outParam = new Holder<String>(); //Webサービスの呼出し(サーバが上記の例の場合、resultには0が入る) int result = portStub.serverMethod(inParam, inoutParam, outParam); //返信されたout/inoutパラメタ値の利用 int inoutResult = inoutParam.value.intValue(); //(サーバが上記の例の場合、10) String outResult = outParam.value; //(サーバが上記の例の場合、「abc」) :
注意
out/inoutパラメタ使用時の注意事項
Holderクラスのvalueフィールドのデータ型として、java.lang.Integerなどの数値をあらわすクラスを定義する場合、valueフィールドにはnullを使用できません。
その他
注意
その他の注意事項
目安として、通信データサイズが数100Kバイト(XMLでのタグなどを含む)を超える場合、性能およびメモリ消費量の観点から、「添付ファイル型」を使用することを検討してください。また、プロセス全体で同時に送信する添付ファイルの合計データ量が10Mバイトを超えるような場合はストリーミングモードに設定して送信を行ってください。
「添付ファイル型」を除いた分の通信データサイズが大きい場合、受信時に大量にメモリを消費し、メモリ不足や処理時間超過を招く恐れがあります。
ただし、通信データサイズが同じでもメモリ消費量は内容形式により大きく異なり、また、同時処理多重度や性能要件もシステムにより異なります。上記サイズを目安としつつ、条件に応じて、実際の業務用のデータ内容形式を使用して要件に対する事前検証を行うことをお勧めします。
XMLスキーマ上nillable="false"である要素に対してnullを設定して送信した場合は、受信側で初期値を持ったオブジェクトまたは値に復元されるなど、思わぬトラブルを招く場合があります。このような要素に対しては、nullを設定して送信しないでください。
派生によるXMLデータ型を使用する場合、xs:restrictionのbase属性にxs:anySimpleTypeは指定できません。
XMLデータ型がxs:anySimpleTypeの場合、WebサービスアプリケーションのパラメーターのJavaデータ型はjava.lang.Objectになります。送信側では、通信データのxsi:typeはjava.lang.Object型パラメーターに渡したオブジェクトから動的に決定します。受信側はjava.lang.Object型パラメーターのインスタンスのJavaデータ型を確認し、適切にキャストしてください。送信側で通信データにxsi:typeが設定されない場合、受信側のjava.lang.Object型パラメーターのJavaデータ型はorg.w3c.dom.Nodeの可能性があります。