




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
java远程通讯技术及简单实现JavaJMS应用服务器网络协议网络应用 在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java底层领域中有很多可实现远程通讯的技术,例如:RMI、MINA、ESB、Burlap、SOAP、EJB和JMS 等,在j2ee中,对java底层远程通讯的技术进行了封装,形成了 Hessian 、 HttpInvoker 、 XFire 、 Axis 等多种形式的远程调用技术。 但对高级程序员而言仍需要掌握Java底层领域中远程通讯的技术,尤其是rmi,xml-rpc,JMS。1.远程服务基本原理1)底层协议要实现网络机器间的通讯,首先得来看看计算机系统网络通信的基本原理,在底层层面去看,网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络IO来实现,其中传输协议比较出名的有http、tcp、udp等等,http、tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议,网络IO,主要有bio、nio、aio三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。2)应用级协议远程服务通讯,需要达到的目标是在一台计算机发起请求,另外一台机器在接收到请求后进行相应的处理并将结果返回给请求端,这其中又会有诸如one way request、同步请求、异步请求等等请求方式,按照网络通信原理,需要实现这个需要做的就是将请求转换成流,通过传输协议传输至远端,远端计算机在接收到请求的流后进行处理,处理完毕后将结果转化为流,并通过传输协议返回给调用端。 在java领域中知名的远程通信的应用级协议有:RMI、XML-RPC、Binary-RPC、SOAP、JMS2.RMI2.1RMI原理 RMI,即Java RMI(Java Remote Method Invocation),Java远程方法调用.是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI是个典型的为java定制的远程通信协议,RMI全部的宗旨就是尽可能简化远程接口对象的使用。 RMI的基础是接口,RMI构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。来看下基于RMI的一次完整的远程通信过程的原理:1)客户端发起请求,请求转交至RMI客户端的stub类;2)stub类将请求的接口、方法、参数等信息进行序列化;3)基于socket将序列化后的流传输至服务器端;4)服务器端接收到流后转发至相应的skelton类;5)skelton类将请求的信息反序列化后调用实际的处理类;6)处理类处理完毕后将结果返回给skelton类;7)Skelton类将结果序列化,通过socket将流传送给客户端的stub;8)stub在接收到流后反序列化,将反序列化后的Java Object返回给调用者。2.2JAVA对RMI的支持 java.rmi是JAVA提供 RMI 包。RMI是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。调用这样一个对象时,其参数为 marshalled 并将其从本地虚拟机发送到远程虚拟机(该远程虚拟机的参数为 unmarshalled)上。该方法终止时,将编组来自远程机的结果并将结果发送到调用方的虚拟机。如果方法调用导致抛出异常,则该异常将指示给调用方. Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口。2.3rmi在java中的应用 要使用RMI,必须构建四个主要的类:远程对象的本地接口、远程对象实现、RMI客户机和RMI服务器。RMI服务器生成远程对象实现的一个实例,并用一个专有的URL注册。RMI客户机在远程RMI服务器上查找服务对象,并将它转换成本地接口类型,然后像对待一个本地对象一样使用它。1)远程对象的本地接口package test.rmi;import java.rmi.Remote;import java.rmi.RemoteException;public interface HelloRMI extends Remote /* * 简单的返回“Hello World!字样 * return 返回“Hello World!字样 * throws java.rmi.RemoteException */ public String helloWorld() throws RemoteException; /* * param someBodyName * return 返回相应的问候语 * throws java.rmi.RemoteException */ public String sayHelloToSomeBody(String someBodyName) throws RemoteException;2)远程对象实现Java代码1. packagetest.rmi;2. 3. importjava.rmi.RemoteException;4. importjava.rmi.server.UnicastRemoteObject;5. 6. /*7. *User:staratsky8. *Date:2008-8-721:56:479. *远程的接口的实现10. */11. publicclassHelloRMIImplextendsUnicastRemoteObjectimplementsHelloRMI12. privatestaticfinallongserialVersionUID=-L;13. 14. /*15. *因为UnicastRemoteObject的构造方法抛出了RemoteException异常,因此这里默认的构造方法必须写,必须声明抛出RemoteException16. 17. 异常18. *19. *throwsRemoteException20. */21. publicHelloRMIImpl()throwsRemoteException22. 23. 24. 25. /*26. *简单的返回“HelloWorld!字样27. *28. *return返回“HelloWorld!字样29. *throwsjava.rmi.RemoteException30. */31. publicStringhelloWorld()throwsRemoteException32. returnHelloWorld!;33. 34. 35. /*36. *paramsomeBodyName37. *return返回问候语38. *throwsjava.rmi.RemoteException39. */40. publicStringsayHelloToSomeBody(StringsomeBodyName)throwsRemoteException41. return你好,+someBodyName+!;42. 43. 3)RMI服务器Java代码1. packagetest.rmi;2. 3. .MalformedURLException;4. importjava.rmi.AlreadyBoundException;5. importjava.rmi.Naming;6. importjava.rmi.RemoteException;7. importjava.rmi.registry.LocateRegistry;8. 9. /*10. *User:staratsky11. *Date:2008-8-722:03:3512. *创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。13. */14. publicclassHelloRMIServer15. publicstaticvoidmain(Stringargs)16. try17. /创建一个远程对象18. HelloRMIrhello=newHelloRMIImpl();19. /本地主机上的远程对象注册表Registry的实例,并指定端口为8888,这一步必不可少(Java默认端口是1099),必不可缺的一20. 21. 步,缺少注册表创建,则无法绑定对象到远程注册表上22. LocateRegistry.createRegistry(8888);23. 24. /把远程对象注册到RMI注册服务器上,并命名为RHello25. /绑定的URL标准格式为:rmi:/host:port/name(其中协议名可以省略,下面两种写法都是正确的)26. Naming.bind(rmi:/localhost:8888/RHello,rhello);27. /Naming.bind(/localhost:8888/RHello,rhello);28. 29. System.out.println(INFO:远程IHello对象绑定成功!);30. catch(RemoteExceptione)31. System.out.println(创建远程对象发生异常!);32. e.printStackTrace();33. catch(AlreadyBoundExceptione)34. System.out.println(发生重复绑定对象异常!);35. e.printStackTrace();36. catch(MalformedURLExceptione)37. System.out.println(发生URL畸形异常!);38. e.printStackTrace();39. 40. 41. 4)RMI客户机Java代码1. packagetest.rmi;2. 3. .MalformedURLException;4. importjava.rmi.Naming;5. importjava.rmi.NotBoundException;6. importjava.rmi.RemoteException;7. 8. /*9. *User:staratsky10. *Date:2008-8-722:21:0711. *客户端测试,在客户端调用远程对象上的远程方法,并返回结果。12. */13. publicclassHelloRMIClient14. publicstaticvoidmain(Stringargs)15. try16. /在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法17. HelloRMIrhello=(HelloRMI)Naming.lookup(rmi:/localhost:8888/RHello);18. System.out.println(rhello.helloWorld();19. System.out.println(rhello.sayHelloToSomeBody(staratsky);20. catch(NotBoundExceptione)21. e.printStackTrace();22. catch(MalformedURLExceptione)23. e.printStackTrace();24. catch(RemoteExceptione)25. e.printStackTrace();26. 27. 28. 总结:从上面的过程来看,RMI对服务器的IP地址和端口依赖很紧密,但是在开发的时候不知道将来的服务器IP和端口如何,但是客户端程序依赖这个IP和端口。 这也是RMI的局限性之一。这个问题有两种解决途径:一是通过DNS来解决,二是通过封装将IP暴露到程序代码之外。 RMI的局限性之二是RMI是Java语言的远程调用,两端的程序语言必须是Java实现,对于不同语言间的通讯可以考虑用Web Service来实现。3.XML-RPC3.1原理 XML-RPC 网站是这样描述的: 它是允许运行在不同操作系统、不同环境中的软件进行基于 Internet 过程调用的规范和一组实现。这种远程过程调用使用 HTTP 作为传输协议,XML 作为编码格式。XML-RPC 的定义尽可能简单,但能够传送、处理和返回复杂的数据结构。 XML-RPC消息都是HTTP-POST请求。请求的主要部分的XML。服务器端执行后的返回结果同样也是XML格式。函数调用的参数可以是scalars, numbers, strings, dates等等;也可以是混合型的记录和结构体。 所以,要完成XML-RPC,需要完成3部分工作:1)接口实现Java代码1. packagetest.xmlrpc;2. 3. ublicclassHelloHandlerimplementsServicesHandler4. publicStringexecute(Stringstr)5. returnHello,+str+!;6. 2)远程调用Java代码1. packagetest.xmlrpc;2. 3. importjava.io.IOException;4. .MalformedURLException;5. importjava.util.Vector;6. .URL;7. importorg.apache.xmlrpc.XmlRpcException;8. importorg.apache.xmlrpc.client.XmlRpcClient;9. importorg.apache.xmlrpc.client.XmlRpcClientConfigImpl;10. 11. publicclassTestClient12. publicstaticvoidmain(Stringargs)throwsException13. try14. 15. /configclient16. XmlRpcClientConfigImplconfig=newXmlRpcClientConfigImpl();17. config.setServerURL(newURL(http:/localhost:8080/yizhu/HelloHandler);/shouldbemodifiedaccording18. 19. toyourconfigurationofjspcontainer20. /createanewXmlRpcClientobjectandbindaboveconfigobjectwithit21. XmlRpcClientclient=newXmlRpcClient();22. client.setConfig(config);23. /createparameterlist24. Vectorparams=newVector();25. params.addElement(MY);26. /executeXML-RPCcall27. Stringresult=(String)client.execute(HelloHandler.execute,params);28. System.out.println(result);29. catch(MalformedURLExceptione)30. System.out.println(e.toString();31. catch(XmlRpcExceptione)32. System.out.println(e.toString();33. catch(IOExceptione)34. e.printStackTrace();35. 36. 37. 3)建立一个web服务器Java代码1. packagetest.xmlrpc;2. 3. importjavax.servlet.*;4. importjavax.servlet.http.*;5. importjava.io.*;6. importorg.apache.xmlrpc.*;7. importorg.apache.xmlrpc.server.*;8. importorg.apache.xmlrpc.webserver.*;9. 10. publicclassXmlRpcServicesServletextendsHttpServlet11. 12. privateXmlRpcServletServerserver;13. 14. publicvoidinit(ServletConfigpConfig)throwsServletException15. 16. super.init(pConfig);17. 18. try19. /createanewXmlRpcServletServerobject20. server=newXmlRpcServletServer();21. 22. /setuphandlermappingofXmlRpcServletServerobject23. PropertyHandlerMappingphm=newPropertyHandlerMapping();24. phm.addHandler(HelloHandler,HelloHandler.class);25. server.setHandlerMapping(phm);26. 27. /moreconfigofXmlRpcServletServerobject28. XmlRpcServerConfigImplserverConfig=(XmlRpcServerConfigImpl)server.getConfig();29. serverConfig.setEnabledForExtensions(true);30. serverConfig.setContentLengthOptional(false);31. catch(XmlRpcExceptione)32. try33. log(FailedtocreateXmlRpcServer:+e.getMessage(),e);34. 35. catch(Throwableignore)36. 37. 38. thrownewServletException(e);39. 40. 41. 42. 43. publicvoiddoPost(HttpServletRequestRequest,HttpServletResponseResponse)44. 45. throwsIOException,ServletException46. 47. server.execute(Request,Response);48. 49. 50. publicvoiddoGet(HttpServletRequestRequest,HttpServletResponseResponse)51. 52. throwsIOException,ServletException53. 54. server.execute(Request,Response);55. 56. 在web.xml中的配置Java代码1. 2. XmlRpcServer3. test.xmlrpc.XmlRpcServicesServlet4. 5. 6. XmlRpcServer7. /HelloHandler8. 3.2RMI和RPC的区别XML-RPC也是一种和RMI类似的远程调用的协议,它和RMI的不同之处在于它以标准的xml格式来定义请求的信息(请求的对象、方法、参数等).所以, 在RMI和RPC之间最主要的区别在于方法是如何别调用的。 在RMI中,远程接口使每个远程方法都具有方法签名。如果一个方法在服务器上执行,但是没有相匹配的签名被添加到这个远程接口上,那么这个新方法就不能被RMI客户方所调用。在RPC中,当一个请求到达RPC服务器时,这个请求就包含了一个参数集和一个文本值,通常形成“classname.methodname”的形式。这就向RPC服务器表明,被请求的方法在为“classname”的类中,名叫“methodname”。然后RPC服务器就去搜索与之相匹配的类和方法,并把它作为那种方法参数类型的输入。这里的参数类型是与RPC请求中的类型是匹配的。一旦匹配成功,这个方法就被调用了,其结果被编码后返回客户方。3.3xml-rpc的缺点1)XML-RPC的消息系统过于简单,没有完整意义上的消息模型2)XML-RPC调用服务的方式要求直接指定对象和方法,称不上完整的面向服务的体系3)XML-RPC服务器端提供的服务实际上是特定对象的某个方法,限制了服务器端的开发4.Binary-RPCBinary-RPC看名字就知道和XML-RPC是差不多的了,不同之处仅在于传输的标准格式由XML转为了二进制的格式。 Hessian是由caucho提供的一个基于binary-RPC实现的远程通讯library。1)写一个接口:Java代码1. packagetest.hassian;2. publicinterfaceSayHello3. publicStringsayHello(Stringname);4. publicStudentgetStudent();5. 6. 2)编写一个实现:Java代码1. packagetest.hassian;2. importcom.caucho.hessian.server.HessianServlet;3. publicclassSayHelloImplextendsHessianServletimplementsSayHello4. publicStringsayHello(Stringname)5. returnhello+name;6. 7. publicStudentgetStudent()8. Students=newStudent();9. s.setName(staratsky);10. s.setSchool(ustc);11. returns;12. 13. 14. 3)bean类Java代码1. packagetest.hassian;2. importjava.io.Serializable;3. 4. publicclassStudentimplementsSerializable5. /*6. *7. */8. privatestaticfinallongserialVersionUID=-L;9. privateStringname;10. privateStringschool;11. publicStringgetName()12. returnname;13. 14. publicvoidsetName(Stringname)15. =name;16. 17. publicStringgetSchool()18. returnschool;19. 20. publicvoidsetSchool(Stringschool)21. this.school=school;22. 23. pub
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中西医结合人才选拔实战面试题库
- 小儿腹股沟疝的护理
- 大型商场超市春节促销策划书 -策划
- 地理教学研修总结
- 2025基于AI双碳源网荷储智慧综合能源平台建设方案
- oem供应商供货协议合同范本
- 小儿推拿腺样体肥大课件
- 医用输液吊桥采购合同范本
- 小儿推拿提高免疫力课件
- 关于租用土地的合同范本
- 维修单(标准模版)
- 市政工程占道施工方案
- GB/T 39965-2021节能量前评估计算方法
- GB/T 17449-1998包装玻璃容器螺纹瓶口尺寸
- GB/T 12243-2021弹簧直接载荷式安全阀
- GB/T 10066.4-2004电热设备的试验方法第4部分:间接电阻炉
- PMC知识培训课件
- CJJ82-2019-园林绿化工程施工及验收规范
- 个人信息(模板)
- 会计师事务所验资工作底稿模板
- 婚育情况登记表
评论
0/150
提交评论