【问题标题】:consuming list of object from asp.net webservice using ksoap in android app在android应用程序中使用kso​​ap从asp.net webservice中消费对象列表
【发布时间】:2018-11-23 16:08:04
【问题描述】:

我陷入了一种情况,我必须使用一个 asp.net 网络服务,该服务在我的 android 应用程序中返回一个对象列表,有问题的网络服务返回一个 programmedflights 列表,其中包含 flightCode,flightDate,flightType 等参数,下面是我在浏览器中调用 Web 服务时得到的 xml 结果

我希望我的应用程序能够像上面一样读取programmedflights 并将它们设置为新的programmedflights 对象,因为我的android 应用程序中的类是我在android 应用程序中的programmedflights

public class programmed_flights {
    private int    id;
    private String company;
    private String flight_date;
    private String flight_num;
    private String air_port;
    private String flight_type;
    private String status;

    public programmed_flights(){

    }

    public programmed_flights(String company, String flight_date, String flight_num, String air_port,String flight_type,String status ) {
        this.company = company;
        this.flight_date = flight_date;
        this.flight_num = flight_num;
        this.air_port = air_port;
        this.flight_type = flight_type;
        this.status = status;
    }

    public String flightToString() {
        return  company+" "+flight_date+" "+flight_num+" "+air_port+" "+flight_type+" "+status;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getFlight_date() {
        return flight_date;
    }

    public void setFlight_date(String flight_date) {
        this.flight_date = flight_date;
    }

    public String getFlight_num() {
        return flight_num;
    }

    public void setFlight_num(String flight_num) {
        this.flight_num = flight_num;
    }

    public String getAir_port() {
        return air_port;
    }

    public void setAir_port(String air_port) {
        this.air_port = air_port;
    }

    public String getFlight_type() {
        return flight_type;
    }

    public void setFlight_type(String flight_type) {
        this.flight_type = flight_type;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }


}

这是我第一次在 android 中使用 ksoap,我完全没有任何可能的解决方案,我在网上查看了有关如何完成这项工作的各种帖子,但没有一个是我所期望的,任何帮助都会非常感激

这也是我用来消费服务的代码

public String getSoap(long option, String dt){

        SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE,OPERATION_NAME);
        PropertyInfo opt=new PropertyInfo();
        opt.setName("option");
        opt.setValue(option);
        opt.setType(long.class);
        request.addProperty(opt);

        PropertyInfo date=new PropertyInfo();
        date.setName("dt");
        date.setValue(dt);
        date.setType(String.class);
        request.addProperty(date);

        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS);
        Object response=null;

        try
        {
            httpTransport.call(SOAP_ACTION, envelope);
            response = envelope.getResponse();
        }
        catch (Exception exception)
        {
            exception.printStackTrace();
            response=exception.toString();
        }
        return response.toString();
        }
    } 

【问题讨论】:

    标签: android asp.net web-services arraylist android-ksoap2


    【解决方案1】:

    在与这个问题斗争了一周之后,我终于找到了正确的方法,在对该主题进行了大量研究之后,我发现大多数关于在 android 应用程序中从 dotnet Web 服务中消耗对象列表的帖子都留下了这样做的一个重要方面主要是因为帖子没有更新 现在回到我的问题

    从 android 调用 web 服务意味着您正在启动一个可能需要时间才能给出结果的任务,因为应用程序必须与服务器通信然后接收响应,要正确执行此操作,您必须实现线程,这意味着执行应用程序正常运行时在后台执行任务,等待响应在 android 中执行此操作,您必须使用 AsyncTaskService 类,但对于我们的网络服务,我将使用 AsyncTask

    所以要正确解决上述问题,我们必须首先创建一个实现KvmSerialisationprogrammedFlights 类,因为我们的Web 服务返回一个programmedFlights 对象列表,我们需要将SoapEnvelope 中的序列化类发送到帮助服务器识别我们的对象属性的正确映射,以便接收我们想要的正确响应,了解更多关于 ksoap2 KvmSerialisation 访问这个link

    下面是我们实现KvmSerialasationprogrammedFlights

    package com.YouPakageName.serialisation;
    
    //importing needed classes
    import org.ksoap2.serialization.KvmSerializable;
    import org.ksoap2.serialization.PropertyInfo;
    import java.util.Hashtable;
    
    public class programmedFlights  implements KvmSerializable {
        //setting properties
        public int    id;
        public String company;
        public String flight_date;
        public String flight_num;
        public String flight_type;
        public String air_port;
        public String status;
    
        //default constructor
        public programmedFlights(){
    
        }
        //constructor with parameters
        public programmedFlights(int id,String company,String flight_date,String flight_num,String flight_type,String air_port,String status){
    
            this.id = id;
            this.company = company;
            this.flight_date = flight_date;
            this.flight_num = flight_num;
            this.flight_type = flight_type;
            this.air_port = air_port;
            this.status = status;
        }
    
        //here we override our kvmSerialisation methods an adapt to our class
    
        //needed method
        @Override
        public Object getProperty(int index) {
    
            switch(index)
            {
                case 0:
                    return id;
                case 1:
                    return company;
                case 2:
                    return flight_date;
                case 3:
                    return flight_num;
                case 4:
                    return flight_type;
                case 5:
                    return air_port;
                case 6:
                    return status;
            }
    
            return null;
        }
        //needed method
        //here just return the sum of properties in the class
        @Override
        public int getPropertyCount() {
    
            return 7;
        }
    
        //needed method
        @Override
        public void setProperty(int index, Object value) {
    
            switch(index)
            {
                case 0:
                    id = Integer.parseInt(value.toString());
                    break;
                case 1:
                    company = value.toString();
                    break;
                case 2:
                    flight_date = value.toString();
                    break;
                case 3:
                    flight_num = value.toString();
                    break;
                case 4:
                    flight_type = value.toString();
                    break;
                case 5:
                    air_port = value.toString();
                    break;
                case 6:
                    status = value.toString();
                    break;
                default:
                    break;
            }
        }
    
    
    
        //needed method
        @Override
        public void getPropertyInfo(int index, Hashtable properties, PropertyInfo info) {
    
            switch(index)
            {
                case 0:
                    info.type = PropertyInfo.INTEGER_CLASS;
                    info.name = "id";
                    break;
                case 1:
                    info.type = PropertyInfo.STRING_CLASS;
                    info.name = "company";
                    break;
                case 2:
                    info.type = PropertyInfo.STRING_CLASS;
                    info.name = "flight_date";
                    break;
                case 3:
                    info.type = PropertyInfo.STRING_CLASS;
                    info.name = "flight_num";
                    break;
                case 4:
                    info.type = PropertyInfo.STRING_CLASS;
                    info.name = "flight_type";
                    break;
                case 5:
                    info.type = PropertyInfo.STRING_CLASS;
                    info.name = "air_port";
                    break;
                case 6:
                    info.type = PropertyInfo.STRING_CLASS;
                    info.name = "status";
                    break;
                default:break;
            }
        }
    
        //just a method to present our class in String form 
        //not actually needed
        @Override
        public String toString() {
            return "flightPrograms{" +
                    "id=" + id +
                    ", company='" + company + '\'' +
                    ", flight_date='" + flight_date + '\'' +
                    ", flight_num='" + flight_num + '\'' +
                    ", flight_type='" + flight_type + '\'' +
                    ", air_port='" + air_port + '\'' +
                    ", status='" + status + '\'' +
                    '}';
        }
    }
    

    在创建我们的序列化类之后,现在这是我们的主要活动,带有一个私有 AsyncTask 类,我们将使用它来调用我们的 Web 服务并返回我们的对象

    对象将在列表中返回,我们将在 TextView 中以列表的长度显示其中一个

    //importing needed classes
    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.SoapFault;
    import org.ksoap2.serialization.PropertyInfo;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.HttpResponseException;
    import org.ksoap2.transport.HttpTransportSE;
    import org.xmlpull.v1.XmlPullParserException;
    import android.widget.TextView;
    
    public class test_db extends FragmentActivity implements AdapterView.OnItemSelectedListener{
    
    TextView tdate = null;
    
     //variables needed to call our web service
        private final String SOAP_ACTION = "http://yourOwnNAMESPACE.org/getTodayFlights";
    
        private final String OPERATION_NAME = "getTodayFlights";
    
        private final String WSDL_TARGET_NAMESPACE = "http://yourOwnNAMESPACE/";
    
        private final String SOAP_ADDRESS = "http://www.yourServiceHost/WebServicePage.asmx";
    
        //holds the recieved list of objects 
        public programmedFlights[] list;
    
        //property we send to WebMethod
        Long getnet = Long.valueOf(1);
    
    //method for looping into response to get out objects (deserialisation)
        public static programmedFlights[] RetrieveFromSoap(SoapObject response)
            {
                programmedFlights[] flights = new programmedFlights[response.getPropertyCount()];
                for (int i = 0; i < flights.length; i++) {
                    SoapObject obj = (SoapObject)response.getProperty(i);
                    programmedFlights flyer = new programmedFlights();
                    flyer.id = Integer.parseInt(obj.getProperty(0).toString());
                    flyer.company = obj.getProperty(1).toString();
                    flyer.flight_date = obj.getProperty(2).toString();
                    flyer.flight_num = obj.getProperty(3).toString();
                    flyer.flight_type = obj.getProperty(4).toString();
                    flyer.air_port = obj.getProperty(5).toString();
                    flyer.status = obj.getProperty(6).toString();
                    flights[i] = flyer;
                }
                return flights;
            }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_test_db);
    
    //setting our TextView
    tdate = findViewById(R.id.textView6);
    
    //calling the AsyncTask to execute our Wedservice in doinBackground
         final AsyncTask<Object, Void, Object> execute = new mycall().execute((Object) null);
    
       }
    
    private class mycall extends AsyncTask<Object,Void,Object>{
        @Override
        protected Object doInBackground(Object... objects) {
            SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE, OPERATION_NAME);
    //setting request properties
                PropertyInfo opt = new PropertyInfo();
                opt.setName("option");
                opt.setValue(getnet);
                opt.setType(long.class);
                request.addProperty(opt);
    //creating our envelope
                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                envelope.dotNet = true;
                envelope.setOutputSoapObject(request);
    //this part is important for getting our list of objects, never forget to add
    //it to the envelope ******
                envelope.addMapping(WSDL_TARGET_NAMESPACE, "programmedFlights", new programmedFlights().getClass());
                Log.e("request",request.toString());
                HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS,100000);
                httpTransport.debug = true;
                try {
    //calling WebMethod
                    httpTransport.call(SOAP_ACTION, envelope);
    //getting WebMethod response 
                    SoapObject response = (SoapObject) envelope.getResponse();
    //Getting our objects from soap response
                    list = RetrieveFromSoap(response);
        //catching errors
                } catch (HttpResponseException e) {
                    e.printStackTrace();
                    errors = errors+"http_response_error "+e.toString();
                    return errors;
                } catch (SoapFault soapFault) {
                    soapFault.printStackTrace();
                    errors = errors+"soapFault_error "+soapFault.toString();
                    return errors;
                } catch (XmlPullParserException e) {
                    e.printStackTrace();
                    errors = errors+"Xml_pull_error "+e.toString();
                    return errors;
                } catch (IOException e) {
                    e.printStackTrace();
                    errors = errors+"I/O_error "+e.toString();
                    return errors;
                }
                return list;
            }
    
    
            @Override
            protected void onPostExecute(Object list) {
                if(list.getClass() == programmedFlights[].class ){
                    programmedFlights[] data = (programmedFlights[]) list;
                    tdate.setText(data.length+" "+data[0].toString());
                    tdate.append(data[1].toString());
                }else if(list.getClass() == String.class){
                    String error = (String) list;
                    tdate.setText(error);
                }
                super.onPostExecute(list);
            }
        }
    
     }
    

    注意:永远不要直接从 doinBackground 获取 WebMethod 响应,这将导致空响应并且 java.io.IOException 始终使用 onPostExecute 得到你的回应,就像我在上面用这条线做的那样

    final AsyncTask<Object, Void, Object> execute = new mycall().execute((Object) null);
    

    它在onPostExecute 方法中告诉您的活动在doinBackground 在后台执行并将响应返回给onPostExecute 之后如何处理您的响应

    我希望这将帮助许多人在 android 上遇到此类 Web 服务问题, 有不明白的可以留言,我会回来简单解释的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      相关资源
      最近更新 更多