プログラマ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がお勧めです。