为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

用JAX RPC开发Web服务 Servlet 作

2017-10-16 14页 doc 42KB 15阅读

用户头像

is_219945

暂无简介

举报
用JAX RPC开发Web服务 Servlet 作用JAX RPC开发Web服务 Servlet 作 用JAX RPC开发Web服务 Servlet 作 级别:初级 陈亚强(),高级软件工程师,北京华园天一科技有限公司 2003年7月01日 本文是J2EE Web服务开发系列文章的第三篇,本文将首先介绍JAX-RPC基本构架,然后重点讨论把Servlet作为JAX-RPC Web服务端点时的开发步骤,以及各个步骤中要使用的工具和编程技巧。在内容的组织上,仍然结合本系列文章第一篇(《用JAXM开发Web服务》)中的案例,一步步引导读者使用JAX-RPC开发Web服务...
用JAX RPC开发Web服务  Servlet 作
用JAX RPC开发Web服务 Servlet 作 用JAX RPC开发Web服务 Servlet 作 级别:初级 陈亚强(),高级软件工程师,北京华园天一科技有限公司 2003年7月01日 本文是J2EE Web服务开发系列文章的第三篇,本文将首先介绍JAX-RPC基本构架,然后重点讨论把Servlet作为JAX-RPC Web服务端点时的开发步骤,以及各个步骤中要使用的工具和编程技巧。在内容的组织上,仍然结合本系列文章第一篇(《用JAXM开发Web服务》)中的案例,一步步引导读者使用JAX-RPC开发Web服务。阅读本文前您需要以下的知识和工具: JavaTM Web Services Developer Pack 1.1,并且会使用初步使用;使用EJB容器来开发、部署EJB,并且了解怎么在客户端访问EJB组件;对Apache axis Web服务开发工具有基本的了解;基本的Java编程知识。如果使用JAX-RPC开发Web服务,我们几种选择: Servlet作为Web服务端点;无状态会话Bean作为Web服务端点;基于消息(如JMS)的应用程序作为Web服务端点。本文以Servlet作为Web服务端点的情况来介绍JAX-RPC Web服务开发,关于本篇文章中案例的介绍详见本系列文章第一篇:《用JAXM开发Web服务》。 本文的参考见参考资料 本文的全部代码在这里下载 JAX-RPC快速入门 JAX-RPC,Java?API for XMLbased RPC,顾名思义,它是一种远程方法调用(或者说远程过程调用),那么它和其它的远程方法调用(RPC,COM,CORBA,RMI)有什么区别呢?我们看一般的远程方法调用的结构,如图1所示。 综合比较常用的远程方法调用技术,它们有以下的共性: 在客户端和服务端有通用编程接口;在客户端有Stub,在服务端有Tie(有的叫Skeleton);客户端和服务端有专门的进行数据传输。对于通用接口 Java RMI有Java RMI interface in 的描述,比如CORBA有IDL of CORBA, RMI,对于XMLbased RPC来说,IDL就是WSDL(Web服务描述语言)。那么XMLbased RPC来说,什么是这个结构中的"传输协议",当然是SOAP,SOAP消息通过以传输文本为基础的协议(HTTP、SMTP、FTP)为载体来使用的,也就是说,SOAP消息的传输建立在HTTP、SMTP、FTP传输协议之上。 JAX-RPC的构架如下。 从上图可以看出,客户端调用的是JAX-RPC服务端点(Service Endpoint),这个服务端点是通过WSDL语言描述的。在这个体系结构中,对于客户端,可以是JS2E、J2ME或者J2EE平台运行环境;对于服务端,可以是J2EE1.3或者J2EE1.4容器(Servlet容器或者EJB容器)。Apache axis是一个很好的JAX-RPC运行环境实现,同时也提供了优秀的开发工具,本文将使用它进行开发。 使用Servlet作为服务端点,本案例的基本构架如下图所示。 客户端通过SOAP消息和JAX-RPC服务端交互,JAX-RPC服务端运行在Servlet容器中,它通过调用EJB容器中的EJB组件来处理具体的业务逻辑。 使用JAX-RPC开发Web服务,可以按照以下的步骤进行: 服务端点定义;服务描述;服务端点实现;服务端点部署;服务发布和发现。注意:对于服务的发布和发现,由于机制比较复杂,本文不讨论,可能会在本系列文章进行专题讨论。 开发快速入门 一个完整的JAX-RPC开发实例,将按照上面的5个步骤进行,但是我们也 可以使用非常简单的方式来发布一个Web服务。在介绍我们的案例前,让我们 用一分钟快速开发一个Web服务。 首先安装好JWSDP,你可以从下载。 把本案例源代码中的\src\bookservice.ear\web.war目录拷贝 到%JWSDP_HOME%\webapps目录下,web.war文件里已经包括了Apache axis运 行环境。 在%JWSDP_HOME%\classes目录下新建一个HelloWorld.java文件,它的代 码如下: 例程1最简单的Web服务HelloWorld package com.hellking.webservice; public class HelloWorld{public String sayHello(String name){return"Hello~"+name;}} 编译这个类,然后编辑%JWSDP_HOME%\webapps\WEB-INF\server-config.wsdd文件,找到/service标记,在其后面加入以下内容: service name="HelloWorld"provider="java:RPC"parameter name="allowedMethods"value="sayHello"/parameter name="className"value="com.hellking.webservice.HelloWorld"//service 在浏览器例输入: 如果出现部署WSDL描述文件,那么最简单的Web服务已经部署成功~ 下面我们使用最简单的方式来调用这个Web服务,在浏览器里输入: 那么在浏览器将会显示以下内容: 例程2在浏览器里调用Web服务 ?xml version="1.0"encoding="UTF-8"?soapenv:Envelope xmlns: soapenv="xmlns:xsd="xmlns:xsi="soapenv:Body sayHelloResponse soapenv:encodingStyle="sayHelloReturn xsi:type="xsd:string"Hello~hellking/sayHelloReturn/sayHelloResponse/soapenv:Body/soapenv:Envelope 如果结果是这样,那么最简单的Web服务已经部署成功,并且测试也通过了。注意"Hello~hellking"是调用Web服务返回的结果,它是我们期望的。下面我们来看一个完整的Web服务开发的例子。 服务端点定义 服务端点定义的工作主要是确定"服务定义接口"(Service Definition Interface),有时也叫Web服务端点接口(Web services endpoint interface)。服务端点定义有两中方法获得: 使用某些工具从WSDL文件获得;直接使用Java语言编写。Apache axis提供了从WSDL文件中获得Web服务端点的工具。您可以这样使用: java org.apache.axis.wsdl.WSDL2Java(WSDL-file-URL) 使用这个命令前先设置好以下的环境变量,后面的介绍中还会使用axis工具,它们也要这样设置环境变量: SET AXIS_HOME=axis安装目录set CLASSPATH=%CLASSPATH%;%AXIS_HOME%/axis- 1_1/lib/axis.jar;%AXIS_HOME%/axis- 1_1/lib/jaxrpc.jar;%AXIS_HOME%/axis- 1_1/lib/saaj.jar;%AXIS_HOME%/axis-1_1/lib/commons-logging.jar;%AXIS_HOME%/axis-1_1/lib/commons-discovery.jar;%AXIS_HOME%/axis-1_1/lib/wsdl4j.jar;. 关于WSDL2Java的更详细的使用,请参考Apache axis的User Guides()。 我们这里直接使用Java编写服务端点接口的方法。在本案例中,定义了三个业务方法,它们分别是查找所有的图书、按书名查找图书、按类别查找图书。那么安照这三个业务方法,可以定义出以下的服务端点接口: 例程3服务端点定义(BookServiceInterface.java) package com.hellking.webservice.servlet;/**@author hellking*/import java.util.Collection;import com.hellking.webservice.BookVO;public interface BookServiceInterface{/**@return Vector*/public Collection getAllBooks();//查找所有的图书/**@param name*@return BookVO*/public BookVO getTheBookDetail(String name);//按照书名查找图书/**@return Collection*/public Collection getBookByCategory(String category);//按类别查找} 上面代码中的BookVO是一个序列化的对象,它有以下属性,每个属性都提供了getter和setter方法。 例程4 BookVO的部分代码 public class BookVO implements java.io.Serializable{private String name;private String publisher;private float price;private String isbn;private String description;private String category;private Collection authors;public void setName(String name){this.name=name;}public String getName(){return this.name;}…} 编译好这两个类。 服务端点描述 可以使用Java2WSDL从以上定义的服务端点接口中获得服务描述(WSDL文件)。使用Apache axis工具,只要使用以下命令即可: java org.apache.axis.wsdl.Java2WSDL-o temp.wsdl-l"-n"urn: BookServletService"-p"com.hellking.webservice""urn: BookServletService"com.hellking.webservice.servlet.BookServiceInterfa ce 以上命令的解释: -o:生成的WSDL文件;-l:Web服务的位置;-n:这个WSDL文件的名字空间;-p:包到名字空间的映射;最后一个参数是Web服务端点接口。 使用以上命令后,将生成一个名为temp.wsdl Web服务描述文。 服务端点实现 RPC的框架,这个框架使得有了服务描述文件,就可以使用它来生成JAX- 我们编程变得简单,当然您也可以直接编写实现代码,然后部署,但是那样编程会变得困难。 使用以下的命令就可以生成这个框架: java org.apache.axis.wsdl.WSDL2Java-o.-d Session-s-S true-Nurn:BookServletService com.hellking.webservice.servlet temp.wsdl 使用这个命令后将生成以下文件: BookServiceInterface.java:新的BookServiceInterface接口,它扩展了java.rmi.Remote接口; BookServiceInterfaceService.java:客户端服务接口,用来获得BookServiceInterface对象的引用; BookServiceInterfaceServiceLocator.java:在客户端使用,主要用来服务定位; BookServletServiceSoapBindingImpl.java:服务端实现类,它实现了BookServiceInterface接口,服务端的业务方法实现代码就在这里编写; BookServletServiceSoapBindingSkeleton.java:服务端Skeleton; BookServletServiceSoapBindingStub.java:客户端Stub; BookVO.java:新的BookVO序列化对象; deploy.wsdd:部署这个Web服务的脚本; undeploy.wsdd:卸载这个Web服务的脚本。 服务端点实现类的基本框架已经生成出来了,我们的任务就是往里面增加 具体的业务内容。下面我们来看具体的服务端点的实现。如例程3所示。 例程5服务端点实现类 package com.hellking.webservice.servlet;import java.util.*; import javax.naming.*;import com.hellking.webservice.ejb.*;public class BookServletServiceSoapBindingImpl implements com.hellking.webservice.servlet.BookServiceInterface{InitialContext init=null;BookServiceFacadeHome facadeHome;public BookServletServiceSoapBindingImpl(){try{init=new }catch(Exception e){}}//业务方法,查找所有的图书InitialContext(); public java.lang.Object getAllBooks()throws java.rmi.RemoteException{System.out.println("getAllBooks"); try{Object objref=init.lookup("ejb/bookfacade"); facadeHome=(BookServiceFacadeHome)javax.rmi.PortableRemoteObject.narr ow(objref,BookServiceFacadeHome.class);Collection result=facadeHome.create().getAllBook(); System.out.println(result.size());Object ret=new Object[result.size()];Iterator it=result.iterator();int i=0; while(it.hasNext()){ret[i++]=it.next();}//System.out.println(((BookVO)ret[0]).getName());return ret;}catch(Exception e){e.printStackTrace();return null;}}//业务方法,按书名查找图书 public com.hellking.webservice.BookVO getTheBookDetail(java.lang.String in0)throws java.rmi.RemoteException{com.hellking.webservice.BookVO ret=null; try{Object objref=init.lookup("ejb/bookfacade"); facadeHome=(BookServiceFacadeHome)javax.rmi.PortableRemoteObject.narr ow(objref,BookServiceFacadeHome.class);Collection result=facadeHome.create().getBookDetail(in0);Iterator it=result.iterator(); while(it.hasNext()){ret=(com.hellking.webservice.BookVO)it.next();}}catch(Exception e){}return ret;}//业务方法,按类别查找图书public java.lang.Object getBookByCategory(java.lang.String in0)throws java.rmi.RemoteException{try{Object objref=init.lookup("ejb/bookfacade"); facadeHome=(BookServiceFacadeHome)javax.rmi.PortableRemoteObject.narr ow(objref,BookServiceFacadeHome.class);System.out.println(in0);Collection result=facadeHome.create().findByCategory(in0);Object ret=new Object[result.size()];Iterator it=result.iterator();int i=0;while(it.hasNext()){ret[i++]=it.next(); System.out.println(i);}return ret;}catch(Exception return null;}}} e){e.printStackTrace(); 可以看出,服务端点的主要任务是调用EJB组件来完成业务逻辑的。 需要向读者说明的是,为了和本系列第一篇文章中的客户端框架兼容(客户端使用的值对象是com.hellking.webservice.BookVO,而这里由WSDL2Java生成的值对象是com.hellking.webservice.servlet.BookVO)。我们需要做以下的改动: 把生成的这些代码中的com.hellking.webservice.servlet.BookVO全部改为com.hellking.webservice.BookVO,然后在Apache axis服务配置文件中申明这个BeanMapping,具体的声明方法在后面介绍。 接下来的工作是编译服务端相关的文件: BookServletServiceSoapBindingImpl、 BookServletServiceSoapBindingSkeleton、BookServiceInterfaceService、BookServiceInterface。 服务端点部署 启动服务器,这个服务器可以是任何能够运行Apache引擎Web服务器,当然最好是同时有EJB容器和EJB容器的服务器,如Webphere、Weblogic、JBOSS,如果没有EJB容器,还需要一个额外的EJB容器,并且需要更改 BookServletServiceSoapBindingImpl中获得上下文(InitialContext)的方法,如: 例程6获得上下文环境 Properties p=new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY,"xxxxx"); p.put(Context.URL_PKG_PREFIXES,"xxxx"); init=new p.put(Context.PROVIDER_URL,"xxxx"); javax.naming.InitialContext(p); 在控制台中,转到deploy.wsdd目录下,执行以下的命令就可以完成部署: java org.apache.axis.client.AdminClient deploy.wsdd 由于我们使用的是自己的序列化Bean对象,故要在%Web-Apps%/WEB-INF/server-config.wsdd文件中做以下更改:找到 service name="BookServletService"provider="java:RPC"…/service 在中间加入以下内容: beanMapping languageSpecificType="java: com.hellking.webservice.BookVO"qname="ns7:BookServletService"xmlns:ns7="BookServletService"/ 部署后您必须确保在%Web-Apps%/WEB-INF/classes目录下有服务端相关的类(BookServletServiceSoapBindingImpl、 BookServletServiceSoapBindingSkeleton等)。 在浏览器里输入(这个地址您需要根据具体情况更改): 来验证Web服务是否已经部署成功,如果部署不成功,您可以先尝试重新启动服务器。 客户端 如果服务端已经成功部署,下一步的工作就是编写客户端程序了。由于使用WSDL2Java已经生成了客户端的框架,所以我们的任务将相对简单了。 客户端编程任务主要有以下几个: 在BookServletServiceSoapBindingStub里注册BeanMapping;编写客户端业务代,这里使用了JAXRPCDelegate;更改以前的BookGUI的部分程序。 在BookServletServiceSoapBindingStub里注册BeanMapping 由于在SOAP消息中使用了序列化的BookVO对象,故在 BookServletServiceSoapBindingStub中要进行BeanMapping注册。具体方法: 找到BookServletServiceSoapBindingStub中的getAllBooks, getTheBookDetail,getBookByCategory方法,在每个方法中的 java.lang.Object _resp=_call.invoke(new java.lang.Object{in0}); 前加入以下代码: 例程7在BookServletServiceSoapBindingStub注册BeanMapping QName qn=new QName("BookServletService","BookServletService"); _call.registerTypeMapping(com.hellking.webservice.BookVO.class,qn,new org.apache.axis.encoding.ser.BeanSerializerFactory(com.hellking.webse rvice.BookVO.class,qn),new org.apache.axis.encoding.ser.BeanDeserializerFactory(com.hellking.web service.BookVO.class,qn)); 注意这里的Qname要和server-config.wsdd中描述的名称空间一致。在中server-config.wsdd,我们使用了以下的映射: beanMapping languageSpecificType="java: com.hellking.webservice.BookVO"qname="ns7:BookServletService"xmlns:ns7="BookServletService"/ 在编写业务代表程序前,我们先来对Web服务做一个调用测试。在测试前您必须保证数据库里已经有图书信息。如果EJB和Web Application都部署好,您可以通过以下页面来往数据库里增加数据: 测试代码如下: 例程8测试Web服务 package com.hellking.webservice.servlet;import java.net.URL;import javax.xml.namespace.QName;import javax.xml.rpc.Service;import javax.xml.rpc.ServiceFactory;import com.hellking.webservice.ejb.*;public class Client{public static void main(String args){try{BookServiceInterfaceServiceLocator locator=new BookServiceInterface BookServiceInterfaceServiceLocator(); myProxy=locator.getBookServletService();Object com.hellking.webservice.BookVO c=myProxy.getAllBooks(); book=(com.hellking.webservice.BookVO)c[0]; System.out.println(book.getName());}catch(Exception ex){ex.printStackTrace();}}} 如果在控制台里打印出某个图书的名字,那么就验证了客户端和服务端的部署是正确的。在进行下面的工作前,请确保这个测试是成功的。 编写客户端业务代表 对于客户端程序来说,业务代表直接和Web服务打交道,获得Web服务返回的数据,并做对应的处理,然后把数据返回给GUI程序,GUI程序只负责数据显示。业务代表的代码如下: 例程9 JAXRPCDelegate业务代表 package com.hellking.webservice.servlet;import java.net.URL;import javax.xml.namespace.QName;import javax.xml.rpc.Service;import javax.xml.rpc.ServiceFactory;import com.hellking.webservice.ejb.*;import java.util.*;public class JAXRPCDelegate implements com.hellking.webservice.BookBusiness{BookServiceInterfaceServiceLocat or locator;com.hellking.webservice.servlet.BookServiceInterface bookService;public JAXRPCDelegate(){try{locator=new BookServiceInterfaceServiceLocator(); }catch(Exception bookService=locator.getBookServletService(); e){}}public Collection getBookByCategory(String category){System.out.println("by_category");Collection ret=new ArrayList();try{Object books=bookService.getBookByCategory(category); System.out.println(category);int i=0; while(true){ret.add(books[i++]); }public System.out.println(i);}}catch(Exception e){}return ret; Collection getAllBooks(){Collection ret=new ArrayList();try{Object books=bookService.getAllBooks();int i=0; while(true){ret.add(books[i++]);}}catch(Exception e){}return ret;}public com.hellking.webservice.BookVO getTheBookDetail(String name){System.out.println("bookdetail"); com.hellking.webservice.BookVO ret=new com.hellking.webservice.BookVO(); try{ret=bookService.getTheBookDetail(name);}catch(Exception e){}return ret;}} 和第一篇文章介绍的JAXMDelegate一样,JAXRPCDelegate同样实现了 BookBusiness接口,BookBusiness接口是以前的接口,我们在这里进行重 用,这样的好处是BookClientGUI程序几只要做很少的更改就可以运行。 更改以前的BookClientGUI的部分程序 在BookGUI构造方法里增加以下内容: 例程10更改BookGUI程序 public BookClientGUI(){business=new JAXRPCDelegate();…} 好了,经过以上的奋战,让我们来看运行的结果吧。 java com.hellking.webservice.BookClientGUI 运行结果如图4所示。 总结 通过以上的介绍,相信读者对JAX-RPC Web服务开发已经有一个比较深刻的认识。总结一下,使用JAX-RPC开发Web服务时,主要有以下的工作: 服务端点定义;服务描述;服务端点实现;服务端点部署; 下一步 本文已经介绍了把Servlet作为Web服务端点开发Web服务的全过程,下一篇将是把EJB作为Web服务端点来开发。 参考资料 Apache axis User's Guides:Sun jwsdp-1_1-tutorial,&Web services专区JAX-RPC API Jwdp1.1下载样例代码 关于作者 陈亚强:北京华园天一科技有限公司高级软件工程师,擅长J2EE技术,曾参与多个J2EE项目的设计和开发,对Web服务有很大的兴趣并且有一定的项目经验。热爱学习,喜欢新技术。即将由电子工业出版社出版的《J2EE企业应用开发》正在最终定稿阶段,目前正从事J2EE方面的开发和J2EE Web服务方面的图书写作。您可以通过和他联系。 特别声明: 1:资料来源于互联网,版权归属原作者 2:资料内容属于网络意见,与本账号立场无关 3:如有侵权,请告知,立即删除。
/
本文档为【用JAX RPC开发Web服务 Servlet 作】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索