1. 程式人生 > >使用Spring進行遠端訪問與Web服務

使用Spring進行遠端訪問與Web服務

Chapter 17. 使用Spring進行遠端訪問與Web服務

17.1. 簡介

Spring為各種遠端訪問技術的整合提供了工具類。Spring遠端支援是由普通(SpringPOJO實現的,這使得開發具有遠端訪問功能的服務變得相當容易。目前,Spring支援四種遠端技術:

  • 遠端方法呼叫(RMI。通過使用 RmiProxyFactoryBean RmiServiceExporterSpring同時支援傳統的RMI(使用java.rmi.Remote介面和java.rmi.RemoteException)和通過RMI呼叫器實現的透明遠端呼叫(支援任何Java介面)。
  • Spring
    HTTP呼叫器Spring提供了一種特殊的允許通過HTTP進行Java序列化的遠端呼叫策略,支援任意Java介面(就像RMI呼叫器)。相對應的支援類是 HttpInvokerProxyFactoryBean HttpInvokerServiceExporter
  • Hessian。通過 HessianProxyFactoryBean HessianServiceExporter,可以使用Caucho提供的基於HTTP的輕量級二進位制協議來透明地暴露服務。
  • Burlap BurlapCaucho的另外一個子專案,可以作為Hessian基於XML的替代方案。Spring
    提供了諸如 BurlapProxyFactoryBean BurlapServiceExporter 的支援類。
  • JAX RPCSpring通過JAX-RPC為遠端Web服務提供支援。
  • JMS(待實現)

在討論Spring對遠端訪問的支援時,我們將使用下面的域模型和對應的服務:

// Account domain object

public class Account implements Serializable{

private String name;

public String getName();

public void setName(String name) {

this.name = name;

}

}

// Account service

public interface AccountService {

public void insertAccount(Account acc);

public List getAccounts(String name);

}

// Remote Account service

public interface RemoteAccountService extends Remote {

public void insertAccount(Account acc) throws RemoteException;

public List getAccounts(String name) throws RemoteException;

}

// ... and corresponding implement doing nothing at the moment

public class AccountServiceImpl implements AccountService {

public void insertAccount(Account acc) {

// do something

}

public List getAccounts(String name) {

// do something

}

}

我們將從使用RMI把服務暴露給遠端客戶端開始並探討使用RMI的一些缺點。然後我們將演示一個使用Hessian的例子。

17.2. 使用RMI暴露服務

使 用SpringRMI支援,你可以通過RMI基礎設施透明的暴露你的服務。設定好SpringRMI支援後,你會看到一個和遠端EJB介面類似的配 置,只是沒有對安全上下文傳遞和遠端事務傳遞的標準支援。當使用RMI呼叫器時,Spring對這些額外的呼叫上下文提供了鉤子,你可以在此插入安全框架 或者定製的安全證書。

17.2.1使用 RmiServiceExporter暴露服務

使用 RmiServiceExporter,我們可以把AccountService物件的介面暴露成RMI物件。可以使用 RmiProxyFactoryBean 或者在傳統RMI服務中使用普通RMI來訪問該介面。RmiServiceExporter 顯式地支援使用RMI呼叫器暴露任何非RMI的服務。

當然,我們首先需要在Spring BeanFactory中設定我們的服務:

<bean id="accountService" class="example.AccountServiceImpl">

<!-- any additional properties, maybe a DAO? -->

</bean>

然後,我們將使用 RmiServiceExporter 來暴露我們的服務:

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">

<!-- does not necessarily have to be the same name as the bean to be exported -->

<property name="serviceName" value="AccountService"/>

<property name="service" ref="accountService"/>

<property name="serviceInterface" value="example.AccountService"/>

<!-- defaults to 1099 -->

<property name="registryPort" value="1199"/>

</bean>

正如你所見,我們覆蓋了RMI註冊的埠號。通常,你的應用服務也會維護RMI註冊,最好不要和它衝突。更進一步來說,服務名是用來繫結下面的服務的。所以本例中,服務繫結在 rmi://HOST:1199/AccountService。在客戶端我們將使用這個URL來連結到服務。

注意:我們省略了一個屬性,就是 servicePort 屬性,它的預設值為0。 這表示在服務通訊時使用匿名埠。當然如果你願意的話,也可以指定一個不同的埠。

17.2.2在客戶端連結服務

我們的客戶端是一個使用AccountService來管理account的簡單物件:

public class SimpleObject {

private AccountService accountService;

public void setAccountService(AccountService accountService) {

this.accountService = accountService;

}

}

為了把服務連線到客戶端上,我們將建立另一個單獨的bean工廠,它包含這個簡單物件和服務連結配置位:

<bean class="example.SimpleObject">

<property name="accountService" ref="accountService"/>

</bean>

<bean id="accountService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">

<property name="serviceUrl" value="rmi://HOST:1199/AccountService"/>

<property name="serviceInterface" value="example.AccountService"/>

</bean>

這就是我們在客戶端為支援遠端account服務所需要做的。Spring將透明的建立一個呼叫器並且通過RmiServiceExporter使得account服務支援遠端服務。在客戶端,我們用RmiProxyFactoryBean連線它。

17.3. 使用Hessian或者Burlap通過HTTP遠端呼叫服務

Hessian提供一種基於HTTP的二進位制遠端協議。它是由Caucho建立的,可以在 找到更多有關Hessian的資訊。

17.3.1Hessian配置DispatcherServlet

Hessian使用一個特定的Servlet通過HTTP進行通訊。使用SpringDispatcherServlet,可以很容易的配置這樣一個 Servlet來暴露你的服務。首先我們要在你的應用裡建立一個新的Servlet(下面來自web.xml檔案):

<servlet>

<servlet-name>remoting</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>remoting</servlet-name>

<url-pattern>/remoting/*</url-pattern>

</servlet-mapping>

你可能對SpringDispatcherServlet很熟悉,這樣你就知道,需要在 WEB-INF 目錄裡建立一個名為 remoting-servlet.xml(在你的servlet名後)的應用上下文。這個應用上下文將在下一節中裡使用。

17.3.2使用HessianServiceExporter暴露你的bean

在新建立的 remoting-servlet.xml 應用上下文裡,我們將建立一個HessianServiceExporter來暴露你的服務:

<bean id="accountService" class="example.AccountServiceImpl">

<!-- any additional properties, maybe a DAO? -->

</bean>

<bean name="/AccountService" class="org.springframework.remoting.caucho.HessianServiceExporter">

<property name="service" ref="accountService"/>

<property name="serviceInterface" value="example.AccountService"/>

</bean>

現在,我們準備在客戶端連線服務了。不必顯示指定處理器的對映,只要使用BeanNameUrlHandlerMappingURL請求對映到服務上:所以,這個服務將在由bean名稱指明的URL http://HOST:8080/remoting/AccountService 位置進行暴露。

17.3.3客戶端連線服務

使用 HessianProxyFactoryBean,我們可以在客戶端連線服務。同樣的方式對RMI示例也適用。我們將建立一個單獨的bean工廠或者應用上下文,而後簡單地指明下面的bean SimpleObject將使用AccountService來管理accounts

<bean class="example.SimpleObject">

<property name="accountService" ref="accountService"/>

</bean>

<bean id="accountService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">

<property name="serviceUrl" value="http://remotehost:8080/AccountService"/>

<property name="serviceInterface" value="example.AccountService"/>

</bean>

這就是所有要做的。

17.3.4使用Burlap

我們在這裡將不去仔細討論Burlap,它是一個基於XMLHessian替代方案。它的配置方法和上述Hessian的一樣。只要把 Hessian 換成 Burlap 就行了。

17.3.5對通過HessianBurlap暴露的服務使用HTTP基礎認證

HessianBurlap的一個優勢是我們可以容易的使用HTTP基礎認證,因為他們二者都是基於HTTP的。例如,普通HTTP Server安全機制可以通過使用 web.xml 安全特徵來應用。通常,你不會為每個使用者都建立不同的安全證書,而是在Hessian/BurlapProxyFactoryBean級別共享安全證書(類似一個JDBC資料來源)。

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">

<property name="interceptors">

<list>

<ref bean="authorizationInterceptor"/>

</list>

</property>

</bean>

<bean id="authorizationInterceptor"

class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor">

<property name="authorizedRoles">

<list>

<value>administrator</value>

<value>operator</value>

</list>

</property>

</bean>

這個例子裡我們顯式使用了BeanNameUrlHandlerMapping,並設定了一個攔截器,後者將只允許管理員和操作員呼叫這個應用上下文中提及的bean

注意:當然,這個例子沒有演示靈活的安全設施。考慮更多有關安全的問題時,請參閱 處的Acegi Security System for Spring

17.4. 使用HTTP呼叫器暴露服務

和使用自身序列化機制的輕量級協議BurlapHessian相反,Spring HTTP呼叫器使用標準Java序列化機制來通過HTTP暴露業務。如果你的引數或返回值是複雜型別,並且不能通過HessianBurlap的序列化 機制進行序列化,HTTP呼叫器就很有優勢(參閱下一節,選擇遠端技術時的考慮)。

實際上,Spring可以使用J2SE提供的標準功能或CommonsHttpClient來實現HTTP呼叫。如果你需要更先進,更容易使用的功能,就使用後者。你可以參考 。

17.4.1暴露服務物件

為服務物件設定HTTP呼叫器和你在HessianBurlap中使用的方式類似。就象為Hessian支援提供的 HessianServiceExporterSpringHTTP呼叫器提供了 org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter。為了暴露 AccountService(上述的),使用下面的配置:

<bean name="/AccountService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">

<property name="service" ref="accountService"/>

<property name="serviceInterface" value="example.AccountService"/>

</bean>

17.4.2在客戶端連線服務

同樣,從客戶端連線業務與你使用HessianBurlap時所做的很相似。使用代理,Spring可以將你呼叫的HTTP POST請求轉換成被暴露服務的URL

<bean id="httpInvokerProxy" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">

<property name="serviceUrl" value="http://remotehost:8080/AccountService"/>

<property name="serviceInterface" value="example.AccountService"/>

</bean>

就象上面說的一樣,你可以選擇使用你想使用的HTTP客戶端。預設情況下,HttpInvokerPropxy使用J2SEHTTP功能,但是你也可以通過設定httpInvokerRequestExecutor屬性選擇使用Commons HttpClient

<property name="httpInvokerRequestExecutor">

<bean class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor"/>

</property>

17.5. Web服務

Spring支援:

  • 使用JAX-RPC暴露服務
  • 訪問Web服務

除了上面所說的支援方法,你還可以用來暴露你的服務。XFire是一個輕量級的SOAP庫,目前在Codehaus開發。

17.5.1使用JAXI-RPC暴露服務

SpringJAX-RPC Servlet的端點實現有個方便的基類 - ServletEndpointSupport。為暴露我們的Account服務,我們繼承了SpringServletEndpointSupport類來實現業務邏輯,這裡通常把呼叫委託給業務層。

/**

* JAX-RPC compliant RemoteAccountService implementation that simply delegates

* to the AccountService implementation in the root web application context.

*

* This wrapper class is necessary because JAX-RPC requires working with

* RMI interfaces. If an existing service needs to be exported, a wrapper that

* extends ServletEndpointSupport for simple application context access is

* the simplest JAX-RPC compliant way.

*

* This is the class registered with the server-side JAX-RPC implementation.

* In the case of Axis, this happens in "server-config.wsdd" respectively via

* deployment calls. The Web Service tool manages the life-cycle of instances

* of this class: A Spring application context can just be accessed here.

*/

public class AccountServiceEndpoint extends ServletEndpointSupport implements RemoteAccountService {

private AccountService biz;

protected void onInit() {

this.biz = (AccountService) getWebApplicationContext().getBean("accountService");

}

public void insertAccount(Account acc) throws RemoteException {

biz.insertAccount(acc);

}

public Account[] getAccounts(String name) throws RemoteException {

return biz.getAccounts(name);

}

}

AccountServletEndpoint需要在Spring中同一個上下文的web應用裡執行,以獲得對Spring的訪問能力。如果使用 Axis,把Axis的定義複製到你的web.xml中,並且在"server-config.wsdd"中設定端點(或使用釋出工具)。參看 JPetStore這個例子中OrderService是如何用Axis釋出成一個Web服務的。

17.5.2訪問Web服務

Spring有兩個工廠bean用來建立Web服務代理,LocalJaxRpcServiceFactoryBean JaxRpcPortProxyFactoryBean。 前者只返回一個JAX-RPT服務類供我們使用。後者是一個全功能的版本,可以返回一個實現我們業務服務介面的代理。本例中,我們使用後者來為前面段落中 暴露的AccountService端點建立一個代理。你將看到SpringWeb服務提供了極好的支援,只需要很少的程式碼 - 大多數都是通過類似下面的Spring配置檔案:

<bean id="accountWebService" class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean">

<property name="serviceInterface" value="example.RemoteAccountService"/>

<property name="wsdlDocumentUrl" value="http://localhost:8080/account/services/accountService?WSDL"/>

<property name="namespaceUri" value="http://localhost:8080/account/services/accountService"/>

<property name="serviceName" value="AccountService"/>

<property name="portName" value="AccountPort"/>

</bean>

serviceInterface 是客戶端將要使用的遠端業務介面。wsdlDocumentUrl WSDL檔案的URLSpring需要這些在啟動時建立JAX-RPC服務。namespaceUri 對應到.wsdl檔案中的targetNamespaceserviceName 對應到.wsdl檔案中的service nameportName 對應到.wsdl檔案中的埠號。

現在bean工廠將把Web服務暴露為 RemoteAccountService 介面,訪問服務變得很容易。我們可以在Spring中這樣組裝起來:

<bean id="client" class="example.AccountClientImpl">

...

<property name="service" ref="accountWebService"/>

</bean>

在客戶端我們可以使用類似於普通類的方式來訪問Web服務,區別是它丟擲RemoteException異常。

public class AccountClientImpl {

private RemoteAccountService service;

public void setService(RemoteAccountService service) {

this.service = service;

}

public void foo() {

try {

service.insertAccount(...);

} catch (RemoteException ex) {

// ouch

...

}

}

}

由於Spring提供了自動轉換成非受控異常的能力,我們可以不用考慮受控的RemoteException異常。這要求我們也提供一個非RMI介面,配置檔案現在如下:

<bean id="accountWebService" class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean">

<property name="serviceInterface">

<value>example.AccountService</value>

</property>

<property name="portInterface">

<value>example.RemoteAccountService</value>

</property>

...

</bean>

這裡 serviceInterface 已經改成我們目前的非RMI介面。我們的RMI介面現在使用屬性 portInterface 進行定義。現在客戶端程式碼可以不用處理 java.rmi.RemoteException 異常:

public class AccountClientImpl {

private AccountService service;

public void setService(AccountService service) {

this.service = service;

}

public void foo() {

service.insertAccount(...);

}

}

17.5.3註冊bean對映

為了傳遞類似Account等複雜物件,我們必須在客戶端註冊bean對映。

Note

在伺服器端通常在server-config.wsdd中使用Axis進行bean對映註冊。

我們將使用Axis在客戶端註冊bean對映。為此,我們需要繼承一個Spring Bean工廠並通過程式設計註冊這個bean對映。

public class AxisPortProxyFactoryBean extends JaxRpcPortProxyFactoryBean {

protected void postProcessJaxRpcService(Service service) {

TypeMappingRegistry registry = service.getTypeMappingRegistry();

TypeMapping mapping = registry.createTypeMapping();

registerBeanMapping(mapping, Account.class, "Account");

registry.register("http://schemas.xmlsoap.org/soap/encoding/", mapping);

}

protected void registerBeanMapping(TypeMapping mapping, Class type, String name) {

相關推薦

使用Spring進行遠端訪問Web服務

Chapter 17. 使用Spring進行遠端訪問與Web服務 17.1. 簡介 Spring為各種遠端訪問技術的整合提供了工具類。Spring遠端支援是由普通(Spring)POJO實現的,這使得開發具有遠端訪問功能的服務變得相當容易。目前,Spring支援四種遠端技術:

一個c#的web服務器交互的HttpClient類

指示 all 斷點續傳 www. mod bytearray dex ron 發出 using System;using System.Collections.Generic;using System.IO;using System.Text;using System.Ne

負載均衡web服務集群搭建

linux主機名ip地址角色viplvs01192.168.1.904層負載192.168.1.206lvs02192.168.1.914層負載192.168.1.206lb01192.168.1.57層負載lb02 192.168.1.67層負載web-nginx01 172.16.1.33靜態服務器web

三、負載均衡web服務集群搭建

spa 編譯安裝 特點 ont tables 1.7 常用 標準 靜態 一、負載均衡LVS基本介紹 LB集群的架構和原理很簡單,就是當用戶的請求過來時,會直接分發到Director Server上,然後它把用戶的請求根據設置好的調度算法,智能均衡地分發到後端真正服務器

SpringBoot實戰(十)之使用Spring Boot Actuator構建RESTful Web服務

context prope group -m ans ger config server mls 一、導入依賴 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.a

請教利用fegin進行遠端訪問設定Hystrix熔斷器不生效

本人的環境:1.基於spring boot 2.0.4的 spring cloud(Finchley.SR1)2.分為eureka,merber,order。order通過Fegin的方式呼叫merber的一個方法困惑:遠端呼叫 利用註解@HystrixCommand的方式熔斷器可以起作用, 但是利用這

Spring 實現遠端訪問詳解——rmi

一.  緒論 Spring為各種遠端訪問技術提供整合工具類。Spring遠端訪問通過使用普通POJOs,能更容易的開發遠端訪問服務。目前,Spring遠端訪問的主要技術如下: 1.      遠端呼叫

Angular 4.3 HttpClient (Angular訪問 REST Web 服務) 一、Http 請求示例(Get)

連結 開發工具:Visual Studio Code 在Angular 4.3中引入了新的HttpClientModule。 這個新模組可以在@ angular / common / http包中找到,並且可以完全重新實現前一個HttpModule。新的Ht

引用第三方進行Android前端web後臺的資料互動

1.首先你需要匯入jar包,如圖: 2.然後把jar包放入Project(Android) 3.注意:useLibrary 'org.apache.http.legacy'這句話需要放入Projec

Linux伺服器使用二:VMWare下設定網路連線並使用SSH2進行遠端訪問

在上一章中我們講完了如何在VMWare中安裝CentOS,在本章中就主要來描述完成CentOS的網路訪問以及使用SSH2進行遠端訪問。 1、設定CentOS上網 1)檢查虛擬機器設定 2)檢視物理機的ip、閘道器以及子網掩碼 3)進入li

711 無法載入遠端訪問連線管理服務 Remote Access connection Manager 126 找不到指定的模組

寬頻連接出現錯誤:711 無法載入遠端訪問連線管理服務或者  “Remote Access connection Manager  126 找不到指定的模組 ” 這種情況有可能是服務沒點開,或者有可能是因為被病毒損壞檔案。 先確保Remote Access conne

Gradle+Spring Boot+Git+Docker構建web服務

上週是到公司實習的第一週,在之後的工作中要用到Spring Boot,Git以及Docker等,就以一個簡單的小專案為例學習了一下,現在做一個總結記錄。 Gradle 在之前的學習中用過maven作為構建工具,這裡選擇使用了Gradle。 我使用的ID

linux-windows 通過SecureCRT進行遠端訪問和檔案(包含資料夾)傳輸

檔案傳輸 使用SecureCRT自帶的SFTP連線: securecrt 按下ALT+P就開啟新的會話 進行ftp操作。   輸入:help命令,顯示該FTP提供所有的命令   pwd:  查詢Linux主機所在目錄(也就是遠端主機目錄)   lpwd: 查詢本

Web服務器之Tomcat的相關說明(Web訪問中的角色協議問題和JavaWeb項目的程序結構問題)

b/s架構 c/s架構 context.xml說明 server.xml說明 javaweb項目的程序結構 1、C/S架構和B/S架構的概念:a、C/S架構:- C/S,Client/Server,客戶端/服務器,客戶端需要安裝專用的客戶端軟件。客戶端是針對某以具體業務專門開發的軟件。-

遠端伺服器中flask的web服務允許被其他機器訪問的解決方法

用百度的pyecharts搭了一個python分析資料顯示圖表的專案,用flask部署web服務。 服務啟動方式用的如下方法: app.run(port=10200) 啟動埠是10200,在本地正常執行,: http://127.0.0.1:10200 但是放到Linux遠端伺服器上後,本地

Spring 5 官方文件》24. 使用Spring提供遠端WEB服務

原文連結 譯者:xiuson 24.1 介紹 Spring提供了使用多種技術實現遠端訪問支援的整合類。遠端訪問支援使得具有遠端訪問功能的服務開發變得相當簡單,而這些服務由普通的 (Spring) POJO實現。目前,Spring支援以下幾種遠端技術: 遠端方法呼叫(RMI)。通過使用RmiP

如何在關閉web服務進行一些清理操作(Spring mvc)

背景 目前正在替一家500強企業開發系統,因為系統眾多所以他們使用ESB對各個系統之間的服務進行管理,同樣也要求我們的系統進行對接。要求在我們的系統啟動時進行註冊,在系統關閉時進行登出。根據要求同事寫了一個serverlet在系統啟動的時候進行註冊操作,但是不知道在系統關閉

web服務啟動spring自己主動運行ApplicationListener的使用方法

addclass tty -m pan pre contex oid his @override 我們知道。一般來說一個項目啟動時須要載入或者運行一些特殊的任務來初始化系統。通常的做法就是用servlet去初始化。可是servlet在使用spring b

Spring mvc創建的web項目,如何獲知其web的項目名稱,訪問具體的鏈接地址?

服務 spa 重新 組織 ngs 分享 per 結構 ava 我們創建的springmvc項目:jstz_random,包名:com.redin.jstz,那麽其web項目的名稱為jstz_random。這個也是我們訪問的連接中的projectname 1、可以通過查看we

基於容器服務架構的Web應用實踐eShopOnContainers

contain 安全 github ima 微服務架構 使用 服務架構 ctu target 微軟官方提供了一個基於Docker和微服務的示例應用eShopOnContainers;它使用了面向服務的架構並且從服務端到客戶端都是跨平臺的;該架構使用通過http作為客戶端與服