10.5 インタフェースの透過性

WebサービスとWebサービスクライアントは,疎な関係にあり,相互のインタフェースはWSDLの定義内容だけです。Webサービス側は,WSDLを通じてWebサービスのインタフェース情報(メタデータ)を公開し,Webサービスクライアント側はそのメタデータを使用してSOAPメッセージを生成し,送受信します。

WebサービスおよびWebサービスクライアントの両方がApplication ServerのJAX-WSエンジンで動作する場合も,WSDL以外のインタフェース情報は交換されません。

Javaインタフェースの透過性はないため,SEIを起点としてWebサービスを開発した場合,Webサービス側とWebサービスクライアント側でメソッドシグネチャが異なることがあります。

ここでは,生成前のJavaメソッドと生成後のJavaメソッドの例を基に,メソッドシグネチャの違いについて説明します。

<この節の構成>
(1) 配列のパラメタを持つ場合
(2) OUTパラメタを一つだけ持つ場合
(3) non-wrapperスタイルの配列

(1) 配列のパラメタを持つ場合

次に示すJavaメソッドを持つSEIを起点に,Webサービスを開発することを想定します。このJavaメソッドは,配列(int型)のパラメタを持ちます。

@WebMethod
public void test1( int[] param1 );

この場合にマッピングされるWSDLの一部を次に示します。

...
<types>
 <xsd:schema targetNamespace="http://cosminexus.com/jaxws">

   <xs:element name="test1" type="tns:test1"/>

   <xs:element name="test1Response" type="tns:test1Response"/>

   <xs:complexType name="test1">
     <xs:element name="arg0" type="xs:int" nillable="true"
       minOccurs="0" maxOccurs="unbounded" />
   </xs:complexType>

   <xs:complexType name="test1Response">
     <xs:sequence/>
   </xs:complexType>
 </xs:element>
</types>
<message name="test1">
 <part name="parameters" element="tns:test1"/>
</message>

<message name="test1Response">
 <part name="parameters" element="tns:test1Response"/>
</message>

<portType ...>
 <operation name="test1">
   <input message="tns:test1"/>
   <output message="tns:test1Response"/>
 </operation>
 ...
</portType>
...

パラメタは,maxOccurs="unbounded"のwrapper子要素にマッピングされます。

このWSDLを指定してcjwsimportコマンドを実行すると,生成されるサービスクラスのJavaメソッドは次のようになります。

@WebMethod
public String test1( java.util.List<Integer> arg0 );

maxOccurs="unbounded"のwrapper子要素は,java.util.Listクラスにマッピングされます。また,この場合,xsd:int型は,java.lang.Integerクラスにマッピングされます。

(2) OUTパラメタを一つだけ持つ場合

次に示すJavaメソッドを持つSEIを起点に,Webサービスを開発することを想定します。このJavaメソッドは,OUTパラメタを一つだけ持ち,戻り値は持ちません。

@WebMethod
public void test1( @WebParam(mode=WebParam.Mode.OUT) Holder<String> param1 );

この場合にマッピングされるWSDLの一部を次に示します。

...
<types>
 <xsd:schema targetNamespace="http://cosminexus.com/jaxws">

   <xs:element name="test1" type="tns:test1"/>

   <xs:element name="test1Response" type="tns:test1Response"/>

   <xs:complexType name="test1">
     <xs:sequence/>
   </xs:complexType>

   <xs:complexType name="test1Response">
     <xs:sequence>
       <xs:element name="arg0" type="xs:string" minOccurs="0"/>
     </xs:sequence>
   </xs:complexType>
 </xs:element>
</types>
<message name="test1">
 <part name="parameters" element="tns:test1"/>
</message>

<message name="test1Response">
 <part name="parameters" element="tns:test1Response"/>
</message>

<portType ...>
 <operation name="test1">
   <input message="tns:test1"/>
   <output message="tns:test1Response"/>
 </operation>
 ...
</portType>
...

OUTパラメタは,wsdl:output要素から参照されるwrapper子要素にマッピングされます。

このWSDLを指定してcjwsimportコマンドを実行すると,生成されるサービスクラスのJavaメソッドは次のようになります。

@WebMethod
public String test1();

wsdl:output要素から参照されるwrapper子要素が1個だけなので,そのwrapper子要素は戻り値にマッピングされます。

(3) non-wrapperスタイルの配列

次に示すJavaメソッドを持つSEIを起点に,Webサービスを開発することを想定します。このJavaメソッドは,non-wrapperスタイルで,java.lang.Stringクラスの配列のパラメタを持ちます。

@WebMethod
@javax.jws.soap.SOAPBinding(
 parameterStyle=javax.jws.soap.SOAPBinding.ParameterStyle.BARE)
public String test1( String[] param1 );

この場合にマッピングされるWSDLの一部を次に示します。

...
<types>
 <xsd:schema targetNamespace="http://jaxb.dev.java.net/array">
   <xsd:complexType name="stringArray" final="#all">
     <xsd:sequence>
       <xsd:element name="item" type="xsd:string" minOccurs="0"
         maxOccurs="unbounded" nillable="true" />
     </xsd:sequence>
   </xsd:complexType>
 </xsd:schema>

 <xsd:schema targetNamespace="http://cosminexus.com/jaxws"
   xmlns:ns1="http://jaxb.dev.java.net/array">
   <xsd:element name="test1" nillable="true" type="ns1:stringArray"/>
   <xsd:element name="test1Response" nillable="true" type="xsd:string"/>
 </xsd:schema>
</types>

<message name="test1">
 <part name="test1" element="tns:test1" />
</message>

<message name="test1Response">
 <part name="test1Response" element="tns:test1Response" />
</message>

<portType ...>
 <operation name="test1">
   <input message="tns:test1" />
   <output message="tns:test1Response" />
 </operation>
 ...
</portType>
...

パラメタは,{http://jaxb.dev.java.net/array}stringArray型のwrapper子要素にマッピングされます。

このWSDLを指定してcjwsimportコマンドを実行すると,生成されるサービスクラスのJavaメソッドは次のようになります。

@WebMethod
@javax.jws.soap.SOAPBinding(
 parameterStyle=javax.jws.soap.SOAPBinding.ParameterStyle.BARE)
public String test1(net.java.dev.jaxb.array.StringArray test1);

{http://jaxb.dev.java.net/array}stringArray型のwrapper子要素は,net.java.dev.jaxb.array.StringArrayクラスにマッピングされます。