如何使用KSOAP2从Android调用.NET Web服务?
调用Web服务时遇到问题。 我在服务器上有一个.NET Web服务,我在Android中使用KSOAP2(ksoap2-j2se-full-2.1.2)。 运行程序时,我得到了一个像“org.ksoap2.serialization.SoapPrimitive”运行时exception。 我该怎么办?
这是我的代码。
package projects.ksoap2sample; import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; import android.app.*; import android.os.*; import android.widget.TextView; public class ksoap2sample extends Activity { /** Called when the activity is first created. */ private static final String SOAP_ACTION = "http://tempuri.org/HelloWorld"; private static final String METHOD_NAME = "HelloWorld"; private static final String NAMESPACE = "http://tempuri.org/"; private static final String URL = "http://192.168.1.19/TestWeb/WebService.asmx"; TextView tv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv=(TextView)findViewById(R.id.text1); try { SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); //request.addProperty("prop1", "myprop"); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet=true; envelope.setOutputSoapObject(request); HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); androidHttpTransport.call(SOAP_ACTION, envelope); Object result = (Object)envelope.getResponse(); String[] results = (String[]) result; tv.setText( ""+results[0]); } catch (Exception e) { tv.setText(e.getMessage()); } } }
这很简单。 你得到的结果是一个原始的Object
。
你的代码:
Object result = (Object)envelope.getResponse();
正确的代码:
SoapObject result=(SoapObject)envelope.getResponse(); //To get the data. String resultData=result.getProperty(0).toString(); // 0 is the first object of data.
我认为这应该肯定工作。
你的.NET Web服务是怎样的?
我使用code.google.com中的ksoap 2.3来获得相同的效果。 我跟着“代码项目”的教程(这是很棒的顺便说一下)
每次我用
Integer result = (Integer)envelope.getResponse();
获取我的web服务的结果(不pipetypes,我试过对象,string,诠释)我碰到了org.ksoap2.serialization.SoapPrimitive
exception。
我find了一个解决scheme(解决方法)。 我必须做的第一件事是从我的web服务方法中删除“SoapRpcMethod()属性。
[SoapRpcMethod(), WebMethod] public Object GetInteger1(int i) { // android device will throw exception return 0; } [WebMethod] public Object GetInteger2(int i) { // android device will get the value return 0; }
然后,我将我的Android代码更改为:
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
但是,我得到一个SoapPrimitive对象,它有一个私有的“值”字段。 幸运的是,值通过toString()
方法传递,因此我使用Integer.parseInt(result.toString())
来获取我的值,这对我来说已经足够了,因为我没有任何需要获取的复杂types从我的Web服务。
这是完整的来源:
private static final String SOAP_ACTION = "http://tempuri.org/GetInteger2"; private static final String METHOD_NAME = "GetInteger2"; private static final String NAMESPACE = "http://tempuri.org/"; private static final String URL = "http://10.0.2.2:4711/Service1.asmx"; public int GetInteger2() throws IOException, XmlPullParserException { SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); PropertyInfo pi = new PropertyInfo(); pi.setName("i"); pi.setValue(123); request.addProperty(pi); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(request); AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL); androidHttpTransport.call(SOAP_ACTION, envelope); SoapPrimitive result = (SoapPrimitive)envelope.getResponse(); return Integer.parseInt(result.toString()); }
inputSoapPrimitive的信封:
SoapPrimitive result = (SoapPrimitive)envelope.getResponse(); String strRes = result.toString();
它会工作。
您可以使用下面的代码来调用Web服务并获取响应。确保您的Web服务以数据表格式返回响应。如果您使用的是来自SQL Server数据库的数据,则此代码可以帮助您。如果您使用MYSQL ,则需要改变一件事就是从句子obj2=(SoapObject) obj1.getProperty("NewDataSet");
replace单词NewDataSet obj2=(SoapObject) obj1.getProperty("NewDataSet");
由DocumentElement
private static final String NAMESPACE = "http://tempuri.org/"; private static final String URL = "http://localhost/Web_Service.asmx?"; // you can use IP address instead of localhost private static final String METHOD_NAME = "Function_Name"; private static final String SOAP_ACTION = NAMESPACE + METHOD_NAME; SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); request.addProperty("parm_name", prm_value); // Parameter for Method SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(request); HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); try { androidHttpTransport.call(SOAP_ACTION, envelope); //call the eb service Method } catch (Exception e) { e.printStackTrace(); } //Next task is to get Response and format that response SoapObject obj, obj1, obj2, obj3; obj = (SoapObject) envelope.getResponse(); obj1 = (SoapObject) obj.getProperty("diffgram"); obj2 = (SoapObject) obj1.getProperty("NewDataSet"); for (int i = 0; i < obj2.getPropertyCount(); i++) //the method getPropertyCount() return the number of rows { obj3 = (SoapObject) obj2.getProperty(i); obj3.getProperty(0).toString(); //value of column 1 obj3.getProperty(1).toString(); //value of column 2 //like that you will get value from each column }
如果你有任何问题,你可以写我..
如果预期有多个结果,则getResponse()
方法将返回包含各种响应的Vector
。
在这种情况下,有问题的代码变成:
Object result = envelope.getResponse(); // treat result as a vector String resultText = null; if (result instanceof Vector) { SoapPrimitive element0 = (SoapPrimitive)((Vector) result).elementAt(0); resultText = element0.toString(); } tv.setText(resultText);
基于ksoap2-android(mosabua fork)的答案
我想你不能打电话
androidHttpTransport.call(SOAP_ACTION, envelope);
在主线程。
networking操作应该在不同的线程上完成。
创build另一个线程或AsyncTask来调用该方法。