日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

远程过程调用RPC RMI(Remote Method Invocation)和Web Service

發布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 远程过程调用RPC RMI(Remote Method Invocation)和Web Service 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

一、RPC是什么

? ? RPC的全稱是Remote Procedure call,是進程間通信方式。

? ? 他允許程序調用另一個地址空間的過程或者函數,不用去關注此過程或函數的實現細節。比如兩臺服務器A,B,一個應用部署在A服務器上,想要調用B服務器上應用提供的函數或者方法,由于不在一個內存空間,不能直接調用,這時候需要通過就可以應用RPC框架的實現來解決。

二、RPC的實現

? ? RPC有很多開源的框架實現這里主要介紹java自帶的RMI

? ? 1、RMI是什么

????????RMI全稱是Remote?Method?Invocation-遠程方法調用,Java?RMI在JDK1.1中實現的,其威力就體現在它強大的開發分布式網絡應用的能力上,是純Java的網絡分布式應用系統的核心解決方案之一。其實它可以被看作是RPC的Java版本。要求客戶端和服務端都要用java實現

? ? 2、RMI簡單實例

? ? (1)服務端代碼實現:

????IHello類實現:

import java.rmi.Remote; import java.rmi.RemoteException;public interface IHello 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; }

? ? HelloImpl實現IHello實現:

import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject;public class HelloImpl extends UnicastRemoteObject implements IHello{protected HelloImpl() throws RemoteException {super();}@Overridepublic String helloWorld() throws RemoteException {return "Hello Word";}@Overridepublic String sayHelloToSomeBody(String someBodyName) throws RemoteException {return "你好," + someBodyName + "!";}}

? ? HelloServer:

import java.net.MalformedURLException; import java.nio.channels.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry;/** * Created by IntelliJ IDEA. * Date: 2008-8-7 22:03:35 * 創建RMI注冊表,啟動RMI服務,并將遠程對象注冊到RMI注冊表中。 */ public class HelloServer { public static void main(String args[]) throws java.rmi.AlreadyBoundException { try { //創建一個遠程對象 IHello rhello = new HelloImpl(); //本地主機上的遠程對象注冊表Registry的實例,并指定端口為8888,這一步必不可少(Java默認端口是1099),必不可缺的一步,缺少注冊表創建,則無法綁定對象到遠程注冊表上 LocateRegistry.createRegistry(8888); //把遠程對象注冊到RMI注冊服務器上,并命名為RHello //綁定的URL標準格式為:rmi://host:port/name(其中協議名可以省略,下面兩種寫法都是正確的) Naming.bind("rmi://localhost:8888/RHello",rhello); // Naming.bind("//localhost:8888/RHello",rhello); System.out.println(">>>>>INFO:遠程IHello對象綁定成功!"); } catch (RemoteException e) { System.out.println("創建遠程對象發生異常!"); e.printStackTrace(); } catch (AlreadyBoundException e) { System.out.println("發生重復綁定對象異常!"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("發生URL畸形異常!"); e.printStackTrace(); } } }

? ?(2)客戶端代碼實現:

???? 新建客戶端工程GiveMeWords,客戶端需要將服務端的IHello接口拷貝過來,并且必須和服務器端包名相同。否則會報如下錯誤(本人親測):

????????java.lang.ClassNotFoundException: test.rmi.IHello (no security manager: RMI class loader)

import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException;public class HelloClient {public static void main(String args[]){ try { //在RMI服務注冊表中查找名稱為RHello的對象,并調用其上的方法 IHello rhello =(IHello) Naming.lookup("rmi://localhost:8888/RHello"); System.out.println(rhello.helloWorld()); System.out.println(rhello.sayHelloToSomeBody("熔巖")); } catch (NotBoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } }

服務端工程結構截圖?

客戶端工程結構截圖

先運行服務器端代碼,在運行客戶端代碼。運行結果:

三、Web Service

? ? 1、WebService是一種跨編程語言和跨操作系統平臺的遠程調用技術。

? ? ????XML+XSD,SOAP和WSDL就是構成WebService平臺的三大技術。Web Service采用http協議傳輸,數據格式為特定格式的XML。

????? ? SOAP協議=HTTP協議+XML協議

????????WSDL(Web Service Description Language)基于XML語音的,用于描述Web Service及其函數、參數和返回值。它是WebService客戶端和服務器端都能理解的標準格式。WSDL文件保存在Web服務器上,通過一個url地址就可以訪問到它??蛻舳艘{用一個WebService服務之前,要知道該服務的WSDL文件的地址。WebService服務提供商可以通過兩種方式來暴露它的WSDL文件地址:1.注冊到UDDI服務器,以便被人查找;2.直接告訴給客戶端調用者。也就是說我們要進行Web Service開發,通過服務器端的WSDL文件,我們就可以編寫客戶端調用代碼。

????? ? 服務端代碼:

import javax.jws.WebService; import javax.xml.ws.Endpoint;@WebService public class Function {public String transWords(String words){String res = "";for(char ch : words.toCharArray()){res += "\t" + ch + "\t";}return res;}public static void main(String[] args){Endpoint.publish("http://localhost:9001/Service/Function", new Function());System.out.println("publish success");} }

運行成功后訪問http://localhost:9001/Service/Function?wsdl。wsdl文件如下:

<!--Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. --> <!--Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. --> <definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webService.test/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://webService.test/" name="FunctionService"> <types> <xsd:schema> <xsd:import namespace="http://webService.test/" schemaLocation="http://localhost:9001/Service/Function?xsd=1"/> </xsd:schema> </types> <message name="transWords"> <part name="parameters" element="tns:transWords"/> </message> <message name="transWordsResponse"> <part name="parameters" element="tns:transWordsResponse"/> </message> <portType name="Function"> <operation name="transWords"> <input wsam:Action="http://webService.test/Function/transWordsRequest" message="tns:transWords"/> <output wsam:Action="http://webService.test/Function/transWordsResponse" message="tns:transWordsResponse"/> </operation> </portType> <binding name="FunctionPortBinding" type="tns:Function"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="transWords"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="FunctionService"> <port name="FunctionPort" binding="tns:FunctionPortBinding"> <soap:address location="http://localhost:9001/Service/Function"/> </port> </service> </definitions>

? ??WSDL 文檔在Web服務的定義中使用下列元素:

  • Types?- 數據類型定義的容器,它使用某種類型系統(一般地使用XML Schema中的類型系統)。
  • Message?- 通信消息的數據結構的抽象類型化定義。使用Types所定義的類型來定義整個消息的數據結構。
  • Operation?- 對服務中所支持的操作的抽象描述,一般單個Operation描述了一個訪問入口的請求/響應消息對。
  • PortType?- 對于某個訪問入口點類型所支持的操作的抽象集合,這些操作可以由一個或多個服務訪問點來支持。
  • Binding?- 特定端口類型的具體協議和數據格式規范的綁定。
  • Port?- 定義為協議/數據格式綁定與具體Web訪問地址組合的單個服務訪問點。
  • Service- 相關服務訪問點的集合。

? ? 然后在客戶端項目下運行如下命令?wsimport -s Documents/workspace/GiveMeWords/src?-p com.shu.service?-keep http://localhost:9001/Service/Function?wsdl?即可自動生成客戶端代碼

????Documents/workspace/GiveMeWords/src代碼位置

????com.shu.service包名

? ? 測試代碼:

public class Test {/*** 測試webservice此作為客戶端* test項目中的webService包下面的Function作為服務端*wsimport -s Documents/workspace/GiveMeWords/src -p com.shu.service -keep http://localhost:9001/Service/Function?wsdl* @param args*/public static void main(String[] args){Function fu = new FunctionService().getFunctionPort();String str = fu.transWords("get my words");System.out.println(str);} }

? ? 運行即可調用服務端的遠程方法transWords()方法。但是客戶端怎么知道服務端暴露出來的服務就是transWords呢,還有參數返回值這些客戶端是怎么知道的?我們回到上面的WSDL文件:

<portType name="Function"> <operation name="transWords"> <input wsam:Action="http://webService.test/Function/transWordsRequest" message="tns:transWords"/> <output wsam:Action="http://webService.test/Function/transWordsResponse" message="tns:transWordsResponse"/> </operation> </portType>

operation表情表明方法暴露服務的方法名是transWords。<input>標簽標示輸入參數,<output>函數返回值。這樣我們就得到了我們想要的接口了??傊ㄟ^WSDL文件我們就可以進行編程。

轉載于:https://my.oschina.net/u/579493/blog/897359

總結

以上是生活随笔為你收集整理的远程过程调用RPC RMI(Remote Method Invocation)和Web Service的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。