Java: webserviceクライアント別のWSDL complexTypeのany要素の使い方
SalesforceのPartner WSDLでSOAP APIを使う時、sObjectのフィールド値をセットする時の書き方が各ライブラリによって大分違っています。
書き方の違いは、WSDLでの、complexType で anyの要素が各ライブラリで使い方が違うところに起因します。
各ライブラリでの書き方は次の通りとなります。ライブラリは、axis1.4、axis2、 wsimport、apache cxf、wscを対象とします。
axis1.4
import org.apache.axis.message.MessageElement;
import com.sforce.soap.partner.sobject.SObject;
import javax.xml.namespace.QName;
-------------------------------------------------
SObject sobject = new SObject();
sobject.setType("Sample__c");
MessageElement f1 = new MessageElement();
f1.setQName(new QName("Field1__c"));
f1.setValue("SampleValue1");
MessageElement f2 = new MessageElement();
f2.setQName(new QName("Field2__c"));
f2.setValue("SampleValue2");
sobject.set_any(new MessageElement[]{f1, f2});
axis2 (xmlbeans)
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import com.sforce.soap.partner.sobject.SObject;
----------------------------------------------------
SObject sobject = SObject.Factory.newInstance();
sobject.setType("Sample__c");
Document sobjdoc = sobject.getDomNode().getOwnerDocument();
Element f1 = sobjdoc.createElement("Field1__c");
Node v1 = sobjdoc.createTextNode("SampleValue1");
f1.appendChild(v1);
Element f2 = sobjdoc.createElement("Field2__c");
Node v2 = sobjdoc.createTextNode("SampleValue2");
f2.appendChild(v2);
sobject.getDomNode().appendChild(f1);
sobject.getDomNode().appendChild(f2);
wsimport・apache cxf
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.sforce.soap.partner.sobject.SObject;
--------------------------------------------------------------
SObject sobject = new SObject();
sobject.setType("Sample__c");
Document doc = null;
try{
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
} catch(Exception ignored){}
Element f1 = doc.createElement("Field1__c");
f1.appendChild(doc.createTextNode("SampleValue1"));
Element f2 = doc.createElement("Field1__c");
f2.appendChild(doc.createTextNode("SampleValue1"));
sobject.getAny().add(f1);
sobject.getAny().add(f2);
wsc
import com.sforce.soap.partner.sobject.SObject;
------------------------------------------------------
SObject sobject = new SObject();
sobject.setType("Sample__c");
sobject.addField("Field1__c" , "SampleValue1");
sobject.addField("Field2__c" , "SampleValue2");
最後に
各ライブラリによってだいぶ書き方が違うなーと思います。
wscはSalesforceに最適化されているので、Salesforceの項目の型に合わせてセットするJavaの型が異なります。
Salesforce:date・datetime ⇔ Java:Calendar
Salesforce:int ⇔ Java:Integer
Salesforce:boolean ⇔ Java:Boolean
Salesforce:base64 ⇔ Java:byte[]
それ以外は文字列となります、文字列中にxmlで使用不可の文字(制御コードなど)はライブラリ側が自動で取り除いてくれます。
wsc以外は、全ての項目は文字列となりますが、Salesforceの型に合わない文字列を指定すると、apiコールそのものがエラーとなります。
Salesforceの各型へセットする文字は、次の通りとなります。
Salesforce : date ⇒ yyyy-MM-dd
Salesforce : datetime ⇒ yyyy-MM-dd'T'HH:mm:ss'.000'Z
Salesforce : 数値の項目 ⇒ 数値に変換可能な数字
Salesforce : booelan ⇒ true or false
Salesforce : base64 ⇒ base64変換後の文字列
それ以外は文字列となりますが、文字列中にxmlで使用不可の文字(制御コードなど)は自動で取り除いてくれないので、自身で取り除く必要があります。