android soapfault错误

时间:2012-01-23 08:03:05

标签: android ksoap2 soapfault

我是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;
}

} }

这是webservice 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>

这里是webservice示例:

请求:

<?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

我使用soapobject和getresponse()但发生了错误

2 个答案:

答案 0 :(得分:2)

多数民众赞成因为你有复杂的类型(即对象)而你只是添加&#34;简单类型&#34;属性。
检查我的回答here,我详细解释了需要做什么 您还必须创建与复杂类型匹配的本地类,这些本地类应实现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>

表示在Web服务上,存在一个名为&#34; GetBoundData&#34;的类。因此,自从使用kso​​ap2手动构建soap信封后,您必须在应用程序中创建这样的类,实现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:消息,这意味着它是Web服务所需的功能。 它有 ,这意味着它需要一个GetBoundData类型的参数,它不是一个原始类型,实际上它是一个复杂的类型(对象)。
以下是步骤:
1-你必须写一个复杂类型GetBoundData(我已在上面写过)的本地表示,即类 2-在你的应用程序中,你必须创建一个函数来调用与&#34; GetBoundDataSoapIn&#34;相关的函数。在网络服务上。因此,创建一个名称相当的函数是一个很好的理想,例如:

 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服务发回响应。

答案 1 :(得分:0)


检查NameSpace,方法名称。根据我的经验,当没有与webservice进行正确连接时,我们会收到此错误