【问题标题】:Ksoap2 Passing Complex Object as ParameterKsoap2 将复杂对象作为参数传递
【发布时间】:2012-07-01 15:46:15
【问题描述】:

我通过随请求一起发送一个对象来与网络服务通信。

这是网络服务的 WSDL 格式。

<?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>
<UpdateLocation xmlns="http://tempuri.org/">
  <location>
    <Id>int</Id>
    <TabletId>int</TabletId>
    <SpeedVisibility>boolean</SpeedVisibility>
    <BeltVisibility>boolean</BeltVisibility>
    <LightVisibility>boolean</LightVisibility>
    <ProjectorVisibility>boolean</ProjectorVisibility>
    <DefStart>int</DefStart>
    <DefEnd>int</DefEnd>
    <DefPickerCount>int</DefPickerCount>
    <DefSlotCount>int</DefSlotCount>
    <ServerIP>string</ServerIP>
    <WebURL>string</WebURL>
  </location>
</UpdateLocation>
</soap:Body>
</soap:Envelope>

这是我发出请求的 java 代码。

private void updateSettingsOnServer() {
    SoapObject request = new SoapObject(NAMESPACE, METHOD_UPDATE_SETTINGS);

    Location serverObject = new Location(currentLocation.databaseId, currentLocation.tabletId, currentLocation.isSpeedVisible, currentLocation.isBeltVisible, currentLocation.isLightVisible, currentLocation.isProjectorVisible, currentLocation.slotStarting, currentLocation.slotEnding, prefPickerCount, prefSlotCount, prefServerIPString, prefWebURL);


     PropertyInfo pi = new PropertyInfo();
        pi.setName("serverObject");
        pi.setValue(serverObject);
        pi.setType(serverObject.getClass());
        request.addProperty(pi);




    SoapSerializationEnvelope envelope = 
        new SoapSerializationEnvelope(SoapEnvelope.VER11); 
    envelope.dotNet = true;
    envelope.setOutputSoapObject(request);



    envelope.addMapping(NAMESPACE,"Location",new Location().getClass());


    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);




    try {
        androidHttpTransport.call(SOAP_ACTION_UPDATE_SETTINGS, envelope);




        SoapObject result=(SoapObject)envelope.getResponse(); //To get the data.
        tempText.setText("Received :" + result.toString());

    }
    catch(Exception e)
    {

        tempText.setText("Error");
        //Toast.makeText(context, "Error", Toast.LENGTH_LONG).show();
        e.printStackTrace();
    }

}

我通过以下方式创建了我的自定义类 KVMSerializable。

class Location implements KvmSerializable
{
    public Location(int id, int tabletid, boolean speed, boolean belt, boolean light, boolean projector, int start, int end, int picker, int slot, String server, String web)
    {
        databaseId =id;
        tabletId = tabletid;
        isSpeedVisible = speed;
        isBeltVisible = belt;
        isLightVisible = light;
        isProjectorVisible = projector;
        slotStarting = start;
        slotEnding = end;
        pickerCounting = picker;
        slotCounting = slot;
        serverUrlLink = server;
        webUrlLink = web;


    }

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

    boolean isSpeedVisible, isLightVisible, isBeltVisible, isProjectorVisible;
    int slotStarting, slotEnding , pickerCounting, slotCounting;
    int databaseId, tabletId;
    String serverUrlLink, webUrlLink;


    public Object getProperty(int arg0) {
        // TODO Auto-generated method stub

         switch(arg0)
            {
            case 0:
                return databaseId;
            case 1:
                return tabletId;
            case 2:
                return isSpeedVisible;
            case 3:
                return isBeltVisible;
            case 4:
                return isLightVisible;
            case 5:
                return isProjectorVisible;
            case 6:
                return slotStarting;
            case 7:
                return slotEnding;
            case 8:
                return pickerCounting;
            case 9:
                return slotCounting;
            case 11:
                return serverUrlLink;
            case 12:
                return webUrlLink;

            }

         return null;
    }


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



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

        switch(arg0)
        {
        case 0:
            info.type = PropertyInfo.INTEGER_CLASS;
            info.name = "databaseId";
            break;
        case 1:
            info.type = PropertyInfo.INTEGER_CLASS;
            info.name = "tabletId";
            break;
        case 2:
            info.type = PropertyInfo.BOOLEAN_CLASS;
            info.name = "isSpeedVisible";
            break;
        case 3:
            info.type = PropertyInfo.BOOLEAN_CLASS;
            info.name = "isBeltVisible";
            break;
        case 4:
            info.type = PropertyInfo.BOOLEAN_CLASS;
            info.name = "isLightVisible";
            break;
        case 5:
            info.type = PropertyInfo.BOOLEAN_CLASS;
            info.name = "isProjectorVisible";
            break;
        case 6:
            info.type = PropertyInfo.INTEGER_CLASS;
            info.name = "slotStarting";
            break;
        case 7:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "slotEnding";
            break;
        case 8:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "pickerCounting";
            break;
        case 9:
            info.type = PropertyInfo.INTEGER_CLASS;
            info.name = "slotCounting";
            break;
        case 11:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "serverUrlLink";
            break;
        case 12:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "webUrlLink";
            break;

        default:break;
        }



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

        switch(index)
        {
        case 0:
            databaseId = Integer.parseInt(value.toString());
            break;
        case 1:
            tabletId = Integer.parseInt(value.toString());
            break;
        case 2:
            isSpeedVisible = Boolean.parseBoolean(value.toString());
            break;
        case 3:
            isBeltVisible = Boolean.parseBoolean(value.toString());
            break;
        case 4:
            isLightVisible = Boolean.parseBoolean(value.toString());
            break;
        case 5:
            isProjectorVisible = Boolean.parseBoolean(value.toString());
            break;
        case 6:
            slotStarting = Integer.parseInt(value.toString());
            break;
        case 7:
            slotEnding = Integer.parseInt(value.toString());
            break;
        case 8:
            pickerCounting = Integer.parseInt(value.toString());
            break;
        case 9:
            slotCounting = Integer.parseInt(value.toString());
            break;
        case 10:
            serverUrlLink = (value.toString());
            break;
        case 11:
            webUrlLink = (value.toString());
            break;


        default:
            break;
        }

    }
}

但不幸的是,它不起作用。

我收到此错误。我环顾四周,但仍然无法找到解决此问题的方法。

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@410cdac8

请帮忙。我现在被这个问题困扰了超过 3 天!

【问题讨论】:

  • @user:1063062 : 你能帮我吗?

标签: android android-ksoap2 custom-object


【解决方案1】:

你为什么不使用简单的方法。

final SoapObject request = new SoapObject(AppConsts.NAMESPACE,
                usecaseString);
        request.addProperty("Id", 1);
        request.addProperty("TabletId", 2);
        request.addProperty("SpeedVisibility", true);

以此类推,直到 WebURL。然后你就可以使用这个代码了。

final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        final HttpTransportSE androidHttpTransport = new HttpTransportSE(
                AppConsts.URL);
        androidHttpTransport.debug = true;
        String soapAction = AppConsts.NAMESPACE + usecaseString;

        try {
            androidHttpTransport.call(soapAction, envelope);
            SoapPrimitive resultSoapPrimitive;
            resultSoapPrimitive = (SoapPrimitive) envelope.getResponse();
            if (resultSoapPrimitive != null) {
                result = resultSoapPrimitive.toString();
                if (AppConsts.ENABLE_LOG)
                    Log.d(AppConsts.GAME_TITLE, "result json : " + result);
            } else {
                if (AppConsts.ENABLE_LOG)
                    Log.d(AppConsts.GAME_TITLE, "result json is NULL!!! ");

            }

【讨论】:

  • 对不起,我的无知,但究竟什么是“usecaseString”..?
  • usecaseString 是您要调用的 Web 服务的方法名称。在这种情况下,它是“UpdateLocation”。
  • 好吧,在这种情况下,它不会起作用。我以前也试过。但是,如果您看到我的 WSDL,您就会明白我没有传递多个值。我传递的是一个对象,而不是多个原始值。
  • 您能否提供这些变量 NAMESPACE、URL 和 SOAP_ACTION 的值?并且您的服务托管在本地主机上,对吗?
  • 但是嵌套对象呢,int
【解决方案2】:

哦,我明白了。this 是教你如何做的教程。

【讨论】:

  • 如果您看到我的问题中的代码,那么您会发现我已经按照那里提到的所有步骤进行操作。
  • 您能否提供这些变量 NAMESPACE、URL 和 SOAP_ACTION 的值?并且您的服务托管在本地主机上,对吗?
  • AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport (URL); androidHttpTransport.debug = true; androidHttpTransport.call(SOAP_ACTION_UPDATE_SETTINGS, envelope);Log.d("MyAPP", "----------------- " + androidHttpTransport.requestDump );。如果您支持我的评论,将不胜感激:)。谢谢。
  • Log.d("MyAPP", androidHttpTransport.requestDump); 这也可以。
  • 你让它工作了还是仍然需要它工作?我想我会花一些时间并尝试亲自完成这项工作,然后与您分享代码。如果您仍然需要它。
【解决方案3】:

在服务器端处理该对象怎么样,当服务器应用程序获取您的对象时,服务器源代码如何处理该对象?

【讨论】:

  • 您好!感谢您花时间回答,但问题现在已经解决了。
  • 如果问题已涵盖,您能否发布答案?谢谢!
猜你喜欢
  • 2012-04-22
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-25
  • 1970-01-01
相关资源
最近更新 更多