Dynamic Invocation Interface (DII)のサンプルソース

tutorialのサンプルを引用して、中身を見ます。

package dii;

import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.ParameterMode;

public class HelloClient {

    private static String qnameService = "MyHelloService";
    private static String qnamePort = "HelloIF";

    private static String BODY_NAMESPACE_VALUE = 
        "urn:Foo";
    private static String ENCODING_STYLE_PROPERTY =
         "javax.xml.rpc.encodingstyle.namespace.uri"; 
    private static String NS_XSD = 
        "http://www.w3.org/2001/XMLSchema";
    private static String URI_ENCODING =
         "http://schemas.xmlsoap.org/soap/encoding/";

    public static void main(String args) {

        System.out.println("Endpoint address = " + args[0]);

        try {
            ServiceFactory factory = 
                ServiceFactory.newInstance();
            Service service = 
                factory.createService(
                new QName(qnameService));
    
            QName port = new QName(qnamePort);
    
            Call call = service.createCall(port);
            call.setTargetEndpointAddress(args[0]);
    
            call.setProperty(Call.SOAPACTION_USE_PROPERTY, 
                new Boolean(true));
            call.setProperty(Call.SOAPACTION_URI_PROPERTY
                 "");
            call.setProperty(ENCODING_STYLE_PROPERTY,
                URI_ENCODING);
            QName QNAME_TYPE_STRING = 
                        new QName(NS_XSD, "string");
            call.setReturnType(QNAME_TYPE_STRING);

            call.setOperationName(
                new QName(BODY_NAMESPACE_VALUE,"sayHello"));
            call.addParameter("String_1", QNAME_TYPE_STRING, 
                ParameterMode.IN);
            String params = { "Murph!" };

            String result = (String)call.invoke(params);
            System.out.println(result);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
} 

サービスオブジェクトを作成する
Service service = factory.createService(new QName(qnameService));
でDynamic Proxyと同様にサービスオブジェクトを作成します。ただし、ここではWDSLのファイルを指定せず、サービス名である"MyHelloService"のQName表現だけを渡します。

Callオブジェクトを作成する
QName port = new QName(qnamePort);

Call call = service.createCall(port);

Dynamic Proxyでは、メソッド呼び出しの対象としてHelloIFを実装したクラスのインスタンスを取得しましたが、DIIでは汎用的なCallクラスのインスタンスを取得します。
このときServiceオブジェクトに渡すのは、ポートをあらわすQNameです。ただ、Dynamic Proxyのときは"HelloIFPort"を使用していましたが、DIIでは"HelloIF"を使用しています。なぜでしょう? わかりません。

エンドポイントのアドレスを設定する
call.setTargetEndpointAddress(args[0]);
でエンドポイントのURL(今回は"http://localhost:8080/jaxrpc-hello/")を設定します。

Callオブジェクトのプロパティを設定する
SOAPACTION_USE_PROPERTYにTrueを、
SOAPACTION_URI_PROPERTYに""を設定します。
の3つのプロパティを設定します。これらは、WSDL4/21の日記に掲載)の
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" ...
という個所に相当しているのでしょう。
また、プロパティ"javax.xml.rpc.encodingstyle.namespace.uri"に"http://schemas.xmlsoap.org/soap/encoding/"を設定しています。

戻り値の型(string)を識別します。
QName QNAME_TYPE_STRING = new QName(NS_XSD, "string");
call.setReturnType(QNAME_TYPE_STRING);

呼び出すメソッドの名前(sayHello)と引数の型(string)を指定します。
call.setOperationName(new QName(BODY_NAMESPACE_VALUE, "sayHello"));
call.addParameter("String_1", QNAME_TYPE_STRING, ParameterMode.IN);

Callオブジェクトを通じてリモートメソッドを呼び出します。
String[] params = { "Murphy" };
String result = (String)call.invoke(params);