天天看點

spring mvc 實作遠端服務調用的幾種方式

org.springframework.remoting.httpinvoker.httpinvokerserviceexporter 實作遠端服務調用

(1)httpinvoker方式 伺服器用戶端都是spring時推薦這種方式

服務端 必須要實作 bean實體類  service接口類  serviceimpl服務實作類

用戶端隻需拷貝 bean 實體類  service接口類(注意 ,用戶端 bean,service類要和服務端bean,service類包路徑相同,比如都是

com.hlzt.csm.model.dataplatformcountbean,不然會報找不到類,而且 bean要序列化  public class dataplatformcount implements serializable;

如果服務端有 序列化的private static final long serialversionuid = 1l号,用戶端也必須有,如果服務端沒有此id,用戶端也不要有此id,不然會出錯。service類的包路徑也要相同,最好服務端寫好後直接把實體類和service服務接口類打包,拷貝到用戶端,以免造成兩端不同。

伺服器端要在spring-mvc配置檔案 spring-mvc-servlet.xml中加入以下(注意是在spring-mvc的配置檔案中,不是spring的配置檔案)

服務端 web.xml的配置

spring mvc 實作遠端服務調用的幾種方式

用戶端配置

用戶端 spring的xml檔案配置

注意的是 id="csmdatacountser" 本人測試結果是 此執行個體不能在java中通過 rource 或autowired自動注入,而要通過手工載入方式獲得

applicationcontext context =new classpathxmlapplicationcontext("/spring/spring-remote.xml");

csmdatacountser csmdatacountser=(csmdatacountser)context.getbean("csmdatacountser");

(2)spring rmi方式

首先看下執行個體程式目錄結構:

spring mvc 實作遠端服務調用的幾種方式

spring中釋出rmi服務(zlv_rmiserverwithspring):

(1) 定義接口messageprovider及接口中供調用的方法(messageprovider.java):

<a target="_blank" href="http://my.oschina.net/lvsantorini/blog/489405#">?</a>

1

2

3

4

5

<code>package</code> <code>org.thera.rmi.service;</code>

<code>public</code> <code>interface</code> <code>messageprovider {</code>

<code>    </code><code>public</code> <code>string queryformessage(string name);</code>

<code>}</code>

(2) 實作messageprovider接口(messageproviderimpl.java):

6

7

8

9

10

<code>public</code> <code>class</code> <code>messageproviderimpl </code><code>implements</code> <code>messageprovider {</code>

<code>    </code><code>@override</code>

<code>    </code><code>public</code> <code>string queryformessage(string name) {</code>

<code>        </code><code>return</code> <code>"hello, "</code> <code>+ name;</code>

<code>    </code><code>}</code>

做好了上述準備,下面我們就可以通過spring中內建rmi,友善的釋出rmi服務端

(3) spring配置檔案作如下配置(context.xml):

11

12

13

14

15

16

17

18

19

20

21

<code>&lt;?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code> <code>encoding</code><code>=</code><code>"utf-8"</code><code>?&gt;</code>

<code>&lt;</code><code>beans</code> <code>xmlns</code><code>=</code><code>"http://www.springframework.org/schema/beans"</code>

<code>    </code><code>xmlns:p</code><code>=</code><code>"http://www.springframework.org/schema/p"</code> <code>xmlns:xsi</code><code>=</code><code>"http://www.w3.org/2001/xmlschema-instance"</code>

<code>    </code><code>xsi:schemalocation="http://www.springframework.org/schema/beans</code>

<code>        </code><code>http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;</code>

<code>    </code><code>&lt;!-- 注入要釋出的rmi服務類 --&gt;</code>

<code>    </code><code>&lt;</code><code>bean</code> <code>id</code><code>=</code><code>"messageservice"</code> <code>class</code><code>=</code><code>"org.thera.rmi.service.messageproviderimpl"</code><code>&gt;&lt;/</code><code>bean</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>bean</code> <code>class</code><code>=</code><code>"org.springframework.remoting.rmi.rmiserviceexporter"</code><code>&gt;</code>

<code>        </code><code>&lt;!-- rmi服務名稱,可自定義服務名稱 --&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"servicename"</code> <code>value</code><code>=</code><code>"messageservice"</code> <code>/&gt;</code>

<code>        </code><code>&lt;!-- 導出實體 --&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"service"</code> <code>ref</code><code>=</code><code>"messageservice"</code> <code>/&gt;</code>

<code>        </code><code>&lt;!-- 導出接口 --&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"serviceinterface"</code> <code>value</code><code>=</code><code>"org.thera.rmi.service.messageprovider"</code> <code>/&gt;</code>

<code>        </code><code>&lt;!-- spring預設使用1099端口 --&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"registryport"</code> <code>value</code><code>=</code><code>"1199"</code> <code>/&gt;</code>

<code>    </code><code>&lt;/</code><code>bean</code><code>&gt;</code>

<code>&lt;/</code><code>beans</code><code>&gt;</code>

(4) 加載spring容器,釋出rmi服務(main.java):

<code>package</code> <code>org.thera.rmi.service.main;</code>

<code>import</code> <code>org.springframework.context.applicationcontext;</code>

<code>import</code> <code>org.springframework.context.support.filesystemxmlapplicationcontext;</code>

<code>public</code> <code>class</code> <code>main {</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>

<code>        </code><code>applicationcontext ctx = </code><code>new</code> <code>filesystemxmlapplicationcontext(</code><code>"conf/context.xml"</code><code>);</code>

<code>        </code><code>system.out.println(</code><code>"已成功釋出rmi服務類"</code><code>);</code>

    到這裡,rmi的服務端已經釋出成功,運作結果如下截圖:

spring mvc 實作遠端服務調用的幾種方式

spring中用戶端調用rmi服務(zlv_rmiclientwithspring):

(1) 移植服務端服務接口檔案messageprovider.java;

(2) spring配置檔案做如下配置:

<code>    </code><code>&lt;</code><code>bean</code> <code>id</code><code>=</code><code>"messageservice"</code> <code>class</code><code>=</code><code>"org.springframework.remoting.rmi.rmiproxyfactorybean"</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"serviceurl"</code> <code>value</code><code>=</code><code>"rmi://192.168.1.100:1199/messageservice"</code> <code>/&gt;</code>

(3) 加載spring容器,調用rmi服務端(main.java):

<code>import</code> <code>org.thera.rmi.service.messageprovider;</code>

<code>        </code><code>system.out.println(</code><code>"加載spring容器,并初始化rmi用戶端"</code><code>);</code>

<code>        </code><code>messageprovider client = (messageprovider)ctx.getbean(</code><code>"messageservice"</code><code>);</code>

<code>        </code><code>string temp = client.queryformessage(</code><code>"lvsantorini"</code><code>);</code>

<code>        </code> 

<code>        </code><code>system.out.println(</code><code>"傳回結果: "</code> <code>+ temp);</code>

運作main.java,結果如下圖:

spring mvc 實作遠端服務調用的幾種方式

四種方式總結

1. spring remote service overview

rpc調用類似于調用本地對象的方法,都是同步的操作,調用代碼将被阻塞,直到被調用過程完成為止。

本地調用就是execute process在同一個應用的兩個代碼塊中交換。rpc就是execute

process從一個應用通過網絡傳遞給另外一個應用。

spring remoteservice支援這幾種模式:rmi, hessian, burlap, http invoker和jax-rpc。

在server端,spring可以通過相應的remoteexporter将一個bean的釋出成一個remote

service。

2. rmi in spring

rmi缺點:rmi在有防火牆的環境下運作會有困難,而且rmi要求用戶端和伺服器端都必須用java編寫。

3.  hessian和burlap

hession和burlap都是caucho technology的架構,基于http的輕量級remote

hessian使用binary消息來建立用戶端和伺服器端之間的交流,因為基于binary是以對通迅帶寬的占用小。是以不依賴于語言可以被java之外的語言所用。

burlap是基于xml的技術,消息可讀性比較好,而且burlap相比其他基于xml的技術比如soap來說,burlap的消息結構比較簡單,不需要wsdl之類的東西額外定義。

使用hessian(用戶端代碼)

和rmi類似,spring使用hessianproxyfactorybean來建立一個指向hessian服務的proxy。

由此可見,當使用spring時,可以很簡單的在各種spring所支援的remote技術之間切換,而僅僅需要更改很少的配置。

輸出hessian服務

使用hessianserviceexporter

将pojo的public方法公開成hessian服務。hessianserviceexporter是一個spring

mvc controller,接收hessian的請求然後翻譯成對pojo的方法調用。

輸出burlap服務

burlap服務的輸出幾乎和hessian是一樣的,不同的地方就是使用org.springframework.remoting.caucho.burlapserviceexporter。也需要為它配置url

handler和dispatcherservlet。

4. http invoker

rmi使用java标準的序列化機制,但是很難穿過防火牆;hessian/burlap能穿越防火牆但是使用自己私有的一套系列化機制。

是以http invoker應運而生,使用http協定能通過防火牆,并且使用java序列化機制。

使用http invoker

和rmi,hessian等相同,http invoker也是通過httpinvokerproxyfactorybean。

輸出http invoker服務

和hessian相同,不同的地方就是使用org.springframework.remoting.httpinvoder.httpinvokerserviceexporter。也需要為它配置url

http invoder的限制就是用戶端和伺服器端必須使用spring。