背景,需要自己用 java 写一个 webservice, 然后写一个 android的客户端去调用它。
我这里折腾了2天,最后终于调成功了。以图为证。
要点:
1, MyEclipse开发webservice
MyEclipse 建 webservice之前,先把 Tomcat 设置好: MyEclipse -> Preference -> MyEclipse -> Servers -> Tomcat -> Configure Tomcat 7.x -> 选Enable,输入Tomcat home directory,tomcat base directory 和 tomcat temp directory 会自己填好,保存
核心的代码:
public String sayHello(String name) { return "hello," + name; }因为用 Eclipse 写 webservice,需要引用到一些的包,可能因为一些未知的原因,老是不停的报错。折腾了一些时间后,果断放弃之。用MyEclipse 10 去写webservice, 一路next, 节省了不少时间。
MyEclipse建webservice主要步聚:新建一个web项目,右击之,新建 -> MyEclipse -> WebService > Project: 你的项目名; Framework: JAX-WS; Strategy: buttom-up scenario -> Next --> Java Class 选 自己新建的HelloWorld, ------- 具体的操作参考 下面别人的2篇日志:
myeclipse10创建jax-ws方式的webservice(一)http://blog.sina.com.cn/s/blog_4d91c1660100xly3.html
myeclipse10创建jax-ws方式的webservice(二) http://blog.sina.com.cn/s/blog_4d91c1660100xlyt.html
webservice弄好后,应该 可以通过URL访问;若别人的机器不能访问,则需要关闭 防火墙 或 给 8080端口开启一个例外:
2,android项目中引用 webservice, 一般用第三方的 ksoap
这里我用的是:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar
(ksoap 2.5.2 的下载地址:http://pan.baidu.com/share/link?shareid=2682138732&uk=503735180
之前我用 ksoap3.0的包,可以调用到别人用.net写的webservice; 但就是调不到自己的service。现在换成低版本的,反而成功了。
3, 关于引用 ksoap2的方式,与我们在java项目中通常的引用方式不一样。
在 android项目中,将 ksoap 2.5.2的包放在 libs文件夹中,选中,右键 -> build path -> add to build path; 选中android项目,右键 -> build path -> config build path -> 在 Order and Export选项卡页面中,选中 ksoap 2.5.2的包 -> 保存
4, 读取 webservice的方法
这个方法既要能够访问 .net的webservice, 又要访问 java的webservice.
贴一下我的 ReadRemoteService.java
package com.tools; import java.util.List; import org.ksoap2.SoapEnvelope; import org.ksoap2.SoapFault; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; import org.ksoap2.transport.AndroidHttpTransport; public class ReadRemoteService { public String NAMESPACE; public String METHODNAME; public String WEBSERVICEURL; public Boolean ISDOTNETSERVICE; public List<String> LISTPARAMS; public ReadRemoteService(String nameSpace,String methodName,String WebServiceUrl,Boolean IsDotNetService,List<String> lstParams) { this.NAMESPACE = nameSpace; this.METHODNAME = methodName; this.WEBSERVICEURL=WebServiceUrl; this.ISDOTNETSERVICE = IsDotNetService; this.LISTPARAMS=lstParams; } public Object Get() { try { return ReadService(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return "ERROR:" + e.getMessage(); } } private Object ReadService() throws Exception { // 命名空间 String nameSpace = this.NAMESPACE; //"http://WebXml.com.cn/"; // 调用的方法名称 String methodName = this.METHODNAME; //"getMobileCodeInfo"; // EndPoint String endPoint = this.WEBSERVICEURL; //"http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"; // SOAP Action String soapAction = this.NAMESPACE + this.METHODNAME; //"http://WebXml.com.cn/getMobileCodeInfo"; // 指定WebService的命名空间和调用的方法名 SoapObject rpc = new SoapObject(nameSpace, methodName); // 设置需调用WebService接口需要传入的两个参数mobileCode、userId /*rpc.addProperty("mobileCode", phoneSec); rpc.addProperty("userId", "");*/ if(this.LISTPARAMS !=null) { if(this.LISTPARAMS.size() % 2 !=0 || this.LISTPARAMS.size()<2) { throw new Exception("params should be even!"); } for(int i=0;i<this.LISTPARAMS.size()-1;i=i+2) { //System.out.println(this.LISTPARAMS.get(i)); rpc.addProperty(this.LISTPARAMS.get(i), this.LISTPARAMS.get(i+1)); //throw new Exception("params:" + this.LISTPARAMS.get(i) + " " + this.LISTPARAMS.get(i+1)); } } // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); //(SoapEnvelope.VER10); envelope.bodyOut = rpc; // 设置是否调用的是dotNet开发的WebService envelope.dotNet = this.ISDOTNETSERVICE; envelope.encodingStyle="UTF-8"; if(!envelope.dotNet) { endPoint = endPoint + "?wsdl"; } // 等价于envelope.bodyOut = rpc; envelope.setOutputSoapObject(rpc); try { // 调用WebService HttpTransportSE transport = new HttpTransportSE(endPoint); //AndroidHttpTransport transport =new AndroidHttpTransport(endPoint); //transport.debug=false; /*transport.call(soapAction, envelope);*/ /* if(!envelope.dotNet) { transport.call(null, envelope); }else*/ { transport.call(soapAction,envelope); } } catch (Exception e) { e.printStackTrace(); return "ERROR:" + e.getMessage(); } // 获取返回的数据 SoapObject object=null; SoapFault error=null; try { object = (SoapObject) envelope.bodyIn; }catch(Exception e) { error = (SoapFault)envelope.bodyIn; // detail =(SoapObject) envelope.getResponse(); System.out.println("Error message : "+error.toString()); } // 获取返回的结果 //String result = object.getProperty(0).toString(); // 将WebService返回的结果显示在TextView中 // lbl1.setText(result); if(error!=null) return error; return object; } }
Common.java
package com.tools; import java.util.ArrayList; import android.widget.TextView; public class Common { public static void SolveRemoteService(Object ServiceResult,TextView tvResult) { java.util.Date now=new java.util.Date(); if(ServiceResult instanceof String) { tvResult.setText(now.toLocaleString() + " " + "String:" + ServiceResult.toString()); }else if(ServiceResult instanceof ArrayList) { StringBuilder sb=new StringBuilder(); Object[] values = ((ArrayList) ServiceResult).toArray(); //正确 for(Object x:values) { sb.append(x.toString() + "\r\n"); } tvResult.setText(now.toLocaleString() + " " + "ArrayList:" +sb.toString()); }else { tvResult.setText(now.toLocaleString() + " " + "Other types:" + ServiceResult.toString()); } } }
1)访问 .net的webservice 样例
String sNameSpace="http://WebXml.com.cn/"; String sMethodName="getMobileCodeInfo"; String sWebserviceUrl="http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"; Boolean IsDotNetService=true; List<String> lstParams=new ArrayList<String>(); lstParams.add("mobileCode"); lstParams.add(sPhone); lstParams.add("userId"); lstParams.add(""); ReadRemoteService readService= new ReadRemoteService(sNameSpace,sMethodName,sWebserviceUrl,IsDotNetService,lstParams); Object Result = readService.Get(); Common.SolveRemoteService(Result,tv_Result);2) 访问 java的webService
注意:前面我在webservice中的参考名是 name, 这里却写的是 arg0, 为什么呢?因为 用MyEclipse在自动帮我生成webservice 相关的代码时,参数名已被改为 arg0.
如果 坚持写 name, 结果只有一个,返回的是:hello,null.
tv_WsResult.setText(""); String sName = et_Name.getText().toString().trim(); String sWsUrl=et_WsUrl.getText().toString().trim(); //sWsUrl应该是 http://192.168.8.***:8080/testWebService/HelloWorldPort /* String sResult = ReadMyService(sName,sWsUrl); java.util.Date now=new java.util.Date(); tv_WsResult.setText(now.toLocaleString() + " " + sResult);*/ String sNameSpace="http://testWebService.com/"; String sMethodName="sayHello"; String sWebserviceUrl=sWsUrl; Boolean IsDotNetService=false; List<String> lstParams=new ArrayList<String>(); lstParams.add("arg0"); lstParams.add(sName); /* java.util.Date now=new java.util.Date(); tv_WsResult.setText(now.toLocaleString() + " " + sName); */ ReadRemoteService readService= new ReadRemoteService(sNameSpace,sMethodName,sWebserviceUrl,IsDotNetService,lstParams); Object Result = readService.Get(); Common.SolveRemoteService(Result,tv_WsResult);
6, 特别注意:在第5步,传参时,命名空间,方法名,WebServiceUrl都不能错。
而且java是大小写敏感的,请确保你的webservice在浏览器中首先能访问。
在模拟器上调 本机的webservice,用 本机的IP地址,不用 localhost.
7, 在android项目的AndroidManifest.xml文件中,需要配置相应可以访问网络、可以访问wifi的权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
</uses-permission>
8,如果是真机 要调用 自己电脑 上的 webservice, 则需要关闭真机上的 wifi 和数据连接,同时 打开 设置 -> 更多 -> Internet 传输 (更过PC连接到internet)
至此,全文 结束。感谢大家。