Eclipse+Axis2+android构建WebService实战总结

Eclipse+Axis2构建WebService实战总结

 什么是webservice?

企业提供特定的服务service,其他用户通过internet即web访问这些服务。换句话说,WebService是两个计算机之间通讯(交谈)的技术,网络中一台计算机想要调用另一台计算机的方法时,此时可以需要WebService。很火的SOA、云计算在技术层面上都是WebService

用程序员的观点就是:企业提供实现某功能的函数,其他用过通过在线访问这些函数。

webservice两个重要文件:.aar:服务包文件,提供服务,.wsdl:web服务接口定义语言文件,供客户端使用。

webservice关键技术

1、XML:可扩展的标记语言(XML)是Web service平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关的。

2、SOAP:SOAP是web service的标准通信协议,SOAP为simple object access protocoll的缩写,简单对象访问协议.它是一种标准化的传输消息的XML消息格式。即XML文件的消息格式,由这个协议来决定。SOAP简单的理解,就是这样的一个开放协议SOAP=RPC+HTTP+XML:采用HTTP作为底层通讯协议;RPC作为一致性的调用途径,xml作为数据传送的格式。

3、Axis2:Axis2是实现Web Service的一种技术框架,是新一代的SOAP引擎,即通过这个架构很方便地实现webservice.即在服务端通过这个技术支持,很方便地发布webservice服务,使开发只关注具体的商业实现,而由这个框架直接发布,节省了开发者的时间。在客户端同样只关注调用。为了使用这个框架,在3个地方需要部署Axis2的库:web服务器tomcat上、eclipse服务端开发axis2库、eclipse客户端开发ksoap2库。

4、WSDL:WSDL的全称是web service Description Language,是一种基于XML格式的关于web服务的描述语言。其主要目的在于web service的提供者将自己的web服务的所有相关内容,如所提供的服务的传输方式,服务方法接口,接口参数,服务路径等,生成相应的完全文档,发布给使用者。使用者可以通过这个WSDL文档,创建相应的SOAP请求消息,通过HTTP传递给webservice提供者;web服务在完成服务请求后,将SOAP返回消息传回请求者,服务请求者再根据WSDL文档将SOAP返回消息解析成自己能够理解的内容。

5、UDDI:UDDI 是一种目录服务,企业可以使用它对 Web services 进行注册和搜索。UDDI,英文为 "Universal Description, Discovery and Integration",可译为“通用描述、发现与集成服务”。UDDI是一种创建注册表服务的规范,以便大家将自己的web service进行注册发布供使用者查找.然而当服务提供者想将自己的web service向全世界公布,以便外部找到其服务时,那么服务提供者可以将自己的web service注册到相应的UDDI商用注册网站,目前全球有IBM等4家UDDI商用注册网站。因为WSDL文件中已经给定了web service的地址URI,外部可以直接通过WSDL提供的URI进行相应的web service调用。所以UDDI并不是一个必需的web service组件,服务方完全可以不进行UDDI的注册。

webservice服务端的实现

1、tomcat服务器部署:部署Axis2到tomcat:将Axis2.war解压到tomcat的webapps目录下即可,如果有数据库连接,需把数据库连接jar包添加到tomcat的lib目录下,如:oracle的ojdbc14.jar,和mysql的 mysql-connector-java-3.1.11-bin.jar。部署成功后,启动tomcat,可通过http://localhost:8080/axis2/访问,查看是否部署成功。webservice的axis服务存档aar发布文件就发布到tomcat\webapps\axis2\WEB-INF\services这个目录下

2、安装axis2插件到eclipse:解压插件,直接拷贝到eclipse的插件目录plugins,两个插件为:org.apache.axis2.eclipse.codegen.plugin_1.6.0.jar、org.apache.axis2.eclipse.service.plugin_1.6.0.jar。打开Eclipse,选择File/New/Other菜单项,看到如下界面表明安装成功:

安装这两个插件的目的是:方便生成Axis2的服务包(.aar文件)和生成Axis2客户端

3、打包生成axis2服务包:

选择服务程序类文件所在的目录,不包括包,选中Include..,表示在生成的服务包中只包括类文件,不包括其他文件。

选择跳过WSDL文件,WSDL文件会在部署这个服务到Tomcat后,有Axis2自动生成,通过http://localhost:8080/axis2/services/newWs?wsdl可以查看文件内容。

注意:WSDL是web服务定义语言,通过XML的方式对该服务类进行描述,客户端访问服务时要用到这个文件,可以生成这个文件给客户端,也可以上面的在线获取这个文件。

点击“next”,进入添加服务需要的库文件界面:

需要的库文件直接部署到tomcat中,此处不需要添加,进入下一界面:

选择自动生成service.xml文件。点击进入下一界面:


输入服务名和类名,点击load即可找出该服务程序的全部方法。

输入发布路径,和文件名。生成newWs.aar服务包文件。

部署完成后,输入http://localhost:8080/axis2/services/listServices,即可看到已部署的全部服务。

eclipse中webservice不能发布的原因:

1、界面问题,把发布界面最大化或拖拽,是界面刷新,就可以看到输入界面了。

2、发布界面最后一步,load时,没有任何反映,是这个类的代码有问题,例如有加载动态库的代码,动态库找不到,则会没有反映。

3、代码没改变的情况下好像只能生成一次,想在生成的话,需要改代码,或需要重启eclipse

webservie服务端:java调用C++动态库的实现 

 1、在eclipse中编写一个java类文件,应用中的其他类可以调用这个类中的函数

package util;
 
public class InvokeDll 
{
        //测试函数
        public native int testFunc(int a, int b);
               
        //获取最近一次错误代码
        public native int lastErr();   
}


注意:函数要用native修饰符

2、用javah命令生成C++可调用的.h文件

a、上述java类编译生成类文件InvokeDll.class

bset classpath="D:\teatInvokeDll\bin",类文件生成在D:\testInvokeDll\bin\util\InvokeDll.class
c、命令行进入D:\teatInvokeDll\bin

djavah util.InvokeDll
你会发现当前目录下多了一个util_InvokeDll.h文件,文件内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class util_InvokeDll */
 
#ifndef _Included_util_InvokeDll
#define _Included_util_InvokeDll
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     util_InvokeDll
 * Method:    testFunc
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_util_InvokeDll_testFunc
  (JNIEnv *, jobject, jint, jint);
 
/*
 * Class:     util_InvokeDll
 * Method:    lastErr
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_util_InvokeDll_lastErr
  (JNIEnv *, jobject);
 
#ifdef __cplusplus
}
#endif
#endif

3、在VC中生成dll如java2dll.dll

a、新建一个空的dll工程,名叫java2dll

b、把util_InvokeDll.h头文件复制到工程目录下,并添加到header files文件夹里。

c、在source files文件目录中添加一个java2dll.cpp,文件内容是头文件里的方法的实现:

#include  
#include "util_InvokeDll.h"
 
JNIEXPORT jint JNICALL Java_util_InvokeDll_testFunc(JNIEnv *, jobject, jint a, jint b)
{
    int i=0;
        /*HMODULE hModule = ::LoadLibrary("test.dll");
        
          PFUN newfun = (PFUN)::GetProcAddress(hModule,"testFn");
          i = newfun(a,b);
          ::FreeLibrary(hModule);
        */
    i=a+b;
        return i;       
}
 
JNIEXPORT jint JNICALL Java_util_InvokeDll_lastErr(JNIEnv *, jobject)
{
        int i=0;
        return i;
}

d、点击运行”->“编译,这时你会看到很多数据类型没被声明的错误,那是因为util_InvokeDll.h使用了很多JAVA_HOME/include/jni.h文件自定义的数据类型,而jni.h又引
用了JAVA_HOME/include/win32/jni_md.h,这时你需要把jni.hjni_md.h引入到工程里面来,左击工程名工程属性”->“文件/目录”->“包含文件目录JAVA_HOME/includeJAVA_HOME/include/win32文件夹添加,确定后,再次编译一切正常,这时在工程的目录下就找到java2dll.dll文件,这样dll文件就生成了
4、调用其他标准的C++动态库,如test.dll

例如test.dll,是其他人编写的标准的C++动态库,可以在上述注释掉的部分调用,testFn是它里面的函数。

5、在webservice端的java调用

 加载库Java2dll,并调用接口函数:

   static
   { 
     //动态库dll文件要放到系统目录或用绝对路径凋用System.load("绝对路径")
      System.loadLibrary("Java2dll"); 
   }
 
  //实例化调用类
   InvokeDll dll = new InvokeDll(); 
   
   //调用函数
   String strRet = dll.testFunc(a, b) 
 

总结:调用过程:java普通类-->java native类-->jni C++ 动态库-->标准C++动态库,最终实现java普通类对标准C++动态库的调用。

在VC中生成JNI的DLL时,提示找不到jni.h的解决办法:

就是到jdk的安装目录下include下把以下相应的文件,复制到vc目录下的include文件夹下

\jdk\include\jni.h、\jdk\include\win32\jawt_md.h、\jdk\include\win32\jni_md.h上面主是jdk安装目录下的三个文件,分别复制它们到vc目录下的include文件夹下。

如我的安装位置是:D:\Program Files\Microsoft Visual Studio\VC98\Include你们可以根据自己的安装位置自行确定。

webservice服务端连接数据库的实现

 1、eclipse的user library添加数据库连接库jar包。window->java->build path->new->add JARS

 2、把这个连接库添加到项目:项目右键-->build path->add library->user library->选中要加的连接库。

 3、项目中添加连接代码。

 4、把数据库连接库jar包,copy到tomcat安装目录下的lib文件夹中。

webservice android平台客户端的实现

1、获取并加载KSOAP包:

  出现“Could not find class 'org.ksoap2.serialization.SoapObject'”错误解决方法:1、导入ksoap2.jar,不要忘记一定要用 Add External Jars... 不能用Add Jars。2、然后要在Orader and Export 钩选你的ksoap2.jar,否则不会导出到APK。

2、添加访问internet的权限,如果要操作sdcard还要添加读写sdcard的权限,在AndroidManifest.xml文件中添加

3、调用webservice的具体代码及说明:

 //第1步:先定义要访问的webservice相关的几个参数		
		// 定义webservice的URL,注意不包括?wsdl或.aar,对应文件里的documentation字段
        String serviceUrl = "http://101.101.22.121:8080/axis2/services/testWs";  
        //定义命名空间,对应targetNamespace字段
        String NAMESPACE = "http://test";
        //定义要调用的WebService方法名   
        String methodName = "getGramInfo";  
        String SOAP_ACTION = "http://test/getGramInfo";
      
        //第2步:根据WebService的命名空间和调用的方法名 创建SoapObject对象,  
        SoapObject request = new SoapObject(NAMESPACE, methodName); 
        
        //第3步:设置WebService方法的参数 ,参数名可以不一样,但顺序要一致
        String strParam = "1001";
        request.addProperty("arg0",strParam );  
        
        //第4步:创建soap序列化封装对象:SoapSerializationEnvelope,并指定WebService的版本 
        //版本要对应wsdl文件里的soap版本
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);  
        
        //设置soap序列化封装对象属性   
        envelope.bodyOut = request;//也可通过  setOutputSoapObject来设置
        envelope.dotNet = true;  
        
        //第5步:根据webservice的URL创建HttpTransportSE对象(通过HTTP协议传输soap序列化对象)   
        HttpTransportSE ht = new HttpTransportSE(serviceUrl); 
        ht.debug = true;          
		try 
		{	 
			//第6步:开始调用,soap版本不一致时会出现异常
			//同步调用,实际处理的时候,要起个线程处理
			ht.call(SOAP_ACTION, envelope);  
	        
	        //第7步获取返回结果,有两种方法,此处用bodyIn,有时出现异常可能是webservice端的方法有问题造成的
	      //getResponse好像有问题,据说是服务端没搞定的原因,此处不在深究
	        SoapObject soapObject = (SoapObject) envelope.bodyIn; 
	        //SoapObject soapObject =(SoapObject)envelope.getResponse();
	        
	        System.out.println("soapObject" + soapObject);
	        Toast.makeText(this, soapObject.toString(), Toast.LENGTH_LONG).show();
	    		
	    	//获取返回的内容
	    	String ret = soapObject.getProperty("return").toString();  
	    			   	          
	     }  
	    catch (Exception e)  
	    { 
	       e.printStackTrace();
	       Toast.makeText(this, "异常", Toast.LENGTH_LONG).show();        	
	    }
	    
	      

 

你可能感兴趣的:(android)