已解决:android 模拟器调用本地的webservice 引用不到

背景,需要自己用 java 写一个 webservice, 然后写一个 android的客户端去调用它。


我这里折腾了2天,最后终于调成功了。以图为证。

已解决:android 模拟器调用本地的webservice 引用不到_第1张图片


要点:

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端口开启一个例外:

      已解决:android 模拟器调用本地的webservice 引用不到_第2张图片


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());
   	  }
	}
}

5, 在android项目中调用 刚才的方法的样例

     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)


至此,全文 结束。感谢大家。

     


你可能感兴趣的:(已解决:android 模拟器调用本地的webservice 引用不到)