一、web服务简介
1. 概念
web服务(web service)是一类可以从Internet上获取的服务的总称,它使用标准的XML消息接发系统,并且不受任何操作系统和编程语言的约束,为异构的和不兼容的系统间提供互操作的能力。
web服务通过HTTP、SOAP、XML、WSDL、UDDI等标准协议提供了将异构的、松耦合的应用程序集成在一起的办法。
当前大部分的web应用都是以人为中心,提供人与机器(应用)间的通讯;与此不同,web服务以应用程序为中心,提供应用程序间的直接会话。
2. 相关名词
SOAP(Simple Object Access Protocol):简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的轻量级协议,是一个基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一种语言相互通信。简单的说,SOAP就是一种基于XML的、用于在计算机之间交换信息的协议。
WSDL(Web Service Description Language):web服务描述语言是为web服务指定公共接口的XML语法。公共接口包括所有共用功能的信息、所有XML消息的数据类型、所有特定传输协议的绑定信息和定位特定服务的地址信息。
UDDI(Universal Description, Discovery, and Integration):统一描述、发现和集成是一个描述、发现和连接web服务的技术规范。有了UDDI,公司不但可以发布web服务,还能查找web服务。
3. web服务角色
在web服务体系结构中共有三个主要的角色:
Ø 服务提供者:web服务的提供者,任务是实现服务并在Internet上提供这个服务。
Ø 服务请求者:web服务的消费者。web服务请求者通过打开一个网络连接并发送XML请求来使用已有的web服务。
Ø 服务注册中心:这是一个逻辑上集中式的服务目录。注册中心提供一个集中的地方,供开发者发布新服务或寻找已有服务。因此,它是公司及其服务的集中交换场所。
一般说来,在服务注册中心发布的都是一些提供通用功能的web服务,而我们跟合作伙伴通过web服务传输数据,多是针对具体项目和应用的,并不需要到服务注册中心注册。
4. WSDL简介
WSDL是一种规范,它定义了如何用共同的XML语法描述Web服务。WSDL描述了四种关键的数据:
Ø 描述所有公用函数的接口信息;
Ø 描述消息请求和消息响应的数据类型信息;
Ø 所使用的传输协议的绑定信息;
Ø 用来定位指定服务的地址信息;
由于在web服务客户端的开发中,WSDL文档起着非常重要的作用,需要对WSDL有一个大概的了解。
WSDL规范分为六个主要的元素:
definitions
definitions元素必须是所有WSDL文档的根元素。它定义web服务的名称,声明文档其他部分使用的多个名称空间,并包含所有的元素。
types
types元素描述在客户端和服务器之间使用的所有数据类型。WSDL默认以XML Schema规范作为绑定的类型系统。如果服务只用到了如字符型或整型等XML Schema内置的简单类型,就不需要types元素。
message
message元素描述一个单向消息,无论是单一的消息请求还是单一的消息响应,都有描述。message元素可以包含零个或多个part元素,在请求消息中,part元素指定请求参数,在响应消息中,part元素指定函数返回值。
portType
portType元素结合多个message元素,形成一个完整的单向或往返操作。最普遍的是将一个请求消息和一个响应消息结合在一起,形成一个在SOAP服务中普遍使用的单一的请求/响应操作。
binding
binding元素提供有关portType操作如何通过Internet实际传递的细节。绑定可以通过HTTP GET、HTTP POST或SOAP等多个传输协议实现,最普遍的是通过SOAP实现。
service
service元素定义调用指定服务的地址。一般包含调用SOAP服务的URL。
WSDL规范参考图:
<definitions>:WSDL根元素
|
<types>:传输哪种类型的数据?
|
<message>:传输什么消息?
|
<portType>:支持什么操作(功能)?
|
<binding>:如何通过Internet传输消息? 有什么SOAP特定的细节?
|
<service>:服务在哪里?
|
二、axis简介
axis是Apache组织推出的SOAP引擎,提供创建服务器端、客户端和网关SOAP操作的基本框架。axis项目是Apache组织著名的SOAP项目的后继项目,目前使用java开发的最新版本是1.4,可以从http://apache.justdn.org/ws/axis/1_4/ 下载;Axis C++1.5也已经开发完成。
但Axis并不完全是一个SOAP引擎,它还包括:
Ø 是一个独立的SOAP服务器。
Ø 是一个嵌入Servlet引擎(例如Tomcat)的服务器。
Ø 支持WSDL。
Ø 提供转化WSDL为Java类的工具。
Ø 提供例子程序。
Ø 提供TCP/IP数据包监视工具。
三、axis安装配置
1. 安装
应用Axis开发Web Services,你需要安装如下软件:
Ø JDK1.4.2
Ø 一个支持Servlet的服务器引擎,比如Tomcat,我们假定使用Tomcat作为服务器引擎。
当安装好Tomcat之后,只需将下载的Axis软件包解压缩,将其中的“webapps”目录下的“axis”目录整个拷贝到Tomcat安装目录下的“webapps”目录下即可。
2. 测试
启动Tomcat,访问http://localhost:8090/axis/happyaxis.jsp ,会看到“Axis Happiness Page”页面;
在这个页面中,axis会判断需要的所有jar包是否完全具备,如果缺少某些jar包,会指示你到合适的网址下载。
把下载的jar包放在%CATALINA_HOME%\webapps\axis\ WEB-INF\lib下,重复上面的步骤,直到所需要的jar包都完全具备。
3. 配置
axis测试通过后,为了以后开发上的方便,使用前需要配置一系列的系统变量,需要配置的系统变量如下表所示(假定你已经安装好Tomcat,并配置好了CATALINA_HOME):
Ø AXIS_HOME:%CATALINA_HOME%\webapps\axis
Ø AXIS_LIB:%AXIS_HOME%\lib
Ø CLASSPATH 中加入% AXIS_LIB %下的各个jar包
四、利用axis开发服务端web服务
在跟其他公司合作完成一个大的项目的过程中,有时候对方的程序需要从我们的程序读取某些数据,通过web服务给对方提供服务是选择之一。要从头建立一个能够给对方提供web服务的应用,需要如下的步骤:
1. 新建web应用
按照J2EE规范在%CATALINA_HOME%\webapps新建一个应用,如webserviceTest;
2. 在web应用中配置axis
将%AXIS_HOME%\lib下的各个jar包拷贝到%CATALINA_HOME%\webapps\webserviceTest\WEB-INF\lib下;
将%AXIS_HOME%\WEB-INF下的web.xml拷贝到%CATALINA_HOME%\webapps\webserviceTest\WEB-INF下;
这两个操作相当于在我们的web应用程序中配置了Axis。
3. 编写提供web服务的java类
这个java类跟我们平时用到的java类没有任何不同,需要提供给他人的服务对应该java类的方法。在我们的示例中,提供web服务的java类如下:
在这个类中,提供了两个方法getWsBean()、getName(),其中getWsBean()方法返回一个自定义的对象:
4. 编写deploy.wsdd文件
在%CATALINA_HOME%\webapps\webserviceTest\WEB-INF下新建deploy.wsdd文件,内容如下:
在deploy.wsdd文件中,配置了一个service元素,name属性为wstest,表明我们的web服务名称为wstest。其中className参数是你的想部署的类名(全名),allowedMethods是调用的服务的方法,如果有多个方法的话可以用空格分开(如: <parameter name="allowedMethods" value="getStr getMoney"/>),当用*的时候表示全部。
在deploy.wsdd文件中,还配置了一个handler,用到的LogHandler如下:
注意:很多网上文章里介绍deploy.wsdd文件时都没有提到handler元素和requestFlow元素,可能是axis版本不一致导致的,在我用到的axis1.4里,如果不配置handler,启动Tomcat时就会报错。另外,我怀疑直接使用axis自带的handler可能也可以,没有试过。
5. 发布web服务
编译所有的java类,并将class文件拷贝到%CATALINA_HOME%\webapps\webserviceTest\WEB-INF\classes文件夹下,确保Tomcat已经启动,DOS窗口下进入%CATALINA_HOME%\webapps\webserviceTest\WEB-INF目录,运行如下命令生成server-config.wsdd:
java org.apache.axis.client.AdminClient deploy.wsdd -p8090
如果屏幕上出现:
Processing file deploy.wsdd
<Admin>Done processing</Admin>
表示成功,在%AXIS_HOME%\WEB-INF下会找到server-config.wsdd文件,拷贝到%CATALINA_HOME%\webapps\webserviceTest\WEB-INF下,重新加载webserviceTest应用,现在访问http://localhost:8090/webserviceTest/services/wstest?wsdl ,会出现一个页面包含XML代码,这个就是我们web服务的WSDL文件,如果其他的人要访问我们的web服务,必须知道该WSDL的URL。
6. 关于生成server-config.wsdd文件的几点说明
Ø 因为我的tomcat端口已经改为8090,所以在命令的最后有 -p8090参数,如果你的tomcat端口没有改变,只需运行java org.apache.axis.client.AdminClient deploy.wsdd即可。
Ø 如果在前面配置环境变量时,没有在CLASSPATH 中加入% AXIS_LIB %下的各个jar包,也可以通过如下命令生成server-config.wsdd:
Java -Djava.ext.dirs=lib org.apache.Axis.client.AdminClient deploy.wsdd
Ø 许多网上文章上介绍生成server-config.wsdd文件时使用如下命令:
java org.apache.axis.client.AdminClient -l http://localhost:8090/webserviceTest/services/wstest deploy.wsdd
这种情况下,server-config.wsdd文件应该自动在%CATALINA_HOME%\webapps\webserviceTest\WEB-INF下生成,但是我还没试成功。
Ø 如果在web服务里需要传输自定义对象,还需对生成的server-config.wsdd文件进行修改,注册自定义对象的序列化/反序列化器,具体来说,就是找到如下代码:
修改为:
五、利用axis开发客户端web服务
如果要使用对方提供的web服务,首先必须要有该web服务WSDL的URL,类似http://localhost:8090/webserviceTest/services/wstest?wsdl ,并对WSDL有着一定的了解。
axis支持三种web服务客户端的开发方式,分别是:
Ø 动态调用接口(Dynamic Invocation Interface)
Ø 动态代理服务(Dynamic Proxy)
Ø 静态票根(static stub)
下面分别给予介绍。
1. 动态调用接口
首先看示例代码:
几点说明:
a. 在编写web服务客户端代码时,我们需要获得WSDL的URL,如http://localhost:8090/webserviceTest/services/wstest?wsdl ;需要获得web服务的URL,如http://localhost:8090/webserviceTest/services/wstest;需要获得web服务的名称,如WsTestService;需要获得web服务的端口,如wstest。
WSDL的URL一般由合作伙伴提供;web服务的URL一般是把WSDL的URL去掉后面的参数(即:“?wsdl”字样);web服务的名称对应WSDL文档里service元素的name属性;web服务的端口对应prot元素的name属性。
b. call.setOperationName()方法接受一个QName类型的参数,实例化一个QName对象需要提供web服务的URL和要调用的web服务方法。
c. call.invoke()方法接受一个Object数组参数,数组各个成员是传递给要调用的web服务方法的参数列表。
d. 如果要调用的web服务方法返回一个自定义对象,那么在客户端也需要注册自定义对象的序列化/反序列化器,代码如下:
2. 动态代理服务
首先需要编写代理接口,这个接口必须继承java.rmi.Remote接口,接口提供的方法是web服务提供的所有方法的声明,并且每个接口都要抛出java.rmi.RemoteException异常,如:
编写客户端代码,使用动态代理服务访问web服务,示例代码如下:
说明:
代理接口可以自己手工编写,这需要对WSDL比较熟悉,能够从中抽象出web服务所提供的所有方法及其参数列表、返回值类型等。还有一种选择是利用axis提供的工具生成代理接口,具体方法参见静态票根部分。
如何用动态代理的方法调用返回自定义对象的web服务方法,暂无相关资料。
3. 静态票根
要使用静态票根方法访问web服务,首先必须借助axis生成客户端代码。打开命令行窗口,转到AXIS目录下的WEB-INF子目录。确保Tomcat服务已经处于启动状态,键入命令 :
Java org.apache.axis.wsdl.WSDL2Java http://localhost:8090/webserviceTest/services/wstest?wsdl
该命令执行的结果是在当前所在目录下产生一个子目录,localhost\webserviceTest\services\wstest,该目录下有4个java源文件,分别是:
Ø WsTest.java:定义了web服务代理接口,提供了web服务提供的所有方法的声明参见动态代理服务部分。
Ø WsTestService.java:定义了用于获取Web服务接口的方法。
Ø WsTestServiceLocator.java:接口WsTestService的具体实现。
Ø WstestSoapBindingStub.java:Web服务客户端票根,通过该类与服务器交互。
命令执行后,在当前所在目录还产生一个子目录,BeanService,该目录下有自定义对象的源文件:
ü WsBean.java:web服务提供者自定义的类。
将自动生成的java源文件拷贝到项目合适的地方,并编译。
编写代码访问服务,如下:
说明:
a. 执行WSDL2Java命令自动生成的子目录结构不是固定的,跟WSDL的URL有关系;
b. 自动生成的java源文件的名称不是固定的,跟web服务的名称有关系。
c. 在示例中我将自动生成的代码放在了跟客户端代码WsTestClient.java同样的包中,所以不必引入自动生成的类,否则,需要引入自动生成的类。
d. 使用静态票根调用返回自定义对象的web服务方法时,代码与调用返回XML Schema内置简单类型的方法无任何不同。
六、其他
axis还支持所谓的自动部署,自动部署相当简单,但是限制也较多,网上有许多资料可以参考。个人感觉在真正的项目开发中,恐怕很少有人使用自动部署,更多的是选择通过WSDD自定义部署,也就是我们在第四部分介绍的。七、附录
WSDL文件样例
(完)