読者です 読者をやめる 読者になる 読者になる

動的呼び出しクライアント その2

S2Axis

S2Axis2として、Axis2のEchoサンプルの処理を実現してみます(引数/戻り値にOMElementを使うことになるので、POJOではないのだけれど)。

AxisConnector

AxisConnectorは S2Axis1.x のものを修正。Axis2のサンプルを動かすために、今のところは、引数/戻り値が必ず OMElement となるものとしています。
このクラスが、リモートのサービスを呼び出します。サービスのメソッドの呼び出し、というかAXIOMオブジェクトの送受信?は ServiceClient を使って行います。

public class AxisConnector extends TargetSpecificURLBasedConnector {

    protected AxisService service;

    public void setService(AxisService service) {
        this.service = service;
    }

    protected Object invoke(URL url, Method method, Object[] args)
            throws Throwable {

        EndpointReference targetEPR = new EndpointReference(url.toString());

        Options options = new Options();
        options.setTo(targetEPR);

        ServiceClient client = new ServiceClient();
        client.setOptions(options);

        OMElement om = (OMElement)args[0];
        OMElement result = client.sendReceive(om);

        return result;
    }
}

サービス

サービスは、インタフェースと実装クラスに分けていますが、Axis2のサンプルそのままです。

  • Echo インタフェース
public interface Echo {
    OMElement echo(OMElement element) throws XMLStreamException;
}
  • Echo 実装クラス
public class EchoImpl implements Echo {    
    public OMElement echo(OMElement element) throws XMLStreamException {
        element.build();
        element.detach();
        return element;
    }
}
  • dicon

    
        <meta name="axis-service"/>
    

クライアント

いよいよクライアントの作成です。JUnitのテストクラスとして実装します。

  • EchoTest
    public void test() {
        Echo echo = (Echo) getComponent(Echo.class);
        try {
            OMElement expect = getEchoOMElement();
            OMElement result = echo.echo(expect);
            assertEquals(expect.toString(), result.toString());

            System.out.println(result);
        }
        catch (Exception ex) {
            ex.printStackTrace();
            assertFalse(true);
        }
    }
    
    public static OMElement getEchoOMElement() {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        OMNamespace omNs = fac.createOMNamespace(
                "http://example1.org/example1", "example1");
        OMElement method = fac.createOMElement("echo", omNs);
        method.declareNamespace("http://org.apache.axis2/", "tns");
        OMElement value = fac.createOMElement("Text", omNs);
        value.addChild(fac.createText(value, "Axis2 Echo String "));
        method.addChild(value);

        return method;
    }
  • dicon

    

    

    
        
            new java.net.URL("http://localhost:8080/s2axis2-examples/services/")
        
    

    
        remoting
    

実行

クライアントを実行すると、以下のようなデータ(適宜改行してます)を持つOMElementが返されました!


    Axis2 Echo String 

ただ、最初に実行したときは、引数にはない「xmlns:tns="http://org.apache.axis2/"」の部分が、戻り値では存在していたためにエラーとなってしまいました。サービスで処理した際に追加されるようですね!?
Axis2のサンプルには無かったのだけれど、「method.declareNamespace("http://org.apache.axis2/", "tns");」という処理をテストクラスに加えて処理させてます。

今後

引数/戻り値をPOJO化する必要があります。
メッセージを受け付ける org.apache.axis2.receivers.RawXMLINOutMessageReceiver を見てみたら、既に引数/戻り値が OMElement として処理されてますね。

    Class  parameters = method.getParameterTypes();
    Object args;

    if (parameters == null || parameters.length == 0) {
        args = new Object[0];
    } else if (parameters.length == 1) {
        OMElement omElement = msgContext.getEnvelope().getBody().getFirstElement();
        args = new Object[]{omElement};
    } else {
        throw new AxisFault(Messages.getMessage("rawXmlProivdeIsLimited"));
    }

    OMElement result = (OMElement) method.invoke(obj, args);

うーん、S2Axis2用に MessageReceiver を作成しないとダメかな。