Spring之在用戶端訪問RESTful業務

來源:互聯網
上載者:User

標籤:

Spring之在用戶端訪問RESTful業務 

RestTemplate 是用戶端訪問RESTful業務的核心類。在概念上與Spring其他的模板類相似,比如JdbcTemplate和JmsTemplate。RestTemplate的行為是可以定製的,通過提供回調方法和配置HttpMessageConverter(用於將對象打包到HTTP請求體中並從返回的響應中解壓為一個對象)。由於一般使用XML作為訊息格式,Spring提供了MarshallingHttpMessageConverter 使用對象到XML的架構,這是org.springframework.oxm包的一部分。這個給你了將XML映射為對象,提供了寬泛的選擇。

 

這節描述了如何使用RestTemplate和其關聯的HttpMessageConverters。

 

21.10.1 RestTemplate

Java中調用RESTful業務,一般使用一個輔助類,比如Apache的HttpComponents  HttpClient。對於普通的REST操作,這種方式是非常低級的。

[java] view plaincopy 
  1. String uri = "http://example.com/hotels/1/bookings";  
  2.   
  3. PostMethod post = new PostMethod(uri);  
  4. String request = // create booking request content  
  5. post.setRequestEntity(new StringRequestEntity(request));  
  6.   
  7. httpClient.executeMethod(post);  
  8.   
  9. if (HttpStatus.SC_CREATED == post.getStatusCode()) {  
  10.     Header location = post.getRequestHeader("Location");  
  11.     if (location != null) {  
  12.         System.out.println("Created new booking at :" + location.getValue());  
  13.     }  
  14. }  

 

 

RestTemplate提供了進階方法,對應著六個主要的HTTP方法,使得在一行中調用RESTful業務並執行REST最好的實踐。

 

注意:RestTemplate還有一個非同步部分。

 

RestTemplate 方法回顧表

HTTP方法         RestTemplate方法

DELETE           delete

GET              getForObjectgetForEntity

HEAD             headForHeaders(String url,String。。。urlVariables)

OPTIONS          optionsForAllow(String url,String。。。urlVariables)

POST             postForLocation(String url,Object request,String。。。urlVariables)  postForObeject(String url,Object    request,Class<T> responseType,String...uriVariables)

PUT              put(String url,Object reuqest,String...urlVariables)

PATCH and others  exchange execute

 

RestTemplate方法的名字遵循一個命名規範,第一部分指定了調用什麼HTTP方法,第二部分指明了傳回值。例如,getForObject()方法執行一個GET,並將HTTP響應轉為你想要的物件類型並返回這個對象。postForLocation()方法執行一個POST操作,將給定的對象轉為一個HTTP請求並返回HTTP響應的location頭,這裡可以找到最新的對象。在處理HTTP請求的異常情形下,將拋出RestClientException異常類型;可以通過將ResponseErrorHandler實現插入到RestTemplate可以改變這種異常處理的行為。

 

exchange和execute方法是上述列表指定的方法的泛化版本並且支援其他的結合和方法,比如HTTP PATCH。然而,底層的HTTP也必須支援想得到的聯合。JDK的HttpURLConnection 不支援PATCH方法,但是了Apache HttpComponents HttpClient的4.2版本或者後面的會支援。它們也使得RestTemplate讀HTTP響應到一個一般的類型(比如List<Account>)),使用一個ParameterizedTypeReference,這是一個新類用來抓取和傳遞一般類型資訊。

 

傳遞給這些方法的對象和從這些方法返回的對象由HttpMessageConverter執行個體轉化和從訊息轉化。主要類型的轉換器是預設註冊的,但是了你也可以封裝你自己的轉換器並使用messageConverters()的bean屬性註冊。與這個模板註冊的預設轉換器執行個體是ByteArrayHttpMessageConverter,StringHttpMessageConverter,FormHttpMessageConverter和SourceHttpMessageConverter。你可以使用messageConverters()bean屬性重寫這些預設的,尤其是當使用MarshallingHttpMessageConverter或MappingJackson2HttpMessageConverter時重寫就是必須的了。

 

每個方法傳遞URI模板參數,用兩種方式,要不String變數長度參數,要不Map<String,String>. 例如:

 

[java] view plaincopy 
  1. String result = restTemplate.getForObject(  
  2.         "http://example.com/hotels/{hotel}/bookings/{booking}", String.class,"42", "21");  

 

 

 

上述使用的變數長度參數,

[java] view plaincopy 
  1. Map<String, String> vars = Collections.singletonMap("hotel", "42");  
  2. String result = restTemplate.getForObject(  
  3.         "http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);  

這使用的是Map<String,String>.

 

為建立一個RestTemplate執行個體,你可以僅調用預設的構造器。這將使用來自java.net包中的標準Java類,做實現HTTP請求的底層實現。這個可以通過指定ClientHttpRequestFactory實現來重寫。Spring提供了HttpComponentsClientHttpRequestFactory 工廠類,使用Apache HttpComponents HttpClient  建立請求。HttpComponentsClientHttpRequestFactory使用org.apache.http.client.HttpClient的執行個體配置,反過來使用認證資訊或者串連池功能配置。

 

注意:

    java.net實現HTTP請求時,可能產生一個異常,當訪問響應狀態時,這代表了一個錯誤。如果這是一個問題,轉為使用HttpComponentsClientHttpRequestFactory  

 

前面的例子使用Apache HttpComponents HttpClient直接重寫,並使用下面顯示的RestTemplate:

[java] view plaincopy 
  1. uri = "http://example.com/hotels/{id}/bookings";  
  2.   
  3. RestTemplate template = new RestTemplate();  
  4.   
  5. Booking booking = // create booking object  
  6.   
  7. URI location = template.postForLocation(uri, booking, "1");  


為使用Apache HttpComponents 而不是本地的java.net功能,構造如下的RestTemplate :

[java] view plaincopy 
  1. RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());  


注意:Apache HttpClient支援gzip編碼。為使用它,構造了HttpComponentsClientHttpRequestFactory工廠類,如下所示:

 

[java] view plaincopy 
  1. HttpClient httpClient = HttpClientBuilder.create().build();  
  2. ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);  
  3. RestTemplate restTemplate = new RestTemplate(requestFactory);  

 

 


一般的回調介面是RequestCallback 併當調用執行方法時調用

 

[java] view plaincopy 
  1. public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,  
  2.         ResponseExtractor<T> responseExtractor, String... urlVariables)  
  3.   
  4. // also has an overload with urlVariables as a Map<String, String>.  


 

 

 

RequestCallback介面定義如下:

 

[java] view plaincopy 
  1. public interface RequestCallback {  
  2.  void doWithRequest(ClientHttpRequest request) throws IOException;  
  3. }  

允許你操作要求標頭並寫到請求體中。當使用execute方法時,你不必擔心任何資源管理,模板將總是關閉請求並處理任何錯誤。

 

 

 

 

使用URI working with URI

 

對於每個主要的HTTP方法,RestTemplate提供了String類型的URI或者java.net.URI執行個體的變數作為第一個參數。

 

String URI變數接受模板參數作為一個String變數長度參數或者作為一個Map<String,String>。它們也假設URL String類型是不編碼的並且需要編碼。例子如下:

[java] view plaincopy 
  1. restTemplate.getForObject("http://example.com/hotel list", String.class);  

 

將在http://example.com/hotel%20list上執行一個GET請求。這意味著如果你輸入String類型的已經編碼的URL,其將再編碼一次。即http://example.com/hotel%20list將被變為http://example.com/hotel%2520list。如果這不是我們想要的結果,使用java.net.URI方法變數,其假設已經編碼的url是有用的,如果你想多次使用一個單一的URI。

 

UriComponentsBuilder這個類能用於構建和編碼URI,包括支援URI模板。例如,你可以以一個String類型的url開始。

 

[java] view plaincopy 
  1. UriComponents uriComponents = UriComponentsBuilder.fromUriString(  
  2.         "http://example.com/hotels/{hotel}/bookings/{booking}").build()  
  3.         .expand("42", "21")  
  4.         .encode();  
  5.   
  6. URI uri = uriComponents.toUri();  

 

 

或者分別指定每個URI組件:

 

[java] view plaincopy 
  1. UriComponents uriComponents = UriComponentsBuilder.newInstance()  
  2.         .scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build()  
  3.         .expand("42", "21")  
  4.         .encode();  
  5.   
  6. URI uri = uriComponents.toUri();  

 

 

請求和回應標頭的處理

 

除了上述的方法外,RestTemplate也有exchange()方法,能用於基於HttpEntity類的任何HTTP方法的執行。

 

也許更加重要的是,exchange()這個方法可以用於添加請求和回應標頭。例如:

 

 

[java] view plaincopy 
  1. HttpHeaders requestHeaders = new HttpHeaders();  
  2. requestHeaders.set("MyRequestHeader", "MyValue");  
  3. HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);  
  4.   
  5. HttpEntity<String> response = template.exchange(  
  6.         "http://example.com/hotels/{hotel}",  
  7.         HttpMethod.GET, requestEntity, String.class, "42");  
  8.   
  9. String responseHeader = response.getHeaders().getFirst("MyResponseHeader");  
  10. String body = response.getBody();  

 


在上述的例子中,我們首先準備了一個請求,其包含了MyRequestHeader頭資訊。稍後我們檢索了對應的響應,並讀了MyResponseHeader和訊息體。

 

Jackson JSON 視圖支援

可能指定一個Jackson JSON View序列化對象屬性子集。例如:

 

[java] view plaincopy 
  1. JacksonSerializationValue jsv = new JacksonSerializationValue(new User("eric", "7!jd#h23"),  
  2.     User.WithoutPasswordView.class);  
  3. HttpEntity<JacksonSerializationValue> entity = new HttpEntity<JacksonSerializationValue>(jsv);  
  4. String s = template.postForObject("http://example.com/user", entity, String.class);  

 

本文轉自:http://blog.csdn.net/luccs624061082/article/details/40893963

Spring之在用戶端訪問RESTful業務

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.