Salesforceのapexで自作のWeb Serviceを作成し、外部プログラムから呼び出すには?

以前、「Salesforceに接続して、オブジェクト加工等を行うEclipseプロジェクトのテンプレート」という記事で、Partner WSDLを利用してWebサービス経由でSFDCにログインし、様々な情報を取ってきたり、レコードを作成したりしました。

今回は、自分で、Apexコードで何かを行うクラスを作成し、それをWebサービスとして公開した後、それを外部のJavaプログラムから呼び出すことをやってみたいと思います。

複雑なSFDC内部での処理はApexコードに任せれば、外部プログラムはそれを呼び出すだけなので、呼び出し側の

ロジックが簡素化されるだけでなく、Batch Apexを使った大量一括処理を行うことも比較的楽になると思います。

また、JavaのAPサーバからSalesforce側にあるデータを取得したり、SFDC外部サイトのユーザアクションから、

Salesforceに一連のデータを登録・更新することも簡単になります。

SFDCにWebサービスを作成する

はじめに呼び出すWebサービスをSFDCに作成します。

今回は以下のような「MyWebServiceClass」を作成しました。

Webサービスで公開するメソッドは「myCalledMethod」とし、呼び出し側からは文字列型の変数を渡すことにします。

戻りの型は、サンプルとして作成した「MyInfo」というクラスにします。

自作のクラスでも呼び出しの引数、戻りとして使用できるという例のためですので、普通に文字列や数値型でもいいですよ。

global class MyWebServiceClass  
{  
    
    //Define an object in apex that is exposed in apex web service
    global class MyInfo{
        webservice String myName;
        webservice Integer MyNumber;
    }
     
    webService static MyInfo myCalledMethod(String strParam)  
    {
        // DoSomething
        MyInfo info = new MyInfo();
        info.myName = '111';
        info.MyNumber = 222;
        return info;  
    }  
}

クラスを作成したら、「WSDLの作成」ボタンを押して、wsdlファイルを作成、適当な名前でPCに保存します。

今回は「MyWebServiceClass.wsdl」としました。

WSDLファイルは公開するWebサービスの情報を定義したものです。

後ほど、このファイルを元に、JavaからWebサービスに接続するためのクラスを生成します。

呼び出し側のコード

それではJavaからの呼び出しを行ってみます。

Eclipseで前回の「Salesforceに接続して、オブジェクト加工等を行うEclipseプロジェクトのテンプレート」という記事を参考に、雛形のプロジェクトがあることを前提とします。

はじめに、スタブ・クラスの生成を行います。

java -classpath libwsc-23.jar com.sforce.ws.tools.wsdlc MyWebServiceClass.wsdl .libwebservice_stub.jar

というコマンドをコマンド・プロンプトから打ちます。

PCに保存した「MyWebServiceClass.wsdl」を元に、クラスを生成し、「webservice_stub.jar」としてまとめる

というコマンドです。

雛形で用意した、「partner.jar」と「webservice_stub.jar」がクラスパスに入っていることを確認しましょう。

「partner.jar」には、SFDCにログインして情報を取ってくる一般的な機能を提供するクラス群が、

「webservice_stub.jar」には今回作成したMyWebServiceClassのWebサービスを利用するために特化したクラス群が含まれています。

呼び出しのクラスはこのような感じになります。

public void execute( ) throws ApplicationException{
 
    PartnerConnection connection;
    SoapConnection sconnection;
 
 
    ConnectorConfig config = new ConnectorConfig();
    config.setUsername(USERNAME);
    config.setPassword(PASSWORD);
    config.setAuthEndpoint(AUTH_ENDPOINT);
    config.setTraceMessage(true);
    //config.setProxy(PROXY_SERVER, PROXY_PORT);
 
 
    try {
         
        connection = com.sforce.soap.partner.Connector.newConnection(config);
        System.out.println("Auth EndPoint: "+config.getAuthEndpoint());
            System.out.println("Service EndPoint: "+config.getServiceEndpoint());
            System.out.println("Username: "+config.getUsername());
            System.out.println("SessionId: "+config.getSessionId());
             
             
            config.setServiceEndpoint(Connector.END_POINT);
 
            sconnection = com.sforce.soap.MyWebServiceClass.Connector.newConnection(config);
 
             
        MyInfo info = sconnection.myCalledMethod("test");
         
        System.out.println("getMyName:"+info.getMyName());
         
         
    }catch (ConnectionException e1) {
        e1.printStackTrace();
    }  catch (Exception e) {
        e.printStackTrace();
    } 
 
 
}

はじめにPartnerConnectionを使ってログインを行い、その後、SoapConnectionで自作のWebサービスを呼ぶ流れになっています。

「config.setServiceEndpoint(Connector.END_POINT);」をきちんと指定しないと、

com.sforce.ws.SoapFaultException: No operation available for request {http://soap.sforce.com/schemas/class/MyWebServiceClass}myCalledMethod
    at com.sforce.ws.transport.SoapConnection.createException(SoapConnection.java:204)
    at com.sforce.ws.transport.SoapConnection.receive(SoapConnection.java:148)
    at com.sforce.ws.transport.SoapConnection.send(SoapConnection.java:110)
    at com.sforce.soap.MyWebServiceClass.SoapConnection.myCalledMethod(SoapConnection.java:178)

のようなエラーが表示されるかもしれませんので、気をつけてください。