无法使用kso​​ap在嵌套对象内发送数组

时间:2013-03-25 19:40:17

标签: android ksoap

我希望生成一个肥皂请求,例如:

<soapenv:Body>
    -
    <Perform xmlns="eras.in">
        -
        <request>
            <ActionName>Connect</ActionName>
            -
            <Input xmlns:ns1="eras.in" xsi:type="ns1:Record">
                <ns1:EntityName>Credential</ns1:EntityName>
                -
                <ns1:Fields>
                    -
                    <ns1:Field>
                        <ns1:Key>DomainName</ns1:Key>
                        <ns1:Value xsi:type="ns2:guid"
                            xmlns:ns2="http://schemas.microsoft.com/2003/10/Serialization/">Check2</ns1:Value>
                    </ns1:Field>
                    -
                    <ns1:Field>
                        <ns1:Key>UserName</ns1:Key>
                        <ns1:Value xsi:type="ns3:guid"
                            xmlns:ns3="http://schemas.microsoft.com/2003/10/Serialization/">utsav</ns1:Value>
                    </ns1:Field>
                    -
                    <ns1:Field>
                        <ns1:Key>Password</ns1:Key>
                        <ns1:Value xsi:type="ns4:guid"
                            xmlns:ns4="http://schemas.microsoft.com/2003/10/Serialization/">xxxxx</ns1:Value>
                    </ns1:Field>
                </ns1:Fields>
            </Input>
        </request>
    </Perform>
</soapenv:Body>

但我能够产生类似的东西:

<v:Body>
    <Perform xmlns="eras.in">
        <request i:type="n0:ActionRequest" xmlns:n0="eras.in">
            <ActionName i:type="d:string">Connect</ActionName>
            <sessionId i:null="true" />
            <Input i:type="n0:Record">
                <EntityName i:type="d:string">Credential</EntityName>
                <RecordId i:null="true" />
                <Fields i:type="n0:Fields">
                    <Field i:type="n0:Field">
                        <Key i:type="d:string">DomainName</Key>
                        <Value i:type="d:string">Check2</Value>
                    </Field>
                    <Field i:type="n0:Field">
                        <Key i:type="d:string">UserName</Key>
                        <Value i:type="d:string">utsav</Value>
                    </Field>
                    <Field i:type="n0:Field">
                        <Key i:type="d:string">Password</Key>
                        <Value i:type="d:string">xxx</Value>
                    </Field>
                </Fields>
            </Input>
        </request>
    </Perform>
</v:Body>

在检查服务器时,我看到Fields数组是一个空对象。

somepne可以帮忙吗?

我怀疑在服务器端对象中有一个名为Fields的字段数组。而我发送一个名为Fields的矢量对象。这会导致问题吗?

或者是因为字段标签缺少名称空间前缀?

谢谢和问候。

我的Java代码是:

       SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 
       SoapSerializationEnvelope envelope = new        SoapSerializationEnvelope(SoapEnvelope.VER11);
      ActionRequest ERequest = new ActionRequest();
      ERequest.setActionName("Connect");
      Record r = new Record();
      r.setEntityName("Credential");
      Fields fs = new Fields();
      fs.add(new Field("DomainName","Check2"));
      fs.add(new Field("UserName","utsav"));
      fs.add(new Field("Password","xxxx"));
      r.setFields(fs);
      ERequest.setInput(r);
      request.addProperty("request",ERequest);
      envelope.setOutputSoapObject(request);
  envelope.dotNet = true;
  envelope.setAddAdornments(false);
  envelope.implicitTypes = true;
  envelope.addMapping(NAMESPACE, "ActionRequest", new ActionRequest().getClass());
  envelope.addMapping(NAMESPACE, "Record", new Record().getClass());
  envelope.addMapping(NAMESPACE, "Field", new Field().getClass());

ActionRequest.java:

        package com.example.eat;

        import java.util.Hashtable;
        import org.ksoap2.serialization.KvmSerializable;
        import org.ksoap2.serialization.PropertyInfo;



     public class ActionRequest  implements KvmSerializable  {


private java.lang.String ActionName;

    private java.lang.Object input;

    private java.lang.String sessionId;

     public java.lang.String getActionName() {
    return ActionName;
}

public void setActionName(java.lang.String actionName) {
    this.ActionName = actionName;
}

public java.lang.Object getInput() {
    return input;
}

public void setInput(java.lang.Object input) {
    this.input = input;
}

public java.lang.String getSessionId() {
    return sessionId;
}

public void setSessionId(java.lang.String sessionId) {
    this.sessionId = sessionId;
}



public ActionRequest() {
}

@Override
public Object getProperty(int arg0) {
    // TODO Auto-generated method stub
    switch (arg0) {
    case 0:
        return ActionName;
    case 1:
         return sessionId;
    case 2: 
         return input;
    default:
        break;
    }
    return null;
}

@Override
public int getPropertyCount() {
    // TODO Auto-generated method stub
    return 3;
}

@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo info) {
    // TODO Auto-generated method stub
     switch (arg0) {
        case 0:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "ActionName";
            break;
        case 1:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "sessionId";
            break;
        case 2:
            info.type = Object.class;
            info.name = "Input";
            break;
        default:
            break;
        }

}

@Override
public void setProperty(int index, Object value) {
    // TODO Auto-generated method stub
    switch (index) {
    case 0:
        this.ActionName =value.toString();
        break;
    case 1:
        this.sessionId = value.toString();
        break;
    case 2:
        this.input =  value;
    default:
        break;
    }       
}

}

Record.Java:

package com.example.eat;

import java.util.Hashtable;

import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class Record  implements KvmSerializable {
    private java.lang.String EntityName;
    private java.lang.String RecordId;
    private Fields Fields1 = new Fields();
    //Field[] fs = new Field[0];

    public  com.example.eat.Fields getFields() {
        return Fields1;
    }

    public void setFields(Fields f) {
        this.Fields1 = f;
    }

    public java.lang.String getEntityName() {
        return EntityName;
    }

    public void setEntityName(java.lang.String entityName) {
        this.EntityName = entityName;
    }

    public java.lang.String getRecordId() {
        return RecordId;
    }

    public void setRecordId(java.lang.String recordId) {
        this.RecordId = recordId;
    }







    public Record() {
    }

    public Record(
           java.lang.String entityName,
           Fields fields,
           java.lang.String recordId) {
           this.EntityName = entityName;
           this.Fields1 = fields;
           this.RecordId = recordId;
    }

    @Override
    public Object getProperty(int arg0) {
        // TODO Auto-generated method stub
         switch (arg0) {
            case 0:
                return EntityName;
            case 1:
                return RecordId;
            case 2: 
                return Fields1;
            default:
                break;
            }
            return null;

    }

    @Override
    public int getPropertyCount() {
        // TODO Auto-generated method stub
        return 3;
    }

    @Override
    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
        // TODO Auto-generated method stub
        switch (index) {
        case 0:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "EntityName";
            break;
        case 1:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "RecordId";
            break;
        case 2:
            info.type = this.Fields1.getClass();
            info.name = "Fields";
            break;
        default:
            break;
        }
    }

    @Override
    public void setProperty(int index, Object value) {
        // TODO Auto-generated method stub

        if(null == value)
            value = "";
        switch (index) {
        case 0:
            EntityName = value.toString();
            break;
        case 1:
            RecordId= value.toString();
            break;
        case 2:
            Fields1= (Fields) value;
            break;


    }


    }

}

Fields.java

package com.example.eat;

import java.util.Hashtable;
import java.util.Vector;

import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class Fields extends Vector <Field> implements KvmSerializable{

    @Override
    public Object getProperty(int arg0) {
        // TODO Auto-generated method stub
         return this.get(arg0);
    }

    @Override
    public int getPropertyCount() {
        // TODO Auto-generated method stub
        return this.size();
    }

    @Override
    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
        // TODO Auto-generated method stub
        arg2.name = "Field";
       // arg2.type = PropertyInfo.STRING_CLASS;
         arg2.type = new Field().getClass();

    }

    @Override
    public void setProperty(int arg0, Object arg1) {
        // TODO Auto-generated method stub
         this.add((Field)arg1);
    }

}

Field.java:

package com.example.eat;

import java.util.Hashtable;
import java.util.Vector;

import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

/**
 * Field.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
 */

public class Field   implements KvmSerializable {
    private java.lang.String key;

    private java.lang.Object value;

    public Field(String key, String value) {
        // TODO Auto-generated constructor stub
        this.key=key;
        this.value=value;
    }

    public Field() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public Object getProperty(int arg0) {
        // TODO Auto-generated method stub
        switch (arg0){
        case 0:
            return key;
        case 1:
            return value;
        default:
            return null;
        }
    }

    @Override
    public int getPropertyCount() {
        // TODO Auto-generated method stub
        return 2;
    }

    @Override
    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
        // TODO Auto-generated method stub

        switch (index) {
        case 0:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "Key";
            break;
        case 1:
            info.type = Object.class;
            info.name = "Value";
            break;

        default:
            break;
        }

    }

    @Override
    public void setProperty(int index, Object value) {
        // TODO Auto-generated method stub
        if(null == value)
            value = "";
        switch (index) {
        case 0:
            key = value.toString();
            break;
        case 1:
            this.value = value;
            break;

        }
    }


}

1 个答案:

答案 0 :(得分:4)

在ksoap中使用SoapObject更容易,因为您可以更好地控制名称空间。 eras服务连接请求的示例如下所示......

private static final String NAMESPACE = "eras.in" ;
private static final String URL = "https://eras.in/Host/";
private static final String SOAP_ACTION = "eras.in/IActionService/Perform";
private static final String METHOD_NAME = "Perform";

public static void main(String[] args) {

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    SoapObject actionRequest = new SoapObject(NAMESPACE, "ActionRequest");

    request.addProperty("request", actionRequest);
    actionRequest.addProperty("ActionName", "Connect");

    SoapObject record = new SoapObject(NAMESPACE, "Record");
    actionRequest.addProperty("Input", record);

    record.addProperty("EntityName", "Credential");

    SoapObject fields = new SoapObject(NAMESPACE, "ArrayOfField");
    record.addProperty("Fields", fields);

    SoapObject domain = new SoapObject(NAMESPACE, "Field");
    domain.addProperty("Key", "DomainName");
    domain.addProperty("Value", "<your domain name>");
    fields.addSoapObject(domain);

    SoapObject user = new SoapObject(NAMESPACE, "Field");
    user.addProperty("Key", "UserName");
    user.addProperty("Value", "<your username>");
    fields.addSoapObject(user);

    SoapObject pwd = new SoapObject(NAMESPACE, "Field");
    pwd.addProperty("Key", "Password");
    pwd.addProperty("Value", "<your password>");
    fields.addSoapObject(pwd);

    envelope.setOutputSoapObject(request);
    envelope.dotNet = true;

    HttpTransportSE httpTransport = new HttpTransportSE(URL);
    try
    {
        httpTransport.call(SOAP_ACTION, envelope);
        SoapObject response = (SoapObject)envelope.getResponse();
        System.out.println(response.toString());
    }
    catch(Exception e)
    {   
        e.printStackTrace();
    }
}   

注意这一行

SoapObject fields = new SoapObject(NAMESPACE, "ArrayOfField");
record.addProperty("Fields", fields);

其中Fields是Record类的属性,此属性的类型是Field数组,即:

class Record
{
    Field[] Fields;
    ...
}