android 调用.net编写的webservice
JSR172规范来调过webservice感觉贼好用,使用J2ME的JSR172来生成stub并加入到项目中调用,调试了半天最后以失败告终,实在没办法了,只能另寻其它的组件,如果自己通过HttpConnection来连接的获取数据的话要封装的东西太多了,不划算。最后找到了KSoap2,在网上找了N多例子回来看,那些例子基本上都是互抄的,没一个能用,真郁闷。不过还好,起码知道了一条思路,自己慢慢研究,最终成功了,下面附上代码和说明:
附件:开发中ksoap2组件使用了ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar,可以点击链接下载;
1、要使android的程序连接网络必须要在AndroidManifest.xml文件中加入下面这句话:
<!-- 连接网络必须要设置该项 -->
<uses-permission android:name="android.permission.INTERNET"/>
否则会报没权限的异常;
2、使用dotnet写webservcie要注意使用RPC模式,(1)首先在你的webservice类中用System.Web.Services.Protocols.SoapRpcServiceAttribute属性指定;(2)在具体的webservice方法中也要指定属性System.Web.Services.Protocols.SoapRpcMethodAttribute属性;
如:
[WebService(Namespace = "http://tempuri.org/")]//指定webservice的名称空间 [SoapRpcService]//指定使用rpc方式 public class Default : System.Web.Services.WebService { [SoapRpcMethod, WebMethod]//具体方法中也要指定rpc方式 public User HelloWorld(User user) { User us = new User(); us.Name = "Hello " + user.Name; us.Age = user.Age; return us; } } //dotnet中的自定义实体类型 public class User { public string Name { get; set; } public int Age { get; set; } }
————————————————————————————————
3、下面是android中的调用方法
要在webservice传输自定类型必须继承KvmSerializable接口
public class User implements KvmSerializable { private String name = null; private int age = 0; @Override public Object getProperty(int arg0) { // TODO Auto-generated method stub Object res = null; switch(arg0){ case 0: res = this.name; break; case 1: res = this.age; break; default: break; } return res; } @Override public int getPropertyCount() { // TODO Auto-generated method stub return 2; } @Override public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) { // TODO Auto-generated method stub switch(arg0){ case 0: arg2.type = PropertyInfo.STRING_CLASS; arg2.name = "Name"; break; case 1: arg2.type = PropertyInfo.INTEGER_CLASS; arg2.name = "Age"; break; default: break; } } @Override public void setProperty(int arg0, Object arg1) { // TODO Auto-generated method stub if(arg1 == null) return; switch(arg0){ case 0: this.name = arg1.toString(); break; case 1: this.age = Integer.valueOf(arg1.toString()); break; default: break; } } }
4、
//调用webservice的具体方法
public String SayHello(){ String nameSpace = "http://tempuri.org/"; String methodName = "HelloWorld"; String soapAction = "http://tempuri.org/HelloWorld"; String url = "http://192.168.2.51/Default.asmx?wsdl";//后面加不加那个?wsdl参数影响都不大 //建立webservice连接对象 org.ksoap2.transport.HttpTransportSE transport = new HttpTransportSE(url); transport.debug = true;//是否是调试模式 //设置连接参数 SoapObject soapObject = new SoapObject(nameSpace, methodName); User user = new User(); user.setProperty(0, "zhi"); user.setProperty(1, 18); PropertyInfo pi = new PropertyInfo(); pi.setName("user");//webservice接口的参数名,大小写必须跟dotnet中的webservice暴露出来的名字一致 pi.setValue(user); pi.setType(user.getClass()); soapObject.addProperty(pi);//将自定参数加入请求对象中 //设置返回参数 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);//soap协议版本必须用SoapEnvelope.VER11(Soap V1.1) envelope.dotNet = false;//注意:这个属性是对dotnetwebservice协议的支持,如果dotnet的webservice 不指定rpc方式则用true否则要用false envelope.bodyOut = transport; envelope.setOutputSoapObject(soapObject);//设置请求参数 envelope.addMapping(nameSpace, "User", user.getClass());//传对象时必须,参数namespace是webservice中指定的, name是服务器类型的名称, claszz是自定义类的类型 try { transport.call(soapAction, envelope); SoapObject sb = (SoapObject)envelope.bodyIn;//服务器返回的对象存在envelope的bodyIn中 User us= (User)envelope.getResponse();//直接将返回值强制转换为已知对象 return us.getName() + us.getAge(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch(Exception ex){ ex.printStackTrace(); } return ""; }