Spring 3.0參考手冊之集成Web Service

Part VI

 

19.9 在客戶端訪問RESTFUL服務

RestTemplate是客戶端訪問RESTFUL服務的核心類。它在概念上和SPRING的其它模版類一樣,如JdbcTemplateJmsTemplate一起其它SPRING項目中的模版類。RestTemplate的行爲可以被定製,定製是通過提供的回調方法和配置HttpMessageConverterHttpMessageConverter用來組織對象到HTTP請求體中並且拆開任何響應回到一個對象中。和通常的使用XML作爲消息格式一樣,SPRING提供了一個MarshallingHttpMessageConverter它使用org.springframework.oxm包中的Object-to-XML結構。這個包中提供了很多XML到對象映射技術的選擇。

這節描述怎樣使用RestTemplate和與它相關的HttpMessageConverters類。

RestTemplate

Java中調用RESTFUL服務通常使用一個輔助類如Jakarta Commons中的HttpClient。對於如下所示,通用REST操作這個方法層次較低。

 
 

String uri = "http://example.com/hotels/1/bookings";

PostMethod post = new PostMethod(uri);

String request = // create booking request content

post.setRequestEntity(new StringRequestEntity(request));

httpClient.executeMethod(post);

if (HttpStatus.SC_CREATED == post.getStatusCode()) {

Header location = post.getRequestHeader("Location");

if (location != null) {

System.out.println("Created new booking at :" + location.getValue());

}

}

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

RestTemplate提供比較高層的方法,這些方法對應於HTTP的六個主要方法,它使得調用許多RESTFUL服務只用簡單的一行並增強REST的最佳實踐。

 

19.1 RestTemplate方法一覽

HTTP方法

RestTemplate方法

DELETE

delete(String url, String…urlVariables)

GET

getForObject(String url, Class<T> responseType,String…urlVariables)

HEAD

headForHeaders(String url, String…urlVariables)

OPTIONS

optionsForAllow(String url, String…urlVariables)

POST

postForLocation(String url, Object request,

String…urlVariables)

 

postForObject(String url, Object request,

Class<T> responseType, String…uriVariables)

PUT

put(String url, Object request,

String…urlVariables)

RestTemplate方法的名字遵循一個名字轉換方式,第一列顯示如何調用HTTP方法,第二列顯示返回什麼。例如,getForObject方法將執行一個GET方法,轉換HTTP響應到一個你所選類型的對象並且返回該對象。postForLocation方法將會做一個POST操作,轉換給定的對象到一個HTTP請求並且返回響應新建對象可以找到的HTTP位置頭部。爲了防止處理HTTP請求時產生異常,一個RestClientException類型的異常將會被拋出,這一行爲可以通過插入另一個實現了RestTemplateResponseErrorHandler來改變。

傳遞到這些方法的和從這些方法返回的對象分別通過HttpMessageConverter實例被轉換到HTTP消息和來自HTTP消息。默認註冊了對主要的MIME類型的轉換,但是你同樣可以寫自己的轉換並且通過messageConvertersBEAN屬性註冊它。默認的註冊到模版上的轉換實例是ByteArrayHttpMessageConverterStringHttpMessageConverterFormHttpMessageConverterSourceHttpMessageConverter。如果使用MarshallingHttpMessageConverter時你需要通過使用messageConvertersBEAN屬性來重寫這些默認實例。

每一個方法採用兩種類型的URI模版參數,或者一個字符變長的參數或者是一個Map<String,String>的形式。例如,

String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}",

String.class,"42", "21");

 

 

使用變長參數

Map<String, String> vars = Collections.singletonMap("hotel", "42");

String result =

restTemplate.getForObject("http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);

 

使用Map<String,String>的形式

爲了產生一個RestTemplate的實例你可以簡單地調用默認的構造方法。這些使用來自java.net包的標準JAVA類作爲下面的實現來產生HTTP請求。這可以通過具體實現了ClientHttpRequestFactory的類來覆蓋。SPRING提供了CommonsClientHttpRequestFactory實現它使用Jakarta Commons HttpClient來產生請求。CommonsClientHttpRequestFactory使用一個可以由證書信息或連接池功能來配置的org.apache.commons.httpclient.HttpClient實例來配置。

 

前面使用Jakarta Commons HttpClient的例子可以直接使用RestTemplate來重寫,如下

 

uri = "http://example.com/hotels/{id}/bookings";

RestTemplate template = new RestTemplate();

Booking booking = // create booking object

URI location = template.postForLocation(uri, booking, "1");

通常的回調接口是RequestCallback並且當執行方法被調用時調用。

public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,

ResponseExtractor<T> responseExtractor,

String... urlVariables)

// also has an overload with urlVariables as a Map<String, String>.

RequestCallback被定義如下:

public interface RequestCallback {

void doWithRequest(ClientHttpRequest request) throws IOException;

}

並且允許你操縱請求頭和寫請求體。當使用執行方法時你不必擔心任何的資源管理,模版將會關閉請求和處理錯誤。關於使用執行方法和其它方法參數的意義的更多信息請參考API文檔。

 

HTTP Message Conversion

getForObject, postForLocation, put方法傳入和返回的對象分別通過HttpMessageConverters類被轉換成了HTTP請求和來自HTTP的響應。爲了更好的瞭解它的功能 HttpMessageConverter接口如下所示:

public interface HttpMessageConverter<T> {

// Indicate whether the given class is supported by this converter.

boolean supports(Class<? extends T> clazz);

// Return the list of MediaType objects supported by this converter.

List<MediaType> getSupportedMediaTypes();

// Read an object of the given type form the given input message, and returns it.

T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException,

HttpMessageNotReadableException;

// Write an given object to the given output message.

void write(T t, HttpOutputMessage outputMessage) throws IOException,

HttpMessageNotWritableException;

}

 

框架提供對主要MIME類型的具體實現並且默認通過在客戶端的RestTemplate和在服務器端的AnnotationMethodHandlerAdapter註冊。

下面描述HttpMessageConverters的實現。默認的MIME類型在所有轉換器中使用,但是可以通過設置supportedMediaTypes BEAN屬性來重寫。

StringHttpMessageConverter

一個HttpMessageConverter實現可以從HTTP請求和響應中進行讀和寫字符串。默認,這種轉換支持所有的TEXT類型(text/*),並且寫的Content-Typetext/plain

FormHttpMessageConverter

一個HttpMessageConverter實現可以從HTTP請求和響應中進行讀和寫數據。默認,這種轉換讀和寫application/x-www-form-urlencoded的類型。表單數據讀出和寫入MultiValueMap<String, String>

ByteArrayMessageConverter

一個HttpMessageConverter實現可以從HTTP請求和響應中進行讀和寫字節(byte)數據。默認這種轉換支持所有的類型(*/*)並且寫的Content-Type application/octet-stream。這可以通過設定支持的類型和重寫getContentType(byte[])來覆寫。

MarshallingHttpMessageConverter

一個HttpMessageConverter實現可以使用在org.springframework.oxm包中的SPRING提供的Marshaller Unmarshaller來讀寫XML。這種轉換在它被使用前需要一個Marshaller t  Unmarshaller。這可以通過構造方法或BEAN屬性來被注射實現。默認這種轉換支持(text/xml)(application/xml)

SourceHttpMessageConverter

一個HttpMessageConverter實現可以從HTTP請求和響應來讀寫javax.xml.transform.Source。只有DOMSourceSAXSourceStreamSource被支持。默認,這種轉換支持(text/xml)(application/xml)

BufferedImageHttpMessageConverter

一個HttpMessageConverter實現可以從HTTP請求和響應來讀寫java.awt.image.BufferedImage

這種轉換讀寫的MEDIA類型通過Java I/O API來支持

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章