Java RPC 通信机制之 SOAP:应用 Apache Axis进行 Web Service开发

一、概述
SOAP 原意为 Simple Object Access Protocol (简单对象访问协议),是一个用于分布式环境的、轻量级的、基于 XML 进行信息交换的通信协议( SOAP is an XML based protocol used to exchange information throughout a distributed environment )。

以下是 w3c 网站上的定义:

SOAP Version 1.2 (SOAP) is a lightweight protocol intended for exchanging structured information in a decentralized, distributed environment. It uses XML technologies to define an extensible messaging framework providing a message construct that can be exchanged over a variety of underlying protocols. The framework has been designed to be independent of any particular programming model and other implementation specific semantics.

可以认为 SOAP 是 XML-RPC 的高级版本,二者基于相同的原理:利用 HTTP + XML 封装进行 RPC 调用。

SOAP 最初由 MS 发起研究,用以解决 MTS/COM 资源消耗大,不够轻巧等问题,后逐渐被 IBM 等巨头接纳并加入研究,现已提交 W3C ,成为 Web Service 应用传输标准。对于轻量级、可扩展 Web Service 应用协议的需求促成了 SOAP 的广泛应用,也间接促进了 XML 的流行。关于相关历史的更多信息,见 http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/SOAPSpecificationIndexPage.mspxhttp://www-128.ibm.com/developerworks/cn/webservices/ws-ref1/index.html

二、 SOAP数据包结构解析
SOAP 的消息被称为一个 SOAP Envelope ,包括 SOAP Header 和 SOAP Body 。其中, SOAP Header 可以方便的插入各种其它消息来扩充 Web Service 的功能,比如 Security (采用证书访问 Web Service ), SOAP Body 则是具体的消息正文,也就是 Marshall 后的信息。

SOAP 调用的时候,也就是向一个 URL (比如 http://api.google.com/search/beta2 )发送 HTTP Post 报文(根据 SOAP 规范, HTTP Get 报文也可被支持),调用方法的名字在 HTTP Request Header SOAP-Action 中给出,接下来就是 SOAP Envelope 了。服务端接到请求,执行计算,将返回结果 Marshall 成 XML ,用 HTTP 返回给客户端。

以下是一个典型的 SOAP 数据包:

< s:Envelope xmlns:s = "http://www.w3.org/2003/05/soap-envelope ">

      < s:Header >

            < m:transaction xmlns:m = "soap-transaction " s:mustUnderstand = "true ">

                  < transactionID > 1234</ transactionID >

            </ m:transaction >

      </ s:Header >

      < s:Body >

            < n:purchaseOrder xmlns:n = "urn:OrderService ">

                  < from >

                        < person > Christopher Robin</ person >

                        < dept > Accounting</ dept >

                  </ from >

                  < to >

                        < person > Pooh Bear</ person >

                        < dept > Honey</ dept >

                  </ to >

                  < order >

                        < quantity > 1</ quantity >

                        < item > Pooh Stick</ item >

                  </ order >

            </ n:purchaseOrder >

      </ s:Body >

</ s:Envelope >

其中包含了一些 SOAP 规范定义的标签,同时也可以包含一些具体应用相关的标签。

Note:

如果你是一个普通的应用开发者,以上介绍已经足够了,因为相应的 SOAP 应用平台会负责完成相应 SOAP 数据包的打包和解析;如果你是一个 SOAP 应用平台的实现者,关于 SOAP 基础理论的更多介绍可参考《 Programming Web Services with SOAP 》一书或 SOAP Specification ( http://www.w3.org/TR/soap12-part0/ )。

三、安装 Apache Axis
Apache Axis 本身也是一个 Web Project ,它内建了对 SOAP 的编码、解析,并为 Client 提供了一些使用 SOAP Service 的 API ,同时,为 Web Service 的发布提供管理,并对 Client 提交的处理请求作出响应。对于基于 Axis 的应用而言,我们可以将注意力完全放在具体 Service 和 Client 的设计上,而无需考虑中间的传输过程(对于 Client 而言,还需要使用一些 Axis 提供的访问 SOAP 服务的特定 API ),这一点是与 XML RPC 不同的地方。

Apache Axis 可以从 http://ws.apache.org/axis/ 下载,当前的最新版本是 1.4 。

安装 Axis 的过程很简单:

1 、解压 Axis 到任意目录下;

2 、拷贝 Axis 目录下的 webapps/axis 目录到 %TOMCAT_HOME%/webapps 下;

3 、为了便于编译和测试程序,添加环境变量 :

AXIS_HOME      Axis 的解压目录

AXIS_LIB      %AXIS_HOME%/lib

AXISCLASSPATH      %AXIS_LIB%/axis.jar;%AXIS_LIB%/commons-discovery-0.2.jar;%AXIS_LIB%/commons-logging-1.0.4.jar;%AXIS_LIB%/jaxrpc.jar;%AXIS_LIB%/saaj.jar;%AXIS_LIB%/log4j-1.2.8.jar

完成上述工作后,启动 Tomcat ,并用 IE 打开: http://localhost:8080/axis/ ,点击其中的 Validation 、 List 两个链接,如果没有报告任何错误,则说明 Axis 安装成功。

关于 Apache Axis 安装的更多信息可以参考官方文档: http://ws.apache.org/axis/java/install.pdf

四、举例
有了上面对 SOAP 的基本理解,下面我们体验一下 Apache Axis 1.4 提供的 SOAP 服务。

以下面 EchoService 为例:

public class EchoService {

      public String echoString(String name) {

            return name;

      }

}

其对应的 Client 程序如下所示:

package demo.soap;

 

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

 

import javax.xml.namespace .QName;

 

public class EchoClient {

      public static void main(String [] args) {

            try {

                  String endpoint = "http://localhost:8080/axis/EchoService.jws" ;

                  // Create Service and Call object to set up a SOAP RPC

                  Service service = new Service();

                  Call call = (Call)service.createCall();

                  // Tells which service and method will be invoked

                  call.setTargetEndpointAddress(new java.net.URL(endpoint));

                  call.setOperationName(new QName("echoString" ));

                  // Invoke method with required parameters

                  String ret = (String)call.invoke(new Object[] { "Hello!" });

 

                  System.out.println("Sent 'Hello!', got '" + ret + "'" );

            } catch (Exception e) {

                  System.err.println(e.toString());

            }

      }

}

对于 Client 程序而言,对 Axis Service 进行访问的基本方法是:

1 、创建 Service 及 Call 对象;

2 、设置 Call 对象属性,如访问点(标明将访问哪个 Axis Service )及方法名等;

3 、传入参数数组,调用 Call 对象的 invoke 方法。

可使用如下命令编译 EchoClient.java :

javac -cp %AXISCLASSPATH% EchoClient.java

在 Axis 中,存在两种发布 SOAP Service 的方法。

方法一:

将源程序 EchoService.java 拷贝到 %TOMCAT_HOME%/webapps/axis 下,并将其后缀改为 .jws 即可。

第一种方法非常的简单,但是第一种发布方法存在几个重要的限制:

1 、不能指定 package ;

2 、需要有 Service 的源码;

因此常常不能满足我们的需要。

方法二:

第二种发布 Axis Service 的方法需通过配置来完成。

以下面的 HelloService 为例(与前面的 EchoService 基本没有什么区别,但其中使用了 package ):

package demo.soap;

 

public class HelloService {

      public String sayHello() {

            return "Hello World!" ;

      }

}

要发布上面的 Service ,需编写如下的配置文件:

< deployment xmlns = "http://xml.apache.org/axis/wsdd/ " xmlns:java = "http://xml.apache.org/axis/wsdd/providers/java ">

      < service name = "HelloService " provider = "java:RPC ">

            < parameter name = "className " value = "demo.soap.HelloService "/>

            < parameter name = "allowedMethods " value = "* "/>

      </ service >

</ deployment >

将上述内容保存为 %TOMCAT_HOME%/webapps/axis/WEB-INF/deploy.txt ,并在其所在目录下执行:

java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.txt

生成 server-config.wsdd 文件,打开该文件看一下,可以看到 HelloService 的相关信息已被添加到该文件,此外,还包括一些默认的配置信息以及 AdminService 、 Version 两个基础服务。

以下是 HelloService 的 Client 程序的相关代码:

package demo.soap;

 

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

 

public class HelloClient {

      public static void main(String [] args) throws Exception {

            String endpoint = "http://localhost:" + "8080" + "/axis/services/HelloService" ; // Attention: A little difference

 

            Service service = new Service();

            Call call = (Call)service.createCall();

            call.setTargetEndpointAddress(new java.net.URL(endpoint));

            call.setOperationName("sayHello" );

 

            String res = (String)call.invoke(new Object[] {});

 

            System.out.println(res);

      }

}

与前面的 EchoClient 的区别仅在于访问点稍有不同。

发布后如何删除对应的 Service 呢?要删除上面发布的 HelloService 服务,只需在 %TOMCAT_HOME%/webapps/axis/WEB-INF 目录下添加如下的 undeploy.txt 描述文件,其内容如下:

< undeployment xmlns = "http://xml.apache.org/axis/wsdd/ ">

      < service name = "HelloService "/>

</ undeployment >

然后执行:

java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.txt

以更新 server-config.wsdd 文件。

刷新一下页面:

http://localhost:8080/axis/servlet/AxisServlet

将看到前面已发布的对应的 Service 已被删除。

如果以后还要发布新的 Service ,你可以选择直接更新上面产生的 server-config.wsdd 文件,或者重复上面的步骤。

Note :除了发布自己的 Web Service 到 Axis ,你也可以将 Axis 集成到自己的 Web Application ,具体方法见 http://ws.apache.org/axis/java/install.pdf

五、 Google Web API
在继续下面的讨论之前,先娱乐一下,谈谈 Google Web API 。

为了便于程序员体验 Google 的搜索服务,或者将 Google 的搜索服务集成到自己的应用中, Google 于 2002 发布了 Google Web API ,可以让世界各地的 Java 、 .NET 、 Perl 、 Python 等程序员,免费地通过 Google 提供的 SOAP 开发接口以 Web Services 的方式,对 Google 下达查找指令,并且可以将结果使用于自己的程序或网页中。(不过使用上也有限制,它一天只允许未付费的程序员查找 1000 次。要使用前,必须先向 Google 注册帐号,取得一个 32 位长度的 license key ,每次呼叫查询时,必须带入这个 license key 。)

通过使用 Google Web API ,能够从 Google 那儿以结构化数据的形式( xml 格式)取得检索结果,所带来的最大好处就是你可以根据你自己的意愿和设计,把这些检索结果显示你自己的页面上。这个页面上可显示自己的 logo 或一些其它的内容,就象自己编写的页面一样,而不必非要把 Google 的 logo 显示在页面的顶部和底部。一句话,你可以控制 Google 的检索了,让 Google 为你的网站服务。(参考 5 )

以下是使用 Proxy 连接 Google SOAP 服务的例子:

java -cp googleapi.jar -Dhttp.proxyHost=xxx(proxy_host_ip/name) -Dhttp.proxyPort=xxx(proxy_port) com.google.soap.search.GoogleAPIDemo xxx(license_key) search billdavid

其输出大致如下:

Parameters:

Client key = o917zHlQFHIr2+qMGPUYflB+j89LLbcX

Directive  = search

Args       = billdavid

Google Search Results:

======================

{

TM = 0.694308

Q  = "billdavid"

CT = ""

TT = ""

CATs =

  {

  <EMPTY>

  }

Start Index = 1

End   Index = 10

Estimated Total Results Number = 1280

Document Filtering = true

Estimate Correct = false

Rs =

  {

 

  [

  URL  = "http://forums.vandyke.com/member.php?u=2050"

  Title = "VanDyke Software Forums - View Profile: <b>billdavid</b>"

  Snippet = "This is a discussion forum for users and evaluators of VanDyke Soft

ware products."

  Directory Category = {SE="", FVN=""}

  Directory Title = ""

  Summary = ""

  Cached Size = "16k"

  Related information present = true

  Host Name = ""

  ],

 

  [

  URL  = "http://forums.vandyke.com/showthread.php?t=1393"

  Title = "Will you add two new features to SecureCRT? - VanDyke Software Forums

"

  Snippet = "<b>billdavid billdavid</b> is offline. Registered User. Join Date:

Apr 2006 <b>...</b><br>  Originally Posted by <b>billdavid</b>. I think the foll

owing features are very useful: <b>...</b>"

  Directory Category = {SE="", FVN=""}

  Directory Title = ""

  Summary = ""

  Cached Size = "30k"

  Related information present = true

  Host Name = "forums.vandyke.com"

  ],

 

  [

  URL  = "http://www.beliefnet.com/user/profile_view.asp?userID=424089&popUp=1"

    Title = "Beliefnet Member Profile"

  Snippet = "Member Name: <b>billdavid</b>. Member since: 2/24/2003. Location: s

ebring, florida , us.<br>  Sex: Male. Age: 53. Occupation: Other. Organizations

and Affiliations: <b>...</b>"

  Directory Category = {SE="", FVN=""}

  Directory Title = ""

  Summary = ""

  Cached Size = "8k"

  Related information present = true

  Host Name = ""

  ],

(下略 ... )

以下是通过 ethereal 抓到的本机发出的 Google Search 数据包:

POST http://api.google.com/search/beta2 HTTP/1.0

Host: api.google.com

Content-Type: text/xml; charset=utf-8

Content-Length: 864

SOAPAction: "urn:GoogleSearchAction"

<? xml version = '1.0 ' encoding = 'UTF-8 '?>

< SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/ " xmlns:xsi = "http://www.w3.org/1999/XMLSchema-instance " xmlns:xsd = "http://www.w3.org/1999/XMLSchema ">

      < SOAP-ENV:Body >

            < ns1:doGoogleSearch xmlns:ns1 = "urn:GoogleSearch " SOAP-ENV:encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/ ">

                  < key xsi:type = "xsd:string "> xxx…xxx </ key >

                  < q xsi:type = "xsd:string "> billdavid</ q >

                  < start xsi:type = "xsd:int "> 0</ start >

                  < maxResults xsi:type = "xsd:int "> 10</ maxResults >

                  < filter xsi:type = "xsd:boolean "> true</ filter >

                  < restrict xsi:type = "xsd:string "></ restrict >

                  < safeSearch xsi:type = "xsd:boolean "> false</ safeSearch >

                  < lr xsi:type = "xsd:string "></ lr >

                  < ie xsi:type = "xsd:string "> UTF-8</ ie >

                  < oe xsi:type = "xsd:string "> UTF-8</ oe >

            </ ns1:doGoogleSearch >

      </ SOAP-ENV:Body >

</ SOAP-ENV:Envelope >

com.google.soap.search.GoogleAPIDemo.java 的源代码可以在 googleapi 的压缩包中找到,其中演示了大部分基本 Google Web API 的用法,关于 Google Web API 的更多信息见参考 4 。

六、 Axis2
随着 Web Services 技术的演进, Apache Web Services 中间件也在不断发展,从第一代的 Apache SOAP ,第二代的 Axis ,逐渐发展成为第三代 Web Service 中间件 Axis2 。与 Axis 相比, Axis2 采用了性能更为优越的 XML 解析技术,采用面向组件的架构设计,从而具有更好的灵活性和可扩展性,并可支持异步通信需求等。参考 6 、 7 给出了利用 Axis2 进行 Web Service 开发的详细步骤。

参考:
1.   劳虎, SOAP 与 Web services , http://2tigers.net/html/tiger_column/article3.html

2.   孟岩, Web Service : WebOS 中的 Function Call , http://www.mengyan.org/blog/archives/2006/06/09/125.html

3.   Axis 学习笔记, http://www.javaresearch.org/article/showarticle.jsp?column=5&thread=29576

4.   Google, Google SOAP Search API, http://www.google.com/apis/

5.   Patrick Chanezon, Patch For Google APIs to handle proxy settings, http://www.chanezon.com/pat/google_proxy_patch.html

6.   Hilton ,关于 Google API 的学习, http://hedong.3322.org/archives/000274.html

7.   Gopalakrishnan U 、 Shreevidya Rao ,通过 Axis2 开发 Web 服务, http://www-128.ibm.com/developerworks/cn/webservices/ws-webaxis1/index.html

8.   joyeta , Apache Axis2(java web service) 備忘記, http://blog.matrix.org.cn/page/joeyta?entry=apache_axis2_java_web_service

 

http://www.javaeye.com/wiki/topic/408971

 

JavaSE6.0 Web Service学习笔记

http://www.javaeye.com/topic/166314?page=1

 

web service框架---axis学习笔记

http://www.javaeye.com/topic/250240

 

使用Axis创建Web Service服务

http://www.javaeye.com/topic/417433

 

在axis中通过wsdd文件发布和卸载webservice

http://www.javaeye.com/topic/56552

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/findhappy7/archive/2009/08/18/4457891.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值