用Axis 1.1 for Java进行Web Services开发
下面的所有几乎来自Axis1.1的文档。但不完全来自文档,本人做了部分修改,这些修改完全出自国内读者的需要。
什么是SOAP?
SOAP是一个基于XML的用于应用程序之间通信数据编码的传输协议。最初由微软和Userland Software提出,随着不断地完善和改进,SOAP很快被业界广泛应用,目前完全发布版本是1.1。在其发展过程中,W3C XML标准工作小组积极促成SOAP成为一个真正的开放标准。在写作此文档之时,SOAP1.2草案已经发布,1.2对1.1中相对混乱的部分做了改进。
SOAP被广泛作为新一代跨平台、跨语言分布计算Web Services的重要部分。
这里太肤浅的说明,请参阅我的整理《一步一步学习SOAP》。
什么是Axis?
Axis本质上就是一个SOAP引擎,提供创建服务器端、客户端和网关SOAP操作的基本框架。Axis目前版本是为Java编写的,不过为C++的版本正在开发中。
但Axis并不完全是一个SOAP引擎,它还包括:
是一个独立的SOAP服务器。
是一个嵌入Servlet引擎(例如Tomcat)的服务器。
支持WSDL。
提供转化WSDL为Java类的工具。
提供例子程序。
提供TCP/IP数据包监视工具。
Axis是第三代Apache SOAP,从2000年起,SOAP v2开发小组开始讨论如何让Axis更加灵活、可配置,以及能够处理SOAP和来自W3C的各种XML标准。通过不断地讨论和代码编写,Axis目前取得了如下成果:
速度提高。 Axis通过基于事件的SAX对XML文档进行处理,从而在速度和效率上比Apache SOAP有所提高。
灵活性提高。
稳定性提高。
提供面向组件的部署。
提供一个简洁的传输抽象框架。其核心引擎完全于传输方式独立。从而使基于何种协议传输的选择更加灵活。
支持WSDL。包括到处WSDL和客户代理生成等。
在目前发行1.1版本中有什么东西?
SOAP1.1/1.2引擎。
灵活的配置和部署系统。
支持及时自动生成SOAP服务(JWS)。
支持所有的基本数据类型,为自定义串行操作提供类型映射系统。
JavaBean的自动串行操作,包括将自定义属性类型映射到XML的属性和元素。
RPC和基于消息的SOAP服务提供者。
从部署好的服务自动生成WSDL。
WSDL2Java工具可以从WSDL描述文件中产生相应的客户和服务器端SOAP操作框架。
初步提供安全扩展,能够与Servlet2.2安全集成。
通过HTTP Cookie和与传输无关的SOAP头信息提供会话跟踪。
初步支持带附件的SOAP消息。
在EJB方面提供把EJB作为Web服务的访问途经。
基于Servlet的HTTP传输。
基于JMS的传输。
独立的服务器(但需要HTTP 服务器和Servlet容器支持)。
提供客户端、服务器端相关应用程序的样例。
Axis的运行需要如下组件包
axis.jar
jaxrpc.jar
saaj.jar
commons-logging.jar
commons-discovery.jar
wsdl4j.jar
符合JAXP-1.1的XML处理器。
一步一步开始用Axis进行Web Services操作
下面给出一段简单的调用Web Services方法的客户端代码(由于原文档中直接用导入包的方式初学者不易了解那个类在那个包中,所以下面我做了一些简单的修改,希望能给学习者清楚的思路):
public class TestClient {
public static void main(String[] args) {
try{
String endpoint="http://localhost:8080/axis/SayHello.jws?wsdl";// 调用的web服务的url地址,这里是一个http请求,希望得到的结果是wsdl文档。
org.apache.axis.client.Service service=new org.apache.axis.client.Service();//建立请求服务框架实例。
/*
* org.apache.axis.client.Service实现JAX-RPC's javax.xml.rpc.Services接口
* 该接口充当产生下面提到的org.apache.axis.client.Call实例
* 的角色。
*/
org.apache.axis.client.Call call=(org.apache.axis.client.Call)service.createCall();//从框架中生成一个维护调用的实例。
/*
* org.apache.axis.client.Call实现了JAX-RPC's javax.xml.rpc.Call接口。
*/
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new javax.xml.namespace.QName("http://www.edu-edu.com.cn/luopc/ws","echoString"));//设置需要调用的函数名称
String result=(String)call.invoke(new Object[]{"hello!"});
System.out.println(result);
}catch(Exception e){
System.err.println(e.toString());
}
}
}
上面的代码可能和原文档中不同,并且在名称空间、函数多态上会给用户造成糊涂。不过别急,我在翻译手册的同时会加入很多解释的代码,假如哪位纯粹看不懂可以通过邮件获取帮助:luopc@edu-edu.com.cn ,邮件主题必须是我提供的文档名称。
通过上面的调用代码,最终生成向服务器请求SOAP信息包,具体XML内容如下:
<?xml version="1.0" encoding="UTF-8"?<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<SOAP-ENV:Body <ns1:echoString xmlns:ns1="http://www.edu-edu.com.cn/luopc/ws" <arg0 xsi:type="xsd:string"Hello!</arg0 </ns1:echoString</SOAP-ENV:Body</SOAP-ENV:Envelope
这里我不再多少,细心的朋友请从代码中找相应的对应信息来进行自己的逻辑理解。至于SOAP协议在我以后的翻译文档中会加入进去。
从上面的代码中我们在调用的时候输入了参数new Object[]{“hello!”}。然后从生成的SOAP请求包中可以看到自动序列化成<arg0 xsi:type="xsd:string"Hello!</arg0。你可以看到参数名称为arg0,类型为xsd:string。其实在Axis客户端我们可以直接通过具体的方法来设置每一个参数名称、类型以及返回值类型。如下代码:
call.addParameter("testParam",org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);call.setReturnType(org.apache.axis.Constants.XSD_STRING);
加入上面的代码之后生成如下的SOAP信息:
<?xml version="1.0" encoding="UTF-8"?<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<SOAP-ENV:Body <ns1:echoString xmlns:ns1="http://www.edu-edu.com.cn/luopc/ws" <testParam xsi:type="xsd:string"Hello!</testParam </ns1:echoString</SOAP-ENV:Body</SOAP-ENV:Envelope
可以作简单的对比。
也许你会迷惑设置参数名称和不设置参数名称有什么区别的疑问。这里作简单的解释:
1. 为什么要call.setReturnType(org.apache.axis.Constants.XSD_STRING)?
上面你可以调用或者可以不调用,但当返回结果中没有标明数据类型时Axis就不知道如何进行数据类型转换。当然假如返回类型你很清楚并且返回应答SOAP的结果中表明了相应的数据类型你便可以不进行上面的函数调用。
2. 为什么要设置参数名称和类型?
好了,下在你知道了如何调用Web Services了,下面告诉你如何写作和发布Web Services。
通过Axis发布Web Services
这里写作一个简单的类,然后一步一步进行发布。希望用户能够从中理出一些思路来。我在其他的关于Web Services的文章中会专门针对Web Services的通用发布方法。虽然Web Services牵涉到很多复杂的知识,但请大家不要感觉到这些操作简单,也许你已经有很多疑问,没关系,记下你的疑问,不断的投试。
public class SayHello {public String echoString(String hello){return hello;}}
哈哈,这个类是不是太简单了。
一步一步来。
Axis提供两种将Java类发布成Web Services的途径,即即时快速自动发布和通过配置文件进行发布。我们首先从最轻易部署的入手。
JWS----即时部署
简单说就是将自己写的Java类源文件按一定的规则Copy到特定的目录下便可自行被Axis部署。具体步骤如下:
将上面写的SayHello.java复制到axis目录下。
改名为SayHello.jws。
注重:在你写的类中不能有具体包的信息,因为这正是Axis即时部署不支持的。
运行我们前面写的客户端进行测试,运行结果是hello!。