1. 程式人生 > 其它 >rmi遠端呼叫被拒絕_Spring 5.2.2 技術的整合—RMI、Hessian

rmi遠端呼叫被拒絕_Spring 5.2.2 技術的整合—RMI、Hessian

技術標籤:rmi遠端呼叫被拒絕

接下來一段時間介紹了Spring框架與許多javaEE(及相關)技術的整合。首先從遠端WEB服務開始介紹。Spring使用各種技術為遠端處理提供支援。遠端處理簡化了遠端支援服務的開發,通過Java介面和物件作為輸入和輸出實現。目前,Spring支援以下遠端處理技術:

  • 遠端方法呼叫(Remote Method Invocation,RMI):通過使用RmiProxyFactoryBean和RmiServiceExporter,Spring支援傳統的RMI(使用java.rmi.Remote介面和java.rmi.RemoteException)以及通過RMI呼叫器(使用任何Java介面)進行透明遠端處理。

  • Spring HTTP Invoker:Spring提供了一種特殊的遠端處理策略,允許通過HTTP進行Java序列化,支援任何Java介面(就像RMI呼叫器那樣)。相應的支援類是HttpInvokerProxyFactoryBean和HttpInvokerServiceExporter。

  • Hessian:通過使用Spring的HessianProxyFactoryBean和HessianServiceExporter,可以通過Caucho提供的基於HTTP的輕量級二進位制協議透明地公開你的服務。

  • JavaWeb服務:Spring通過JAX-WS為Web服務提供遠端處理支援。

  • JMS:spring-jms模組中的JmsInvokerServiceExporter

    JmsInvokerProxyFactoryBean類支援通過JMS作為底層協議進行遠端處理。

  • AMQP:通過AMQP作為底層協議的遠端處理由單獨的Spring AMQP專案支援。

在介紹Spring的遠端處理功能時,我們使用以下域模型和相應的服務:

public class Account implements Serializable{    private String name;    public String getName(){        return name;    }    public void setName(String name) {        this.name = name;    }}public interface AccountService {    public void insertAccount(Account account);    public ListgetAccounts(String name);}//實現程式目前什麼也不做public class AccountServiceImpl implements AccountService {    public void insertAccount(Account acc) {        //處理業務...    }    public ListgetAccounts(String name) {//處理業務...    }}

從使用RMI向遠端客戶端公開服務開始,並討論使用RMI的缺點。然後以一個使用Hessian作為協議的示例繼續。

1、RMI

通過使用Spring對RMI的支援,你可以通過RMI透明地公開你的服務。設定完成後,你基本上擁有一個類似於遠端EJB的配置,除了沒有對安全上下文傳播或遠端事務傳播的標準支援。當你使用RMI呼叫器時,Spring確實為這種額外的呼叫上下文提供了銜接,因此你可以(例如)插入安全框架或自定義安全憑證。

1.1、使用RmiServiceExporter暴露服務

使用RmiServiceExporter,我們可以將AccountService物件的介面公開為RMI物件。介面可以通過使用RmiProxyFactoryBean訪問,或者在傳統RMI服務的情況下通過普通RMI訪問。RmiServiceExporter明確支援通過RMI呼叫器公開任何非RMI服務。

我們首先要在Spring容器中設定服務。下面的示例演示如何執行此操作:

"accountService" bean>

接下來,我們必須使用RmiServiceExporter公開我們的服務。下面的示例演示如何執行此操作:

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">    <property name="serviceName" value="AccountService"/>    <property name="service" ref="accountService"/>    <property name="serviceInterface" value="example.AccountService"/>        <property name="registryPort" value="1199"/>bean>

在前面的示例中,我們覆蓋RMI登錄檔的埠。通常,你的應用程式伺服器還維護一個RMI登錄檔,最好不要干擾它。此外,服務名稱用於繫結服務。因此,在前面的示例中,服務被繫結到'rmi://HOST:1199/AccountService'。我們稍後使用這個URL在客戶端連結服務。

servicePort屬性已被省略(預設為0)。這意味著使用匿名埠與服務通訊。

1.2、在客戶端連線服務

我們的客戶端是一個簡單的物件,它使用AccountService來管理帳戶,如下例所示:

public class SimpleObject {    private AccountService accountService;    public void setAccountService(AccountService accountService) {        this.accountService = accountService;    }    // 使用accountService的其他方法}

為了在客戶端上鍊接服務,我們建立一個單獨的Spring容器,以包含以下簡單物件和服務連結配置節點:

class=    <property name="accountService" ref="accountService"/>bean>"accountService"     <property name="serviceUrl" value="rmi://HOST:1199/AccountService"/>    <property name="serviceInterface" value="example.AccountService"/>bean>

這就是我們需要做的,以支援客戶端上的遠端帳戶服務。Spring透明地建立一個呼叫器,並通過RmiServiceExporter遠端啟用帳戶服務。在客戶端,我們使用RmiProxyFactoryBean將其連結起來。

2、使用Hessian通過HTTP遠端呼叫服務

Hessian提供了一個基於HTTP的二進位制遠端處理協議。它是由Caucho開發的,你可以在https://www.caucho.com/進行進一步瞭解。

2.1、Hessian

Hessian通過HTTP進行通訊,並使用一個定製的servlet進行通訊。通過使用Spring的DispatcherServlet原則,我們可以連線這樣一個servlet來公開你的服務。首先,我們必須在應用程式中建立一個新的servlet,如下面的web.xml檔案:

<servlet>    <servlet-name>remotingservlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>    <load-on-startup>1load-on-startup>servlet><servlet-mapping>    <servlet-name>remotingservlet-name>    <url-pattern>/remoting/*url-pattern>servlet-mapping>

如果你熟悉Spring的DispatcherServlet原則,那麼你可能知道現在必須建立一個名為remoting的Spring容器配置remoting-servlet.xml在WEB-INF目錄中。下一步將使用應用程式上下文。

或者,考慮使用Spring更簡單的HttpRequestHandlerServlet。這樣可以將遠端暴露定義嵌入根應用程式上下文(預設情況下,在WEB-INF/applicationContext.xml),單個servlet定義指向特定的暴露的bean。在本例中,每個servlet名稱都需要與其目標暴露的bean名稱相匹配。

2.2、使用HessianServiceExporter暴露您的bean

在新建立的名為遠端處理的應用程式上下文中remoting-servlet.xml,我們建立一個HessianServiceExporter來暴露我們的服務,如下例所示:

"accountService" bean>"/AccountService"     <property name="service" ref="accountService"/>    <property name="serviceInterface" value="example.AccountService"/>bean>

現在我們已經準備好在客戶端連線服務了。沒有明確指定的處理程式對映(將請求url對映到服務上),所以我們使用BeanNameUrlHandlerMapping。因此,服務在包含DispatcherServlet例項的對映(如前所定義)中的bean名稱所指示的URL處暴露:https://HOST:8080/remoting/AccountService。

或者,你可以在根應用程式上下文中(例如,在WEB-INF/applicationContext.xml中)建立HessianServiceExporter的應用程式上下文,如下例所示:

"accountExporter"     <property name="service" ref="accountService"/>    <property name="serviceInterface" value="example.AccountService"/>bean>

在後一種情況下,你應該在web.xml檔案,最終結果相同:暴露服務被對映到位於/remoting/AccountService的請求路徑。請注意,servlet名稱需要與目標匯出器的bean名稱匹配。下面的示例演示如何執行此操作:

<servlet>    <servlet-name>accountExporterservlet-name>    <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServletservlet-class>servlet><servlet-mapping>    <servlet-name>accountExporterservlet-name>    <url-pattern>/remoting/AccountServiceurl-pattern>servlet-mapping>

3、在客戶端的服務中連結

通過使用HessianProxyFactoryBean,我們可以在客戶端連結服務。同樣的原則適用於RMI示例。我們提到使用以下示例建立一個單獨的AccountServiceSimpleObject,其中使用AccountBean管理以下例項:

class=    <property name="accountService" ref="accountService"/>bean>"accountService"     <property name="serviceUrl" value="https://remotehost:8080/remoting/AccountService"/>    <property name="serviceInterface" value="example.AccountService"/>bean>

4、對通過Hessian公開的服務應用HTTP基本身份驗證

Hessian的一個優點是我們可以很容易地應用HTTP基本身份驗證,因為這兩個協議都是基於HTTP的。常規HTTP伺服器安全機制可以通過使用web.xml檔案例如,安全功能。通常,您不需要在這裡使用每使用者安全憑據。相反,您可以使用在HessianProxyFactoryBean級別定義的共享憑據(類似於JDBCDataSource),如下例所示:

class=    <property name="interceptors" ref="authorizationInterceptor"/>bean>"authorizationInterceptor"        class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor">    <property name="authorizedRoles" value="administrator,operator"/>bean>

在前面的示例中,我們顯式地提到了BeanNameUrlHandlerMapping對映,並設定了一個攔截器,以便僅允許管理員和操作員呼叫此應用程式上下文中提到的bean。

前面的例子沒有展示一種靈活的安全基礎設施。有關安全性的更多配置,請檢視Spring Security專案。

歡迎關注和轉發Spring中文社群(加微信群,可以關注後加我微信):

34ec1c92e067b58592155acf36ef7407.png