用JAVA开发WEB Service(学习总结)

时间:2024.3.19

JAVA开发WEB Service

学习前的准备

开发环境 JBOSS4.05+axis1.4+JDK1.5

axis1.4下载地址: http://www.apache.org/dist/ws/axis/1_4/,选择axis-bin-1_4.zip  

所需要的JAR包:

部署axis

以我们CreateGWS405产品为例,在产品server\default\deploy目录下新建一个应用,比如叫myService.war。在里面新建文件夹“WEB-INF”,将axis1.4以下目录中的web.xml文件拷贝到“WEB-INF”下。“axis-bin-1_4\axis-1_4\webapps\axis\WEB-INF“。然后将jar包拷贝到产品server\default\lib下。至此部署完毕。

开发webService服务端

  用编辑器编写一个简单的服务类,代码如下:

import java.util.*;

import java.text.*;

public class SayHello {

         public String say(String name){

                   System.out.println("call webservice say.....");

                   return " Hello " + name;

         }

}

将该类复制到myService.war中与“WEB-INF”同级目录,然后更改其名字为”SayHello.jws”。

启动CreateGWS405,在浏览器地址输入http://localhost:88/myService/SayHello.jws?wsdl打开页面后你会看到

  Click to see the WSDL   <--点击链接,如果你上面的步骤都正常,类也没有带

其他包的话,那么就生成了wsdl了。

至此webService服务端发布成功,接下来就是编写客户端了。

  开发webService客户端。(DLL方式)

  这里为了方便测试,我们就以CreateGWS405产品为客户端,在create.war下新建一个JSP页面,代码如下:

String urlname = "http://localhost:88/myService/SayHello.jws?wsdl";

Service s = new Service();

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

//要调用的方法名称

call.setOperationName("say");

call.setTargetEndpointAddress(urlname);

//方法传入一个String型参数,返回值也是String

String val = (String) call.invoke(new Object[] { "haha" });

      

System.out.println(val);

需要导入:import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

至此一个简单的客户端就编写好了。上面服务端的方法参数是String,返回值也是String,而实际业务中可能还需要以int,boolean等类型做参数,而且参数不止一个。返回值有时是int有时又是集合ArrayList那该怎么做呢,请看下面这个服务端代码

import java.util.*;

import java.text.*;

public class SayHello {

         public String say(String name){

                   System.out.println("call webservice say.....");

                   return " Hello " + name;

         }

         public ArrayList getList(String str){

             ArrayList strs = new ArrayList();

             System.out.println("call webservice getList.....");

             strs.add("A");

             strs.add("B");

             strs.add("C");

             strs.add(str);

             return strs;

         }

         public String [] getStrs(String str,int a){

             System.out.println("call webservice getStrs.....");

             String[] abc = new String[a];

             abc[0]=str;

             return abc;

         }

         public int getInt(String arg){

             System.out.println("call webservice getInt.....");

             return arg.length();

         }

}

这个服务端有4个方法,分别返回不同类型的值。客户端就要改成

String urlname = "http://localhost:8080/aixs_proxy_demo/SayHello.jws?wsdl";

       Service s = new Service();

       try {

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

           //要调用的方法名称

           call.setOperationName("say");

           call.setTargetEndpointAddress(urlname);

           //方法传入一个String型参数,返回值也是String

           String val = (String) call.invoke(new Object[] { "haha" });

           System.out.println(val);

          

           Call call4 = (Call) s.createCall();

           //要调用的方法名称

           call4.setTargetEndpointAddress(urlname);

           call4.setOperationName("getList");

           String st1 = "abc";

           //传入参数类型为String

           call4.addParameter(new QName("st1"), XMLType.XSD_STRING, ParameterMode.IN);

           //返回一个ArrayList

           call4.setReturnType(new QName("ArrayList"), ArrayList.class);

           ArrayList list = (ArrayList) call4.invoke(new Object[] { st1 });

           System.out.println("+++++" + list.size());

          

           Call call2 = (Call) s.createCall();

           String st2 = "abc";

           int count = 303;

           call2.setOperationName("getStrs");

           call2.setTargetEndpointAddress(urlname);

           //传入参数类型为String和int

           call2.addParameter(new QName("st2"), XMLType.XSD_STRING, ParameterMode.IN);

           call2.addParameter(new QName("count"), XMLType.XSD_INT, ParameterMode.IN);

           //返回一个String[]

           call2.setReturnType(new QName("String[]"), String[].class);

           String[] strs = (String[]) call2.invoke(new Object[] { st2,

                  Integer.valueOf(count) });

           System.out.println("-----" + strs.length);

          

           Call call3 = (Call) s.createCall();

           String st3 = "abcdefg";

           call3.setOperationName("getInt");

           call3.setTargetEndpointAddress(urlname);

           //传入参数类型为String

           call3.addParameter(new QName("st3"), XMLType.XSD_STRING, ParameterMode.IN);

           //返回一个int

           call3.setReturnType(new QName("Integer"), Integer.class);

           Integer getint = (Integer) call3.invoke(new Object[] {st3});

           System.out.println(getint);

       } catch (Exception e) {

           e.printStackTrace();

       }

需要导入: import java.util.ArrayList;

import javax.xml.namespace.QName;

import javax.xml.rpc.ParameterMode;

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

import org.apache.axis.encoding.XMLType;

学习中需要注意的地方:

1、  在客户端调用其他程序的类时需要先把外部类引入到myService.war\WEB-INF\下新建classes文件夹,包路径与原类相同,如果是jar文件,则需要复制到myService.war\WEB-INF\lib下。这样.jws格式文件才能正确编译为.class文件。

2、  调用其他服务器上的webservice时需要注意一定要将包导入完全,如果包缺少会影响使用。

开发webService客户端。Dynamic Proxy方式 (代理方式)

  还是以上面那个服务端为例,用代理的方式来调用webService我们只需要对客户端的代码进行修改就可以了,代码如下

String wsdlUrl = "http://localhost:8080/aixs_proxy_demo/SayHello.jws?wsdl";

       String nameSpaceUri = "http://localhost:8080/aixs_proxy_demo/SayHello.jws";

       // 服务名

       String serviceName = "SayHelloService";

       // 服务

       String portName = "SayHello";

       // 创建代理对像

       ServiceFactory serviceFactory;

       try {

           serviceFactory = ServiceFactory.newInstance();

//创建远程服务

           Service service = (Service) serviceFactory.createService(new URL(wsdlUrl), new QName(

                  nameSpaceUri, serviceName));

//向上转型为接口

           MyServiceInterface proxy = (MyServiceInterface) service.getPort(

                  new QName(nameSpaceUri, portName), MyServiceInterface.class);

//调用相应方法

           System.out.println("proxy.say ----"

                  + proxy.say("li lei"));

           System.out.println("proxy.getList ----"

                  + proxy.getList("AAAA").size());

           System.out.println("proxy.getStrs ----"

                  + proxy.getStrs("BBBB",10).length);

           System.out.println("proxy.getInt ----"

                  + proxy.getInt("ABCDEFG"));

       } catch (MalformedURLException e) {

           e.printStackTrace();

       } catch (ServiceException e) {

           e.printStackTrace();

       }

需要导入:

import java.net.MalformedURLException;

import java.net.URL;

import javax.xml.namespace.QName;

import javax.xml.rpc.ServiceException;

import javax.xml.rpc.ServiceFactory;

import org.apache.axis.client.Service;

MyServiceInterface接口类的编写

import java.rmi.Remote;

import java.util.*;

publicinterface MyServiceInterface extends Remote{

    public String say(String name);

   

    public ArrayList getList(String str);

   

    public String [] getStrs(String str,int a);

   

    publicint getInt(String arg);

}

需要注意的是:

1、  接口必须继承Remote类,才能做代理

2、  接口里面的方法必须和jws文件中的方法保持一致。


第二篇:WebService学习,开发总结--唐木之无线观察


WebService学习,开发总结--唐木之无线观察

发布时间:2009-7-16 阅读:123

原文地址:

/blog/user1/261/archives/2006/2095.html

基本概念:

1, 什么是 Web 服务? Web 是使应用程序可以以与平台和编程语言无关的方式进行相互通信的一项技术。Web 服务是一个软件接口,它描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作。它使用基于 XML 语言的协议来描述要执行的操作或者要与另一个 Web 服务交换的数据。一组以这种方式交互的 Web 服务在面向服务的体系结构(Service-Oriented Architecture,SOA)中定义了特殊的 Web 服务应用程序。

2, 什么是SOAP? SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的轻量级协议,是一个基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一种语言相互通信。

SOAP包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例;SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。

应用中比较关注的是envelop,由一个或多个Header和一个Body组成。

SOAP在可互操作的基础 Web 服务协议栈中的位置:

3, 什么是Axis?

Axis本质上就是一个SOAP引擎(Apache Axis is an implementation of the SOAP),提供创建服务器端、客户端和网关SOAP操作的基本框架。但Axis并不完全是一个SOAP引擎,它还包括:

是一个独立的SOAP服务器。

是一个嵌入Servlet引擎(例如Tomcat)的服务器。

支持WSDL。

提供转化WSDL为Java类的工具。

提供例子程序。

提供TCP/IP数据包监视工具。

4, Axis相比Soap v2的优点: Axis是第三代Apache SOAP的实现,从20xx年起,SOAP v2开发小组开始讨论如何让Axis更加灵活、可配置,以及能够处理SOAP和来自W3C的各种XML标准。通过不断地讨论和代码编写,Axis目前相比SOAP V2取得了如下成果:

速度提高。 Axis通过基于事件的SAX对XML文档进行处理,从而在速度和效率上比Apache SOAP有所提高。

灵活性提高。

稳定性提高。

提供面向组件的部署。

提供一个简洁的传输抽象框架。其核心引擎完全于传输方式独立。从而使基于何种协议传输的选择更加灵活。

支持WSDL。包括WSDL和客户端代码生成等。

5, 什么是WSDL?

WSDL(Web Service Description Language)Web服务器描述语言是用XML文档来描述Web服务的标准,是Web服务的接口定义语言,由Ariba、Intel、IBM、MS等共同提出,通过WSDL,可描述Web服务的三个基本属性:

·服务做些什么——服务所提供的操作(方法)

·如何访问服务——和服务交互的数据格式以及必要协议

·服务位于何处——协议相关的地址,如URL

WSDL文档以端口集合的形式来描述Web服务,WSDL 服务描述包含对一组操作和消息的一个抽象定义,绑定到这些操作和消息的一个具体协议,和这个绑定的一个网络端点规范。 WSDL在Web 服务概念性协议栈中的位置:

6, 什么是WSDD? WSDD就是WEB服务分布描述(Web Service Deployment Descriptor), 它定义了WEB服务的接口,如服务名、提供的方法、方法的参数等信息。

7, 什么是UDDI? UDDI就是统一描述、发现和集成(Universal Description, Discovery, and Integration)。UDDI用于集中存放和查找WSDL描述文件,起着目录服务器的作用。

Web 服务中的角色、操作和构件: ? 服务提供者。从企业的角度看,这是服务的所有者。从体系结构的角度看,这是托

管访问服务的平台。

? 服务请求者。从企业的角度看,这是要求满足特定功能的企业。从体系结构的角度

看,这是寻找并调用服务,或启动与服务的交互的应用程序。服务请求者角色可以由浏览器来担当,由人或无用户界面的程序(例如,另外一个 Web 服务)来控制它。 ? 服务注册中心。这是可搜索的服务描述注册中心,服务提供者在此发布他们的服务

描述。在静态绑定开发或动态绑定执行期间,服务请求者查找服务并获得服务的绑定信息(在服务描述中)。对于静态绑定的服务请求者,服务注册中心是体系结构中的可选角色,因为服务提供者可以把描述直接发送给服务请求者。同样,服务请求者可以从服务注册中心以外的其它来源得到服务描述,例如本地文件、FTP 站点、Web 站点、广告和服务发现(Advertisement and Discovery of Services,ADS)或发现 Web 服务(Discovery of Web Services,DISCO)。

8, AXIS的几种服务类型:

AXIS有四种service styles,分别是:RPC, Document, Wrapped, 和Message。最常用的就是RPC和Message。

RPC:在AXIS中是一个默认选项。当你部署的时候使用下列两种方式: 或则 ,它遵循SOAP RPC和编码规则。每个RPC都包括一个表示名称的外部接点和一些表示参数的内部接点。AXIS会根据规则将一个XML(WSDL文件)文件转化成一个JAVA对象,并对对想赋上在文件中描述的值。也可以根据规则将一个JAVA对象转化成XML文件。

Document

适合于老的XML schema。

Wrapped

和DOCUMENT一样,适合于老的XML schema。

在大多书情况下,你不许要担心是DOCUMENT服务还是WRAPPED服务。

Message

以这种方式部署的话,会使AXIS失去意义,它使你的代码真正的用XML形式,而不需要转化成JAVA对象。以这种方式部署的有以下四种服务方法:

public Element [] method(Element [] bodies);

public SOAPBodyElement [] method (SOAPBodyElement [] bodies);

public Document method(Document body);

public void method(SOAPEnvelope req, SOAPEnvelope resp); 几种服务类型的主要区别:

基于RPC(远程过程调用)方式,这也是Web服务最常用的方式。面向消息/文档的的类型跟RPC不同的是它提供了一个更底层的抽象,要求更多的编程工作。客户端可以传入任何的XML文档,得到的响应不一定是SOAPEnvelope,可以返回任何它所需要的东西,甚至不返回。虽然这对开发者来说非常的灵活,但是这种通讯类型在实际的应用中并不常见。面向消息/文档的Web服务主要适合于下面几种情况,比如批量处理,基于表单的数据导入,有需要返回非XML数据时,Web服务器实现中要求直接访问传输层等等

二, 开发,部署Web服务:

首先下载并安装tomcat4.x.及以上版本

然后到Axis主页下载,现在最新版本是1.3 final,我们使用的是1.2.1 final版,将解压的axis中的webapps目录下的axis拷贝到tomcat安装路径下的webapp下,将解压的axis下lib下的jar文件拷贝到tomcat安装目录下commonlib下,并把他们加入到你的系统路径中。

然后启动tomcat,

打开IE,输入:http://localhost:8080/axis,如果出现axis主页,说明安装axis成功。 部署web服务 在axis下部署web服务有以下两种方式:

1. 即时部署(Instance Deployment)利用JWS文件 只需要将.java文件拷贝到axis目录下,并将文件后缀改为.jws即可。

访问部署后的wsdl文件只需键入: http://localhost:8080/axis/filename.jws?wsdl 以下是WSDL的一个例子:

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

<wsdl:definitions targetNamespace="http://service." xmlns:apachesoap="/xml-soap"

xmlns:impl="http://service."

xmlns:intf="http://service."

xmlns:tns1="http://vo.service."

xmlns:wsdl="/wsdl/"

xmlns:wsdlsoap="/wsdl/soap/"

xmlns:xsd="/2001/XMLSchema"> <wsdl:types> //描述消息中复杂数据类型的使用

<schema targetNamespace="http://vo.service."

xmlns="/2001/XMLSchema">

<import namespace="http://service."/>

<import namespace="/soap/encoding/"/>

<complexType name="UserGameGrade">//定义复杂类型

<sequence>

<element name="MClassID" nillable="true" type="xsd:string"/>

<element name="gameID" nillable="true" type="xsd:string"/>

<element name="gradeType" type="xsd:int"/>

...... </sequence>

</complexType>

</schema>

......

</wsdl:types>

<wsdl:message name="getGameGradeRankResponse"> //定义操作的输出参数 <wsdl:part name="getGameGradeRankReturn" type="tns1:GameGradeRank"/> </wsdl:message>

<wsdl:message name="getGameGradeRankRequest"> //定义操作的输入参数 <wsdl:part name="in0" type="xsd:string"/>

<wsdl:part name="in1" type="xsd:int"/>

<wsdl:part name="in2" type="xsd:int"/>

</wsdl:message>

......

<wsdl:portType name="GameGradeService"> // WSDL: portType 元素中定义了 Web 服务的操作。

<wsdl:operation name="getGameGradeRank" parameterOrder="in0 in1 in2"> //操作定义了输入和输出数据流中可以出现的 XML 消息

<wsdl:input message="impl:getGameGradeRankRequest"

name="getGameGradeRankRequest"/>

<wsdl:output message="impl:getGameGradeRankResponse"

name="getGameGradeRankResponse"/>

</wsdl:operation>

<wsdl:operation name="getUserGameGradeRank" parameterOrder="in0 in1 in2 in3 in4"> <wsdl:input message="impl:getUserGameGradeRankRequest"

name="getUserGameGradeRankRequest"/>

<wsdl:output message="impl:getUserGameGradeRankResponse"

name="getUserGameGradeRankResponse"/>

</wsdl:operation>

......

</wsdl:portType>

<wsdl:binding name="GameGradeServiceSoapBinding"

type="impl:GameGradeService">//描述特定服务接口(WSDL: portType)的协议、数据格式、安全性和其它属性

<wsdlsoap:binding style="rpc" transport="/soap/http"/> <wsdl:operation name="getGameGradeRank">

<wsdlsoap:operation soapAction=""/>

<wsdl:input name="getGameGradeRankRequest">

<wsdlsoap:body namespace="http://service." use="literal"/> </wsdl:input>

<wsdl:output name="getGameGradeRankResponse">

<wsdlsoap:body namespace="http://service." use="literal"/> </wsdl:output>

</wsdl:operation> </wsdl:binding>

<wsdl:service name="GameGradeServiceService">//定义服务:名字,访问点,位置

<wsdl:port binding="impl:GameGradeServiceSoapBinding"

name="GameGradeService">

<wsdlsoap:address

location="http://localhost:8080/gamebase/services/GameGradeService"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>2.定制部署(Custom Deployment)利用部署描述符wsdd

以下是部署描述符的一个例子: <deployment xmlns="/axis/wsdd/"

xmlns:java="/axis/wsdd/providers/java">

<service name="GameGradeService" type="" provider="java:RPC"

style="rpc" use="encoded"> //服务名字,服务类型及服务提供者 <parameter name="scope" value="Request"/>

<parameter name="className" value="/blog/com.gamebase.kernel.service.ServiceImpl"/> //实现该服务

的具体类

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

<namespace>http://service.</namespace>

<typeMapping xmlns:ns1="http://vo.service." //类型映射

encodingStyle="/soap/encoding/"

qname="ns1:GameGradeRank"//Qualified Name(特定名字)

languageSpecificType="java:com.gamebase.kernel.service.vo.GameGradeRank"

serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"//指定序列化工厂

deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" //反序列化工厂

name="GameGradeRank"/> ………

</service>

</deployment>

访问部署后的wsdl文件只需键入

http://localhost:8080/axis/services/ GameGradeService

三, 在IDE下开发Web服务: 1,在Jubilder下开发WebService:

使用Jbuilder集成开发环境,能够根据服务接口类生成web服务描述文件,web服务部署描述文件及客户端代码,这样能够节省我们大部分时间(开发,配置),且减少出错机率。 Jbuilder在以前的版本,如jbuilder8(可能更低版本)就支持Axis,我用的是Jbuilder2006,不过大体步骤都是相同。 在开始前,我们有个服务接口GameGradeService类,服务接口实现类ServiceImpl类及相关附属类。我们要实现该服务接口。

2.1,打开Jbuilder,新建一个工程,如testWebService

2.2,新建一个名为webService的WebService Server (file>new:WebServices:Axis WebServices Server Configuration)

2.3, 在出现的Web Services Designers可视化界面,点击“create Service”,选择“java Service”

2.4,配置新创建的java Service,点击JavaService1,配置Service Name为GameGradeService,

服务接口为我们有的那个服务接口GameGradeService,实现类为我们实现改接口的类ServiceImpl。

2.5,然后编译该工程,能够生成web服务部署文件,web服务描述文件,如果你选择了生成客

户端代码的话,它也能生成相应的客户端代码。

2.6,启动该服务,访问:

http://localhost:8080/webService/services/GameGradeService?wsdl,如果出现该服务的描述文档,说明发布成功。

2.7,执行自动生成的客户端代码进行测试,发现测试成功。

2.8,你可以用webService的webServices Client来根据wsdl只生成客户端代码。 a,新建一个名为webServiceClient的WebService Client(file>new:WebServices:Axis WebServices Client Configuration)

b,在出现的Web Services Designers可视化界面,点击“create Service”,选择“import from url” c,配置新创建的java Service,点击JavaService1,配置Service Name为

GameGradeService,Input WSDL file 为给定的wsdl。

d,然后编译该工程

2,在eclipse下开发WebService:

Eclipse3.1及相关插件已经能够很好的支持webService开发。

右键点击wsdl文件,选择webServices,有以下功能:发布wsdl文件,生成客户

端代码等。

右键点击服务接口文件,选择webServices,有以下功能:生成web Service等。

同时eclipse提供了友好的界面操作,如测试的时候,提供界面让你输入参数,而不必该改程序。

四, 开发过程中的问题:

在使用AXIS开发WEB服务的时候,会遇到很多问题。比如:XML解析器出现的异常、客户端程序找不到可用的Web服务、序列化/反序列化等。

XML解析器出现的异常主要是由于类型映射的问题导致的,用到那个Bean就把那个bean映射进去就可以避免该问题。

客户端程序找不到可用的Web服务主要是由于客户端对服务提供者的url及服务名字输入有错,这一般是由于手写客户端代码造成的。

序列化/反序列化问题,没有对传输中的某个Bean类型映射相应的序列化/反序列化工厂,或者是复杂类型中,没有实现自定义的序列化/反序列化工厂。

以上是开发过程中主要遇到的几类问题,在以后的开发过程中,一定还会需要遇到更多的问题。

五, 其他相关知识: 1,java类与wsdl相互生成工具:

Axis提供了”WSDL2Java”工具,可以利用wsdl描述来产生服务的Java代理和框架(proxy and skeletons)。

Axis提供了”Java2WSDL”工具,可以由java类生成wsdl文件。

2,序列化与反序列化:

序列化/反序列化器在英文中的对应翻译是Serializer/Deserializer,一个序列化器的功能是遵循一定的映射规则和编码风格,将一种类型的JAVA对象通过某种特定的机制,转换成为XML描述的形式;反序列化器的功能是序列化器所做工作的逆操作,两者相辅相成,成对出现。Axis中的序列化/反序列化器采用设计范式中的工厂模式,每一个Serializer唯一对应一个SerializerFactory;每一个Deserializer唯一对应一个

DeserializerFactory。

Axis已经为开发者提供了丰富的序列化/反序列化器,对于java的基本数据类型,绝大部分常用的容器类(比如数组类型,Vector类型等)都提供了实现,特别是提供了对W3C的DOM对象(比如Document, Element等)和符合Bean规范的JAVA对象提供了功能完善的序列化/反序列化器,但对于一些特殊类型的对象,需要通过Web服务进行传递,我们不得不开发自己的序列化/反序列化器。

3,Axis与Spring的结合:

Axis与spring结合,需要提供一些额外工作,即将实现web服务接口的Bean与web服务部署中

服务类如何关联。 如下:

<service name="GameService" type="" provider="Handler" style="rpc">

<parameter name="handlerClass"

value="/blog/com.workingmouse.webservice.axis.SpringBeanRPCProvider"/>

<parameter name="springBean" value="gameInfoService"/>

<parameter name="springBeanClass"

value="/blog/com.gamebase.kernel.service.GameService"/>

<parameter name="scope" value="Request"/>

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

</service>

参数handlerClass的值是处理Bean与wsdd文件中服务类的关联。

参数springBean的值表示实现接口GameService注册的Bean的名字。

参数springBeanClass的值表示接口GameService的类。

发布时间:2009-7-16 阅读:123

原文地址:

/blog/user1/261/archives/2006/2095.html

基本概念:

1, 什么是 Web 服务?

Web 是使应用程序可以以与平台和编程语言无关的方式进行相互通信的一项技术。Web 服务是一个软件接口,它描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作。它使用基于 XML 语言的协议来描述要执行的操作或者要与另一个 Web 服务交换的数据。一组以这种方式交互的 Web 服务在面向服务的体系结构(Service-Oriented Architecture,SOA)中定义了特殊的 Web 服务应用程序。

2, 什么是SOAP?

SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的轻量级协议,是一个基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一种语言相互通信。

SOAP包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例;SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。

应用中比较关注的是envelop,由一个或多个Header和一个Body组成。 SOAP在可互操作的基础 Web 服务协议栈中的位置:

3, 什么是Axis?

Axis本质上就是一个SOAP引擎(Apache Axis is an implementation of the SOAP),提供创建服务器端、客户端和网关SOAP操作的基本框架。但Axis并不完全是一个SOAP引擎,它还包括:

是一个独立的SOAP服务器。

是一个嵌入Servlet引擎(例如Tomcat)的服务器。

支持WSDL。

提供转化WSDL为Java类的工具。

提供例子程序。

提供TCP/IP数据包监视工具。

4, Axis相比Soap v2的优点:

Axis是第三代Apache SOAP的实现,从20xx年起,SOAP v2开发小组开始讨论如何让Axis更加灵活、可配置,以及能够处理SOAP和来自W3C的各种XML标准。通过不断地讨论和代码编写,Axis目前相比SOAP V2取得了如下成果:

速度提高。 Axis通过基于事件的SAX对XML文档进行处理,从而在速度和效率上比Apache SOAP有所提高。

灵活性提高。

稳定性提高。

提供面向组件的部署。

提供一个简洁的传输抽象框架。其核心引擎完全于传输方式独立。从而使基于何种协议传输的选择更加灵活。

支持WSDL。包括WSDL和客户端代码生成等。

5, 什么是WSDL? WSDL(Web Service Description Language)Web服务器描述语言是用XML文档来描述Web服务的标准,是Web服务的接口定义语言,由Ariba、Intel、IBM、MS等共同提出,通过WSDL,可描述Web服务的三个基本属性:

·服务做些什么——服务所提供的操作(方法)

·如何访问服务——和服务交互的数据格式以及必要协议

·服务位于何处——协议相关的地址,如URL

WSDL文档以端口集合的形式来描述Web服务,WSDL 服务描述包含对一组操作和消息的一个抽象定义,绑定到这些操作和消息的一个具体协议,和这个绑定的一个网络端点规范。 WSDL在Web 服务概念性协议栈中的位置:

6, 什么是WSDD?

WSDD就是WEB服务分布描述(Web Service Deployment Descriptor), 它定义了WEB服务的接口,如服务名、提供的方法、方法的参数等信息。

7, 什么是UDDI?

UDDI就是统一描述、发现和集成(Universal Description, Discovery, and Integration)。UDDI用于集中存放和查找WSDL描述文件,起着目录服务器的作用。

Web 服务中的角色、操作和构件:

? 服务提供者。从企业的角度看,这是服务的所有者。从体系结构的角度看,这是托

管访问服务的平台。

服务请求者。从企业的角度看,这是要求满足特定功能的企业。从体系结构的角度看,这是寻找并调用服务,或启动与服务的交互的应用程序。服务请求者角色可以由浏览器来担当,由人或无用户界面的程序(例如,另外一个 Web 服务)来控制它。 ? ? 服务注册中心。这是可搜索的服务描述注册中心,服务提供者在此发布他们的服务

描述。在静态绑定开发或动态绑定执行期间,服务请求者查找服务并获得服务的绑定信息(在服务描述中)。对于静态绑定的服务请求者,服务注册中心是体系结构中的可选角色,因为服务提供者可以把描述直接发送给服务请求者。同样,服务请求者可以从服务注册中心以外的其它来源得到服务描述,例如本地文件、FTP 站点、Web 站点、广告和服务发现(Advertisement and Discovery of Services,ADS)或发现 Web 服务(Discovery of Web Services,DISCO)。

8, AXIS的几种服务类型: AXIS有四种service styles,分别是:RPC, Document, Wrapped, 和Message。最常用的就是RPC和Message。

RPC:在AXIS中是一个默认选项。当你部署的时候使用下列两种方式: 或则 ,它遵循SOAP RPC和编码规则。每个RPC都包括一个表示名称的外部接点和一些表示参数的内部接点。AXIS会根据规则将一个XML(WSDL文件)文件转化成一个JAVA对象,并对对想赋上在文件中描述的值。也可以根据规则将一个JAVA对象转化成XML文件。

Document

适合于老的XML schema。

Wrapped

和DOCUMENT一样,适合于老的XML schema。

在大多书情况下,你不许要担心是DOCUMENT服务还是WRAPPED服务。

Message

以这种方式部署的话,会使AXIS失去意义,它使你的代码真正的用XML形式,而不需要转化成JAVA对象。以这种方式部署的有以下四种服务方法:

public Element [] method(Element [] bodies);

public SOAPBodyElement [] method (SOAPBodyElement [] bodies);

public Document method(Document body);

public void method(SOAPEnvelope req, SOAPEnvelope resp);

几种服务类型的主要区别:

基于RPC(远程过程调用)方式,这也是Web服务最常用的方式。面向消息/文档的的类型跟RPC不同的是它提供了一个更底层的抽象,要求更多的编程工作。客户端可以传入任何的XML文档,得到的响应不一定是SOAPEnvelope,可以返回任何它所需要的东西,甚至不返回。虽然这对开发者来说非常的灵活,但是这种通讯类型在实际的应用中并不常见。面向消息/文档的Web服务主要适合于下面几种情况,比如批量处理,基于表单的数据导入,有需要返回非XML数据时,Web服务器实现中要求直接访问传输层等等

二, 开发,部署Web服务: 首先下载并安装tomcat4.x.及以上版本

然后到Axis主页下载,现在最新版本是1.3 final,我们使用的是1.2.1 final版,将解压的axis中的webapps目录下的axis拷贝到tomcat安装路径下的webapp下,将解压的axis下lib下的jar文件拷贝到tomcat安装目录下commonlib下,并把他们加入到你的系统路径中。

然后启动tomcat,

打开IE,输入:http://localhost:8080/axis,如果出现axis主页,说明安装axis成功。 部署web服务 在axis下部署web服务有以下两种方式:

1. 即时部署(Instance Deployment)利用JWS文件

只需要将.java文件拷贝到axis目录下,并将文件后缀改为.jws即可。

访问部署后的wsdl文件只需键入: http://localhost:8080/axis/filename.jws?wsdl 以下是WSDL的一个例子:

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

<wsdl:definitions targetNamespace="http://service." xmlns:apachesoap="/xml-soap"

xmlns:impl="http://service."

xmlns:intf="http://service."

xmlns:tns1="http://vo.service."

xmlns:wsdl="/wsdl/"

xmlns:wsdlsoap="/wsdl/soap/"

xmlns:xsd="/2001/XMLSchema"> <wsdl:types> //描述消息中复杂数据类型的使用

<schema targetNamespace="http://vo.service." xmlns="/2001/XMLSchema">

<import namespace="http://service."/>

<import namespace="/soap/encoding/"/> <complexType name="UserGameGrade">//定义复杂类型

<sequence>

<element name="MClassID" nillable="true" type="xsd:string"/>

<element name="gameID" nillable="true" type="xsd:string"/>

<element name="gradeType" type="xsd:int"/>

......

</sequence>

</complexType>

</schema>

......

</wsdl:types>

<wsdl:message name="getGameGradeRankResponse"> //定义操作的输出参数

<wsdl:part name="getGameGradeRankReturn" type="tns1:GameGradeRank"/> </wsdl:message> <wsdl:message name="getGameGradeRankRequest"> //定义操作的输入参数 <wsdl:part name="in0" type="xsd:string"/>

<wsdl:part name="in1" type="xsd:int"/>

<wsdl:part name="in2" type="xsd:int"/>

</wsdl:message>

...... <wsdl:portType name="GameGradeService"> // WSDL: portType 元素中定义了 Web 服务的操作。

<wsdl:operation name="getGameGradeRank" parameterOrder="in0 in1 in2"> //操作定义了输入和输出数据流中可以出现的 XML 消息

<wsdl:input message="impl:getGameGradeRankRequest"

name="getGameGradeRankRequest"/>

<wsdl:output message="impl:getGameGradeRankResponse"

name="getGameGradeRankResponse"/>

</wsdl:operation>

<wsdl:operation name="getUserGameGradeRank" parameterOrder="in0 in1 in2 in3 in4"> <wsdl:input message="impl:getUserGameGradeRankRequest"

name="getUserGameGradeRankRequest"/>

<wsdl:output message="impl:getUserGameGradeRankResponse"

name="getUserGameGradeRankResponse"/>

</wsdl:operation>

......

</wsdl:portType> <wsdl:binding name="GameGradeServiceSoapBinding"

type="impl:GameGradeService">//描述特定服务接口(WSDL: portType)的协议、数据格式、安全性和其它属性

<wsdlsoap:binding style="rpc" transport="/soap/http"/> <wsdl:operation name="getGameGradeRank">

<wsdlsoap:operation soapAction=""/>

<wsdl:input name="getGameGradeRankRequest">

<wsdlsoap:body namespace="http://service." use="literal"/> </wsdl:input>

<wsdl:output name="getGameGradeRankResponse">

<wsdlsoap:body namespace="http://service." use="literal"/> </wsdl:output>

</wsdl:operation>

</wsdl:binding>

<wsdl:service name="GameGradeServiceService">//定义服务:名字,访问点,位置 <wsdl:port binding="impl:GameGradeServiceSoapBinding"

name="GameGradeService">

<wsdlsoap:address

location="http://localhost:8080/gamebase/services/GameGradeService"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>2.定制部署(Custom Deployment)利用部署描述符wsdd

以下是部署描述符的一个例子: <deployment xmlns="/axis/wsdd/"

xmlns:java="/axis/wsdd/providers/java"> <service name="GameGradeService" type="" provider="java:RPC"

style="rpc" use="encoded"> //服务名字,服务类型及服务提供者 <parameter name="scope" value="Request"/>

<parameter name="className" value="/blog/com.gamebase.kernel.service.ServiceImpl"/> //实现该服务

的具体类 <parameter name="allowedMethods" value="*"/>

<namespace>http://service.</namespace>

<typeMapping xmlns:ns1="http://vo.service." //类型映射

encodingStyle="/soap/encoding/"

qname="ns1:GameGradeRank"//Qualified Name(特定名字)

languageSpecificType="java:com.gamebase.kernel.service.vo.GameGradeRank"

serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"//指定序列化工厂

deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" //反序列化工厂

name="GameGradeRank"/>

………

</service>

</deployment>

访问部署后的wsdl文件只需键入

http://localhost:8080/axis/services/ GameGradeService

三, 在IDE下开发Web服务:

1,在Jubilder下开发WebService:

使用Jbuilder集成开发环境,能够根据服务接口类生成web服务描述文件,web服务部署描述文件及客户端代码,这样能够节省我们大部分时间(开发,配置),且减少出错机率。 Jbuilder在以前的版本,如jbuilder8(可能更低版本)就支持Axis,我用的是Jbuilder2006,不过大体步骤都是相同。

在开始前,我们有个服务接口GameGradeService类,服务接口实现类ServiceImpl类及相关附属类。我们要实现该服务接口。

2.1,打开Jbuilder,新建一个工程,如testWebService

2.2,新建一个名为webService的WebService Server (file>new:WebServices:Axis WebServices Server Configuration)

2.3, 在出现的Web Services Designers可视化界面,点击“create Service”,选择“java Service”

2.4,配置新创建的java Service,点击JavaService1,配置Service Name为GameGradeService,

服务接口为我们有的那个服务接口GameGradeService,实现类为我们实现改接口的类ServiceImpl。

2.5,然后编译该工程,能够生成web服务部署文件,web服务描述文件,如果你选择了生成客

户端代码的话,它也能生成相应的客户端代码。

2.6,启动该服务,访问:

http://localhost:8080/webService/services/GameGradeService?wsdl,如果出现该服务的描述文档,说明发布成功。

2.7,执行自动生成的客户端代码进行测试,发现测试成功。

2.8,你可以用webService的webServices Client来根据wsdl只生成客户端代码。

a,新建一个名为webServiceClient的WebService Client(file>new:WebServices:Axis WebServices Client Configuration)

b,在出现的Web Services Designers可视化界面,点击“create Service”,选择“import from url”

c,配置新创建的java Service,点击JavaService1,配置Service Name为

GameGradeService,Input WSDL file 为给定的wsdl。

d,然后编译该工程

2,在eclipse下开发WebService:

Eclipse3.1及相关插件已经能够很好的支持webService开发。 右键点击wsdl文件,选择webServices,有以下功能:发布wsdl文件,生成客户端代码等。

右键点击服务接口文件,选择webServices,有以下功能:生成web Service等。

同时eclipse提供了友好的界面操作,如测试的时候,提供界面让你输入参数,而不必该改程序。

四, 开发过程中的问题: 在使用AXIS开发WEB服务的时候,会遇到很多问题。比如:XML解析器出现的异常、客户端程序找不到可用的Web服务、序列化/反序列化等。

XML解析器出现的异常主要是由于类型映射的问题导致的,用到那个Bean就把那个bean映射进去就可以避免该问题。

客户端程序找不到可用的Web服务主要是由于客户端对服务提供者的url及服务名字输入有错,这一般是由于手写客户端代码造成的。

序列化/反序列化问题,没有对传输中的某个Bean类型映射相应的序列化/反序列化工厂,或者是复杂类型中,没有实现自定义的序列化/反序列化工厂。

以上是开发过程中主要遇到的几类问题,在以后的开发过程中,一定还会需要遇到更多的问题。

五, 其他相关知识:

1,java类与wsdl相互生成工具:

Axis提供了”WSDL2Java”工具,可以利用wsdl描述来产生服务的Java代理和框架(proxy and skeletons)。

Axis提供了”Java2WSDL”工具,可以由java类生成wsdl文件。

2,序列化与反序列化:

序列化/反序列化器在英文中的对应翻译是Serializer/Deserializer,一个序列化器的功能是遵循一定的映射规则和编码风格,将一种类型的JAVA对象通过某种特定的机制,转换成为XML描述的形式;反序列化器的功能是序列化器所做工作的逆操作,两者相辅相成,成对出现。Axis中的序列化/反序列化器采用设计范式中的工厂模式,每一个Serializer唯一对应一个SerializerFactory;每一个Deserializer唯一对应一个

DeserializerFactory。

Axis已经为开发者提供了丰富的序列化/反序列化器,对于java的基本数据类型,绝大部分常用的容器类(比如数组类型,Vector类型等)都提供了实现,特别是提供了对W3C的DOM对象(比如Document, Element等)和符合Bean规范的JAVA对象提供了功能完善的序列化/反序列化器,但对于一些特殊类型的对象,需要通过Web服务进行传递,我们不得不开发自己的序列化/反序列化器。

3,Axis与Spring的结合:

Axis与spring结合,需要提供一些额外工作,即将实现web服务接口的Bean与web服务部署中

服务类如何关联。 如下:

<service name="GameService" type="" provider="Handler" style="rpc">

<parameter name="handlerClass"

value="/blog/com.workingmouse.webservice.axis.SpringBeanRPCProvider"/>

<parameter name="springBean" value="gameInfoService"/>

<parameter name="springBeanClass"

value="/blog/com.gamebase.kernel.service.GameService"/>

<parameter name="scope" value="Request"/>

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

.......

</service>

参数handlerClass的值是处理Bean与wsdd文件中服务类的关联。

参数springBean的值表示实现接口GameService注册的Bean的名字。

参数springBeanClass的值表示接口GameService的类。

更多相关推荐:
英文读写literature review范文

TheinfluenceofminingexploitationonenvironmentandthesolutionofthedisposalofsolidwasteresidueBytheyearof20xxChinahas8...

contract review handbook

CROHandbookRevision20xx0427552RevolvingcreditChecktheFinancedatabaseforthepaymentpatternandhistoryIndivid...

summary学术英语literature review

ContentbasedtheriskofnuclearpowerandthedamageofitsradioactivityAnearthquakestruckJapanin20xxwhichseverelydamagednuc...

怎样写Literature Review

怎样写LiteratureReviewWriteaLiteratureReview1IntroductionNottobeconfusedwithabookreviewaliteraturereviewsurv...

Literature Review (翻译实践型论文文献综述示例)

功能对等理论谈EBWhites散文汉译中的风格对等TheStyleEquivalenceintheTranslationofEssaysbyEBWhiteBasedontheTheoryofFunctional...

literature review 的写作

literatureReview的写作首先需要将文献综述LiteratureReview与背景描述BackupgroundDescription区分开来我们在选择研究问题的时候需要了解该问题产生的背景和来龙去脉...

Literature review

IILiteratureReviewInthemiddleagestheGrammarTranslationMethodwasinitiallyusedtoteachmodernlanguagessuchasFrenchGerma...

Literature Review

LiteratureReviewWiththepopularityofthenovelTheromanceoftheThreeKingdomspeoplearemorefamiliarwiththecharactersoftheT...

A Sample of Literature Review(英文文献综述模板)

ASampleofLiteratureReviewOnAdvertisingEnglishAmongthesomanyscholarswhoexamineadvertisinglanguageGNLeechdeservesprim...

我的世界Minecraft教你如何用nat123和Teamviewer联机

想必Minecraft联机一直困扰着你Hamachi要翻墙注册水桶服操作麻烦花生壳不会用网上教程看不懂怎么办呢今天交给大家一个简单的联机技巧用Teamviewer和nat123联机Nat123是一个端口映射软件...

远程操作软件Teamviewer的使用方法

远程操作软件Teamviewer的使用方法Teamviewer使用方法最近由于朋友的电脑有些问题要远程协助他解决点问题使用了几款远程连接的软件如QQ远程协助Windows自带的远程桌面连接VNC等软件因为我们都...

teamviewer原理和阻止方法

teamviewerTeamViewer是一个非常简单好用的远程工具是一个在任何防火墙和NAT代理的后台用于远程控制桌面共享和文件传输的简单且快速的解决方案为了连接到另一台计算机只需要在两台计算机上同时运行Te...

critical review(2篇)