プログラマ38の日記

主にプログラムメモです。

【Java】apache cxfでSalesforce APIを使用する

まずはサンプルコード

    URL wsdlurl = Soap.class.getClassLoader().getResource("/partner.wsdl");
    Soap soapBinding = new SforceService(wsdlurl).getSoap();
    
    BindingProvider bp = (BindingProvider)soapBinding;
    bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,"https://login.salesforce.com/services/Soap/u/38.0");

    Client client = ClientProxy.getClient(bp);

    client.getInInterceptors().add(new GZIPInInterceptor());
    client.getOutInterceptors().add(new GZIPOutInterceptor());
    
    HTTPConduit conduit = (HTTPConduit)client.getConduit();
    HTTPClientPolicy policy = new HTTPClientPolicy();
    policy.setAllowChunking(true);
    policy.setConnectionTimeout(120000);
    policy.setProxyServer("sampleproxyhost");
    policy.setProxyServerType(ProxyServerType.HTTP);
    policy.setProxyServerPort(9999);
    
    ProxyAuthorizationPolicy authpolicy = new ProxyAuthorizationPolicy();
    authpolicy.setUserName("sampleproxyuser");
    authpolicy.setPassword("samplepassword");
    conduit.setProxyAuthorization(authpolicy);
    
    conduit.setClient(policy);
    

        LoginResult loginResult = soapBinding.login("sampleuser@sample.username", "samplepassword", null, null);
        
        
        bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,loginResult.getServerUrl());
        
        SessionHeader sh = new SessionHeader();
        String sessionId = loginResult.getSessionId();
        sh.setSessionId(sessionId);
        
        System.out.println(soapBinding.getServerTimestamp(sh, null, null).getTimestamp());

コードの生成とライブラリの作成

ライブラリ付属のwsdl2javaコマンドを使います。jarまで自動で作成してくれます。

set JAVA_HOME=javahomeのパス

wsdl2java.bat -d partner  -b jaxb.xml -exsh true -autoNameResolution -clientjar partner.jar partner.wsdl
wsdl2java.bat -d metadata -b jaxb.xml -exsh true -autoNameResolution -clientjar metadata.jar metadata.wsdl

_jaxb.xmlというのを上記コマンドで指定していますが、_jaxb.xmlの中身は次のテキストです。 typesafeEnumMaxMembersの上限エラーになったのでサイズを増やしています。(wsimportの時と同様です)

<jaxb:bindings
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    jaxb:extensionBindingPrefixes="xjc"
    jaxb:version="1.0">
    <jaxb:globalBindings typesafeEnumMaxMembers="2000">
  <xjc:serializable/>
    </jaxb:globalBindings>
</jaxb:bindings>

httpproxyの設定

コード内で指定となっています。

    Client client = ClientProxy.getClient(bp);
    
    HTTPConduit conduit = (HTTPConduit)client.getConduit();
    HTTPClientPolicy policy = new HTTPClientPolicy();
    policy.setProxyServer("sampleproxyhost");
    policy.setProxyServerType(ProxyServerType.HTTP);
    policy.setProxyServerPort(9999);
    
    ProxyAuthorizationPolicy authpolicy = new ProxyAuthorizationPolicy();
    authpolicy.setUserName("sampleproxyuser");
    authpolicy.setPassword("samplepassword");
    conduit.setProxyAuthorization(authpolicy);
    
    conduit.setClient(policy);

エンドポイントの設定

BindingProviderを使うことで指定します。

    URL wsdlurl = Soap.class.getClassLoader().getResource("/partner.wsdl");
    Soap soapBinding = new SforceService(wsdlurl).getSoap();
    
    BindingProvider bp = (BindingProvider)soapBinding;
    bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,"https://login.salesforce.com/services/Soap/u/38.0");

セッションIDと、インスタンスURLのセット

ここも、エンドポイントと同様に、BindingProviderを使います。

セッションIDは、SOAPHeaderにセットしておくのではなく、APIを呼び出す際に引数で指定します。

        bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,loginResult.getServerUrl());
        
        SessionHeader sh = new SessionHeader();
        String sessionId = loginResult.getSessionId();
        sh.setSessionId(sessionId);

これで上記コードのsoapBindingでSOAP APIを使用できます。

cxf3.Xを使うとデータバインディングがとても遅かったので、cxf2.7がお勧めです。