1. 程式人生 > >Spring實戰筆記:Spring集成

Spring實戰筆記:Spring集成

Spring RPC REST 消息

一.使用遠程服務

遠程調用是客戶端應用和服務端之間的會話。

1.Spring通過多種遠程調用技術支持RPC(remote procedure call,遠程過程調用)

RPC模型使用場景
RMI不考慮網絡限制時(例如防火墻),訪問/發布基於Java的服務
Hessian 或 Burlap考慮網絡限制時,通過HTTP訪問/發布基於Java的服務。Hessian是二進制協議,而Burlap是基於XML的
HTTP invoker考慮網絡限制,並希望使用基於XML或專有的序列化機制實現Java序列化時,訪問/發布基於Spring的服務
JAX-RPC 和 JAX-WS訪問/發布平臺獨立的、基於SOAP的Web服務

遠程服務:

-- RMI:基於Java的遠程方法調用,使用了Java的序列化機制,服務端和客戶端Java版本需要保持一致(http://blog.csdn.net/a19881029/article/details/9465663);

-- Hessian:類似於RMI,都是使用二進制消息進行客戶端和服務端的交互,但Hessian的二進制消息可以移植到其他非Java語言中(PHP、Python、C++、C#);

-- Burlap:基於XML的遠程調用技術,能夠移植到能夠解析XML的語言上,在調試過程中易讀。

Hessian和Burlap是基於HTTP的,解決了RMI的防火墻滲透問題。但是當傳遞過來的RPC消息包含序列化對象時應使用RMI。

-- HTTP invoker:是Spring框架提供的遠程調用解決方案。客戶端和服務端必須是Spring應用,且必須是基於Java的(序列化機制)。

技術分享圖片


-- SOA:面向服務的架構,簡單對象訪問協議是在分散或分布式的環境中交換信息的簡單的協議,是一個基於XML的協議。核心理念是應用程序可以並且應該被設計成依賴一組公共的核心服務,而不是為每個應用都重新實現相同功能。

Spring為使用Java API for XML Web Service(JAX-WS)來發布和使用所支持的SOAP Web服務提供了大力支持。

JAX-WS編程模型使用註解將類和類的方法聲明為Web服務的操作。使用@WebService註解所標註的類被認為Web服務的端點,而使用@WebMethod註解所標註的方法被認為是操作。

https://www.ibm.com/developerworks/cn/xml/x-sisoap/index.html


2.REST

RPC和REST的區別:

-- RPC遠程過程調用是面向服務的,關註於行為和動作;

-- REST是面向資源的,強調描述應用程序的事物和名詞。

REST:

-- 表述性(Representational):REST資源實際上可以用各種形式進行表述,包括XML、JSON、HTML(選擇最適合資源使用者的任意形式);

-- 狀態(State):當使用REST時,我們更關註資源的狀態而不是對資源采取的行為;

-- 轉移(Transfer):REST涉及到轉移資源數據,它以某種表述性形式從一個應用轉移到另一個應用。

即:REST就是將資源的狀態最適合客戶端或服務端的形式從服務器端轉移到客戶端(或者反過來)。

資源在網絡中以某種表現形式進行狀態轉移。

用HTTP協議裏的動詞來實現資源的添加,修改,刪除等操作:

-- GET:用來獲取資源,

-- POST:用來新建資源(也可以用於更新資源),

-- PUT:用來更新資源,

-- DELETE:用來刪除資源。

Spring支持以下方式創建REST:

-- 控制器可以處理所有的HTTP方法,包含四個主要的REST方法:GET、PUT、DELETE、POST,PATCH在Spring 3.2及以上版本中支持。

-- 借助@PathVariable註解,控制器能夠處理參數化的URL(將變量輸入作為URL的一部分);

-- 借助Spring的視圖和視圖解析器,資源能夠以多種方式進行表述,包括將模型數據渲染為XML、JSON、Atom以及RSS的View實現;

-- 可以使用ContentNegotiatingViewResolver來選擇最合適客戶端的表述;

-- 借助@ResponseBody註解和各種HttpMethodConverter實現,能夠替換基於視圖的渲染方式;

-- @RequestBody註解以及HttpMethodConverter實現可以講傳入的HTTP數據轉化為傳入控制器處理方法的Java對象;

-- 借助RestTemplate,Spring應用能夠方便地使用REST資源。

Spring提供了兩種方式將資源的Java轉換為發送給客戶端的表述形式:

-- 內容協商:選擇一個視圖,它能夠將模型渲染為呈現給客戶端的表述形式;

視圖解析器ContentNegotiatingViewResolver和ContentNegotiationManager共同作用。該方法得到的響應是渲染模型:key-value組成的Map,而不是資源,並不是客戶端預期結果。

-- 消息轉換器(HTTP信息轉換器):通過一個消息轉換器將控制器所返回的對象轉換為呈現給客戶端的表述形式。

在響應體返回資源狀態:

正常情況下,方處理方法返回Java對象(除String或View的實現以外)時,這個對象會放在模型中並在視圖中渲染使用。而使用消息轉換功能時,我們需要告訴Spring跳過正常的模型/視圖流程,並使用消息轉換器。最簡單的方法就是為控制器方法添加@ResponseBody註解。

@ResponseBody註解會告訴Spring,我們要將返回的對象作為資源發送給客戶端,並將其轉換為客戶端可以接收的表述形式。

@RequestMapping(method=RequestMethod.GET, produces="application/json")
public @ResponseBody List<Spittle> spittles(
        @RequestParam(value="max", defaultValue=MAX_LONG_AS_STRING) long max,
        @RequestParam(value="count", defaultValue="20") int count) {
    return spittleRepository.findSpittles(max, count);
}

該例中的@RequestMapping註解中使用了produces屬性,表明這個方法只處理預期輸出為JSON的請求。即該方法只處理Accept頭部信息包含"application/json"的請求。其他任何類型的請求,即使他的URL匹配指定的路徑並且是GET請求也不會被這個方法處理。這樣的請求會被其他方法來進行處理(如果存在適當方法的話),或者返回客戶端HTTP 406響應。

在請求體中接收資源狀態:

@ResponseBody能夠告訴Spring在把數據發送給客戶端的時候,要使用一個消息器,類似的,@RequestBody能告訴Spring查找一個消息轉換器。

@RequestMapping(method=RequestMethod.POST, consumes="application/json")         --consumes與produces類似,不過它會關註Content-Type請求的頭部信息
public @ResponseBody List<Spittle> saveSpittle(@RequestBody Spittle spittle) {
    return spittleRepository.save(spittle);
}

@ResponseBody和@RequestBody是啟用消息轉換器的一種簡潔和強大的方式,Spring 4.0中引入@RestController註解,在控制器類上使用@RestController來代替@Controller的話,Spring將會為該控制器的所有處理方法應用消息轉換功能。

發送錯誤信息到客戶端:

Spring提供多種方式處理返回錯誤信息的場景:

-- 使用@ResponseStatus註解可以指定狀態碼;

-- 控制器方法可以返回ResponseEntity對象,該對象能夠包含更多響應相關的元數據;

-- 異常處理器能夠應對錯誤場景,這樣處理器方法就能關註於正常的狀況。

@RequestMapping(value="/{id}", method=RequestMethod.GET)      
public @ResponseEntity<?> spittleById(@PathVariable long id) {
    Spittle spittle = spittleRepository.findOne(id);
    if (spittle == null) {
        Error error = new Error(4, "Spittle [" + id + "] not found");
        return new ResponseEntity<Error>(error, HttpStatus.NOT_FOUND);
    }
    return new ResponseEntity<Error>(spittle, HttpStatus.OK);
}

處理異常:

當拋出指定異常時運行。

@ExceptionHandler(SpittleNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ResponseEntity<Error> spittleNotFound(SpittleNotFoundException e) {
    long spittleId = e.getSpittleId();
    return new Error(4, "Spittle [" + id + "] not found");
}


3.Spring消息

同步通信:客戶端應用程序直接與遠程服務相交互,並且一直等到遠程過程完成後才就像執行。

異步消息:一個應用程序向另一個應用程序間接發送消息的一種方式,無需等待對方的響應。

在Spring中搭建消息代理:

-- 創建連接工廠;

-- 聲明ActiveMQ;

-- 使用Spring的JMS模板。


Spring實戰筆記:Spring集成