1

我是 android 的初学者,在这里我有使用 Web 服务的活动:

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);        
    GetBoundData val = new GetBoundData() {
    };
    PropertyInfo pi = new PropertyInfo();
    pi.setName("GetBoundData");
    pi.setValue(val);
    pi.setType(GetBoundData.class);
    request.addProperty(pi);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.setOutputSoapObject(request);
    Marshal floatMarshal = new MarshalFloat();

    envelope.addMapping(NAMESPACE, GetBoundData.class.getSimpleName(), GetBoundData.class);
    floatMarshal.register(envelope);
    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
    androidHttpTransport.debug =true;
    TextView t = (TextView)this.findViewById(R.id.resultbox);

    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
    try {

        androidHttpTransport.call(SOAP_ACTION, envelope);
        System.out.println("aht requestDump is :"+androidHttpTransport.requestDump);
        System.out.println("aht responseDump is :"+androidHttpTransport.responseDump);
    } catch (Exception e) {
        e.printStackTrace(); 
    }
    try {

        Object result = (Object) envelope.bodyIn;
        String s = result.toString();
        t.setText(s);
    } catch (ClassCastException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        t.setText("1");
    }

在 GetBoundData 类中:

public abstract class GetBoundData implements KvmSerializable {

String Bound = "((-0.00021792948245596397, -0.0002648681402206421), (0.00021792948246868618, 0.0002648681402206421))";
String Zoom ="21";
public Object getProperty(int arg0) {
switch (arg0){
    case 0:
        return Bound;
    case 1:
        return Zoom;
    default:
        return null;
        }
}

public int getPropertyCount() {
    return 2;//because you have 2 parameters
}

public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
switch(arg0)
{

    case 0:
        arg2.type = PropertyInfo.STRING_CLASS;
        arg2.name = "Bound";
        break;
    case 1:
        arg2.type = PropertyInfo.STRING_CLASS;
        arg2.name = "Zoom";
        break;
    default:break;
}

}
public void setval(String bound, String zoom) {
            Bound =  bound;
            Zoom =  zoom;           

    }
public void setProperty(int arg0, Object arg1) {
switch(arg0)
{
    case 0:
        Bound =  (String)arg1;
        break;
    case 1:
        Zoom =  (String)arg1;           
        break;
    default:
        break;
}

} }

这是网络服务 xml

<wsdl:types>
 <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
  <s:element name="GetBoundData">
   <s:complexType>
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="Bound" type="s:string"/>
      <s:element minOccurs="0" maxOccurs="1" name="Zoom" type="s:string"/>
    </s:sequence>
   </s:complexType>
  </s:element>
  <s:element name="GetBoundDataResponse">
   <s:complexType>
     <s:sequence>
       <s:element minOccurs="0" maxOccurs="1" name="GetBoundDataResult"       type="tns:ArrayOfAnyType"/>
     </s:sequence>
   </s:complexType>
  </s:element>
  <s:complexType name="ArrayOfAnyType">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="unbounded" name="anyType" nillable="true"/>
    </s:sequence>
  </s:complexType>
 </s:schema>
</wsdl:types>

这里的网络服务示例:

要求:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:xsd="http://www.w3.org/2001/XMLSchema"     xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
 <GetBoundData xmlns="http://tempuri.org/">
   <Bound>string</Bound>
   <Zoom>string</Zoom>
 </GetBoundData>
</soap:Body>
</soap:Envelope>

回复:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>
  <GetBoundDataResponse xmlns="http://tempuri.org/">
    <GetBoundDataResult>
      <anyType />
      <anyType />
    </GetBoundDataResult>
  </GetBoundDataResponse>
 </soap:Body>
</soap:Envelope>

但显示这个:

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@44efb360

我在 getresponse() 中使用了soapobject,但发生了错误

4

2 回答 2

2

那是因为您有复杂类型(即对象),而您只是添加“简单类型”属性。在这里
查看我的答案,我详细解释了需要做什么。 您还必须创建与复杂类型匹配的本地类,这些本地类应实现 kvmserializable,例如:

<s:element name="GetBoundData">
 <s:complexType>
  <s:sequence>
  <s:element minOccurs="0" maxOccurs="1" name="Bound" type="s:string"/>
  <s:element minOccurs="0" maxOccurs="1" name="Zoom" type="s:string"/>
 </s:sequence>
</s:complexType>

表示在网络服务上,存在一个名为“GetBoundData”的类。因此,由于使用 ksoap2 您正在手动构建肥皂信封,因此您必须在您的应用程序中创建这样一个类,实现 kvmserializable(这是一个 ksoap2 序列化接口):

public class GetBoundData implements KvmSerializable {

    String Bound; 
    String Zoom;

    @Override
    public Object getProperty(int arg0) {
    switch (arg0){
        case 0:
            return Bound;
        case 1:
            return Zoom;
        default:
            return null;
            }
    }

    @Override
    public int getPropertyCount() {
        return 2;//because you have 2 parameters
    }

    @Override
    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
    switch(arg0)
    {

        case 0:
            arg2.type = PropertyInfo.STRING_CLASS;
            arg2.name = "Bound";
            break;
        case 1:
            arg2.type = PropertyInfo.STRING_CLASS;
            arg2.name = "Zoom";
            break;
        default:break;
    }

    }

    @Override
    public void setProperty(int arg0, Object arg1) {
    switch(arg0)
    {
        case 0:
            Bound =  (String)arg1;
            break;
        case 1:
            Zoom =  (String)arg1;           
            break;
        default:
            break;
    }
}

这就是您如何在本地为服务器上的类(对象,即复杂类型)构建匹配项)。然后您必须添加必要的属性、构建信封、添加映射和编组并发送请求。这些步骤都在我上面提到的链接中进行了解释。

更新 我会向你解释这些是什么:

<wsdl:message name="GetBoundDataSoapIn"> 
<wsdl:part name="parameters" element="tns:GetBoundData"/> 
</wsdl:message> 

什么时候是 wsdl: message这意味着它是 Web 服务所需的功能。它有 ,这意味着它需要一个 GetBoundData 类型的参数,它不是原始类型,实际上它是一个复杂类型(对象)。
所以这里是步骤:
1-您必须编写复杂类型 GetBoundData 的本地表示,即类(我已经在上面写过)
2-在您的应用程序中,您必须创建(取决于您在哪里)一个函数将在 Web 服务上调用与“GetBoundDataSoapIn”相关的函数。因此,创建一个名称显着的函数是一个好主意,例如:

 public GetBoundData getBoundData()
 {
  try
    {
        SoapObject sobj = new SoapObject(YOUR_NAMESPACE,THE_METHOD_NAME);


        //------------------------------------------------------------------------------
        //  GetBoundData :adding property
        //          <wsdl:message name="GetBoundDataSoapIn"> 
        //          <wsdl:part name="parameters" element="tns:GetBoundData"/> 
        //          </wsdl:message> 
        //  GetBoundData has two params:
        //      <s:element minOccurs="0" maxOccurs="1" name="Bound" type="s:string"/>
        //      <s:element minOccurs="0" maxOccurs="1" name="Zoom" type="s:string"/>
        //
        //--------------------------------------------------------------------------

        //--------------
        //  GetBoundData
        //--------------
        PropertyInfo pi = new PropertyInfo();
        pi.setName("GetBoundData");
        pi.setValue(Whatever_value_your_supposed_to_put);// these values are "Bound" And "Zoom" , they're supposed to be gotten in your app somewhere
        pi.setType(GetBoundData.class);
        sobj.addProperty(pi);

        //------------------------------
        //  START BUILDING SOAP ENVELOPE
        //------------------------------
        SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        soapEnvelope.setOutputSoapObject(sobj);


        //---------------------------------------------------------------------------------------
        //      MAPPINGS:   
        //---------------------------------------------------------------------------------------

        soapEnvelope.addMapping(YOUR_NAMESPACE, GetBoundData.class.getSimpleName(), GetBoundData.class);

        //---------------------------------------------------------------------------------------
        //      MARSHALLING: 
        //---------------------------------------------------------------------------------------

        Marshal floatMarshal = new MarshalFloat();
        floatMarshal.register(soapEnvelope);


        AndroidHttpTransport aht = new AndroidHttpTransport(YOUR_URL); 


        aht.debug = true;

        try 
        {

            aht.call(YOUR_ACTION, soapEnvelope);

            //Importat Outputs to check how the request/Response looks like.. Check Logcat to find these outputs
            System.out.println("aht requestDump is :"+aht.requestDump);
            System.out.println("aht responseDump is :"+aht.responseDump);


            return soapEnvelope.getResponse();

        } 
        catch (Exception e) 
        {

            e.printStackTrace();
            return "Exception: " + e.getMessage()+"  message IS :" +e.getMessage()+"  localizedmessage is :"+e.getLocalizedMessage();
        }
    }
    catch(Exception ex)
    {
        ex.printStackTrace();
        return "Exception: " + ex.getMessage();
    }
    }
}

所以检查 logCat 以查看请求和响应的形状,你会看到是否必须获取响应并解析它才能使用它,我不确定你的响应是什么,但在我的情况下它是一个多维数组,所以我不得不使用java功能解析它。
至于:

<wsdl:message name="GetBoundDataSoapOut"> 
<wsdl:part name="parameters" element="tns:GetBoundDataResponse"/> 
</wsdl:message> 

这只是告诉您 Web 服务发回响应。

于 2012-01-28T02:43:21.220 回答
0


检查你的 NameSpace ,Method Name 。根据我的经验,当未与 web 服务建立正确连接时,我们会收到此错误

于 2012-01-23T08:18:16.823 回答