I am using KSoap2 to try to build the XML file request below.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:_5="www.444.com">
<soapenv:Header/>
<soapenv:Body>
<_5:GetStaff>
<!--Optional:-->
<_5:Request>
<!--Optional:-->
<_5:SourceCredentials>
<!--Optional:-->
<_5:SourceName>sourcename</_5:SourceName>
<!--Optional:-->
<_5:Password>password=</_5:Password>
<!--Optional:-->
<_5:SiteIDs>
<!--Zero or more repetitions:-->
<_5:int>1111</_5:int>
</_5:SiteIDs>
</_5:SourceCredentials>
</_5:Request>
</_5:GetStaff>
</soapenv:Body>
</soapenv:Envelope>
I've attempted to take this and generate the following code but it seems the child elements are causing me problems. I'm new to Ksoap2 and can't find a clear solution to structuring.
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("SourceName", "sourcename");
request.addProperty("Password", "password=");
request.addProperty("int", "1111");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE htse = new HttpTransportSE(URL);
try{
htse.call(SOAP_ACTION, envelope);
SoapPrimitive resultString = (SoapPrimitive) envelope.getResponse();
ret = resultString.toString();
}
catch(Exception e){
e.printStackTrace();
}
How would i used KSoap2 to build the tree in order for the child elements to be accessed correctly. The api doesn't respond correctly without this structure.
Is there a way to send this xml file out of maybe an xml resource directly?
or is there another way?
UPDATE: tried to make classes for complex elements
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
import java.util.Hashtable;
/**
* Created by randypfohl on 7/15/15.
*/
public class SourceCredentials implements KvmSerializable {
//Xml variables
private String sourceName;
private String password;
private SiteIDs site;
public SourceCredentials() {
}
public void setSourceName(String sourceName) {
this.sourceName = sourceName;
}
public String getSourceName() {
return this.sourceName;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return this.password;
}
public void setSiteIDs(SiteIDs site) {
this.site = site;
}
@Override
public Object getProperty(int index) {
Object toreturn = null;
switch (index) {
case 0:
toreturn = this.sourceName;
case 1:
toreturn = this.password;
case 2:
toreturn = this.site;
default:
break;
}
return toreturn;
}
@Override
public int getPropertyCount () {
return 3;
}
@Override
public void setProperty ( int index, Object value){
switch (index) {
case 0:
this.sourceName = value.toString();
break;
case 1:
this.password = value.toString();
break;
case 2:
site.setProperty(0, value);
break;
}
}
@Override
public void getPropertyInfo ( int index, Hashtable hashtable, PropertyInfo propertyInfo){
switch (index) {
case 0:
propertyInfo.name = "SourceName";
propertyInfo.type = PropertyInfo.STRING_CLASS;
break;
case 1:
propertyInfo.name = "Password";
propertyInfo.type = PropertyInfo.STRING_CLASS;
break;
case 2:
propertyInfo.name = "SiteIDs";
propertyInfo.type = SiteIDs.class;
break;
default:
break;
}
}
@Override
public String getInnerText () {
return null;
}
@Override
public void setInnerText (String s){
}
}
and this is the siteids class.
import java.util.Hashtable;
import java.util.Vector;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
public class SiteIDs extends Vector<Integer> implements KvmSerializable {
@Override
public Object getProperty(int arg0) {
return this.get(arg0);
}
@Override
public String getInnerText () {
return null;
}
@Override
public void setInnerText (String s){
}
@Override
public int getPropertyCount() {
return 1;
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
arg2.name = "int";
arg2.type = PropertyInfo.INTEGER_CLASS;
}
@Override
public void setProperty(int arg0, Object arg1) {
this.add(Integer.valueOf(arg1.toString()));
}
}
this is the code that i created.
/* String ret ="fail";
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SourceCredentials sourceCredentials = new SourceCredentials();
sourceCredentials.setProperty(0, "name");
sourceCredentials.setProperty(1, "password");
SiteIDs siteIDS = new SiteIDs();
siteIDS.setProperty(0, "1100");
sourceCredentials.setSiteIDs(siteIDS);
request.addProperty("SourceCredentials", sourceCredentials);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
envelope.addMapping(NAMESPACE, SourceCredentials.class.getSimpleName(), SourceCredentials.class);
envelope.addMapping(NAMESPACE, SiteIDs.class.getSimpleName(), SiteIDs.class);
try{
HttpTransportSE htse = new HttpTransportSE(URL);
htse.debug = true;
htse.setXmlVersionTag("<!--?xml version=\"1.0\" encoding= \"UTF-8\" ?-->");
htse.call(SOAP_ACTION, envelope);
SoapPrimitive resultString = (SoapPrimitive) envelope.getResponse();
ret = resultString.toString();
System.out.println(ret);
}
catch(Exception e){
e.printStackTrace();
}
return ret;
I can't figure it out. i seem to always get a strange error.
SoapFault - faultcode: 'soap:Server' faultstring: 'Server was unable to process request. ---> Object reference not set to an instance of an object.' faultactor: 'null' detail: org.kxml2.kdom.Node@b1eb5d78
You have to create serializable objects and pass them to the SOAP object.
public class SourceCredentials implements KvmSerializable {
//Xml variables
private String sourceName;
private String password;
private SiteIDs siteIDs;
public SourceCredentials(){
}
public setSourceName(String sourceName){
this.sourceName = sourceName;
}
public String getSourceName(){
return this.sourceName;
}
public setPassword(String password){
this.password = password;
}
public String getPassword(){
return this.password;
}
public setSiteIDs(SiteIDs siteIDs){
this.siteIDs = siteIDs;
}
public getSiteIDs(){
return this.siteIDs;
}
@Override
public Object getProperty(int index) {
switch(index){
case 0:
return this.sourceName;
case 1:
return this.password;
case 2:
return this.siteIDs;
default:
break
}
@Override
public int getPropertyCount() {
return 3;
@Override
public void setProperty(int index, Object value) {
switch(index){
case 0:
this.sourceName = value.toString();
break;
case 1:
this.password = value.toString();
break;
case 2:
this.siteIDs = (SiteIDs) value;
break;
}
}
@Override
public void getPropertyInfo(int index, Hashtable hashtable, PropertyInfo propertyInfo) {
switch (index){
case 0:
propertyInfo.name = "SourceName";
propertyInfo.type = PropertyInfo.STRING_CLASS;
break;
case 1:
propertyInfo.name = "Password";
propertyInfo.type = PropertyInfo.STRING_CLASS;
break;
case 2:
propertyInfo.name = "SiteIDs";
propertyInfo.type = PropertyInfo.OBJECT_CLASS;
break;
default:
break;
}
}
@Override
public String getInnerText() {
return null;
}
@Override
public void setInnerText(String s) {
}
And you do the same with SiteIds
Then you pass the Soap object.
EDIT
You try this?
SourceCredentials sourceCredentials = new SourceCredentials();
//Create SiteIDs KvmSerializable object
SiteIDs siteIDS = new SiteIDS();
siteIDS.setInt(1111)
//Setters
sourceCredentials.setSourceName("sourcename");
sourceCredentials.setPassword("password=");
sourceCredentials.setSiteIDS(siteIDS);
request.addProperty("SourceCredentials", sourceCredentials);
EDIT 2
Try this
SiteIDS.java
public class SiteIDs implements KvmSerializable {
private List<Integer> Int; //change name of variable, int it's a reserved name
public SiteIDs() {
}
public List<Integer> getInt() {
return Int;
}
public void setInt(List<Integer> anInt) {
Int = anInt;
}
@Override
public Object getProperty(int i) {
switch (i){
case 0:
return Int;
default:
break;
}
return null;
}
@Override
public int getPropertyCount() {
return 1;
}
@Override
public void setProperty(int i, Object value) {
switch (i) {
case 0:
this.Int = (List<Integer>) value;
break;
default:
break;
}
}
@Override
public void getPropertyInfo(int i, Hashtable hashtable, PropertyInfo propertyInfo) {
switch (i) {
case 0:
propertyInfo.name = "int";
propertyInfo.type = List.class;
break;
default:
break;
}
}
@Override
public String getInnerText() {
return null;
}
@Override
public void setInnerText(String s) {
}
And this:
SourceCredentials sourceCredentials = new SourceCredentials();
//Create SiteIDs KvmSerializable object
SiteIDs siteIDS = new SiteIDS();
List<Integer> ints = new ArrayList<Integer>();
ints.add(1111); //add one o more ints
siteIDS.setInts(ints);
//Setters
sourceCredentials.setSourceName("sourcename");
sourceCredentials.setPassword("password=");
sourceCredentials.setSiteIDS(siteIDS);
request.addProperty("SourceCredentials", sourceCredentials);