Spring RestTemplate中幾種常見的請求方式

Spring Cloud中服務的發現與消費一文中,當咱們從服務消費端去調用服務提供者的服務的時候,使用了一個很好用的對象,叫作RestTemplate,當時咱們只使用了RestTemplate中最簡單的一個功能getForEntity發起了一個get請求去調用服務端的數據,同時,咱們還經過配置@LoadBalanced註解開啓客戶端負載均衡,RestTemplate的功能不可謂不強大,那麼今天咱們就來詳細的看一下RestTemplate中幾種常見請求方法的使用。git


本文是Spring Cloud系列的第六篇文章,瞭解前五篇文章的內容有助於更好的理解本文: github

1.使用Spring Cloud搭建服務註冊中心
2.使用Spring Cloud搭建高可用服務註冊中心
3.Spring Cloud中服務的發現與消費
4.Eureka中的核心概念
5.什麼是客戶端負載均衡spring


本文主要從如下四個方面來看RestTemplate的使用:app

  • GET請求
  • POST請求
  • PUT請求
  • DELETE請求

OK,開始吧。負載均衡

環境搭建

首先咱們要搭建一個測試環境,方便咱們一會驗證相應的API。
服務註冊中心我就直接使用前文(使用Spring Cloud搭建服務註冊中心)中建立的服務註冊中心。
服務提供者和服務消費者我建立在一個maven工程中,若是小夥伴對IntelliJ IDEA中建立maven多模塊項目還不瞭解的話,能夠參考IntelliJ IDEA中建立Web聚合項目(Maven多模塊項目)。建立好的maven項目以下圖所示: maven

圖片描述

其中commons是一個公共模塊,是一個普通的JavaSE工程,咱們一會主要將實體類寫在這個模塊中,provider和consumer是兩個spring boot項目,provider將扮演服務提供者的角色,consumer扮演服務消費者的角色。 ide

commons模塊主要用來提供實體類,內容以下: 函數

圖片描述
而後在provider和consumer模塊中添加對commons的依賴,依賴代碼以下:post

<dependency>
    <groupId>org.sang</groupId>
    <artifactId>commons</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

provider和consumer的開發小夥伴們能夠參考使用Spring Cloud搭建服務註冊中心Spring Cloud中服務的發現與消費,我這裏就再也不贅述了。下文中我只列出provider和consumer的核心代碼,文末能夠下載源碼。測試

GET請求

在RestTemplate中,發送一個GET請求,咱們能夠經過以下兩種方式:

第一種:getForEntity

getForEntity方法的返回值是一個ResponseEntity<T>ResponseEntity<T>是Spring對HTTP請求響應的封裝,包括了幾個重要的元素,如響應碼、contentType、contentLength、響應消息體等。好比下面一個例子:

@RequestMapping("/gethello")
public String getHello() {
    ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class);
    String body = responseEntity.getBody();
    HttpStatus statusCode = responseEntity.getStatusCode();
    int statusCodeValue = responseEntity.getStatusCodeValue();
    HttpHeaders headers = responseEntity.getHeaders();
    StringBuffer result = new StringBuffer();
    result.append("responseEntity.getBody():").append(body).append("<hr>")
            .append("responseEntity.getStatusCode():").append(statusCode).append("<hr>")
            .append("responseEntity.getStatusCodeValue():").append(statusCodeValue).append("<hr>")
            .append("responseEntity.getHeaders():").append(headers).append("<hr>");
    return result.toString();
}

關於這段代碼,我說以下幾點:

  • getForEntity的第一個參數爲我要調用的服務的地址,這裏我調用了服務提供者提供的/hello接口,注意這裏是經過服務名調用而不是服務地址,若是寫成服務地址就無法實現客戶端負載均衡了。
  • getForEntity第二個參數String.class表示我但願返回的body類型是String
  • 拿到返回結果以後,將返回結果遍歷打印出來

最終顯示結果以下:

圖片描述

有時候我在調用服務提供者提供的接口時,可能須要傳遞參數,有兩種不一樣的方式,以下:

@RequestMapping("/sayhello")
public String sayHello() {
    ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={1}", String.class, "張三");
    return responseEntity.getBody();
}
@RequestMapping("/sayhello2")
public String sayHello2() {
    Map<String, String> map = new HashMap<>();
    map.put("name", "李四");
    ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={name}", String.class, map);
    return responseEntity.getBody();
}
  • 能夠用一個數字作佔位符,最後是一個可變長度的參數,來一一替換前面的佔位符
  • 也能夠前面使用name={name}這種形式,最後一個參數是一個map,map的key即爲前邊佔位符的名字,map的value爲參數值

第一個調用地址也能夠是一個URI而不是字符串,這個時候咱們構建一個URI便可,參數神馬的都包含在URI中了,以下:

@RequestMapping("/sayhello3")
public String sayHello3() {
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://HELLO-SERVICE/sayhello?name={name}").build().expand("王五").encode();
    URI uri = uriComponents.toUri();
    ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri, String.class);
    return responseEntity.getBody();
}

經過Spring中提供的UriComponents來構建Uri便可。

固然,服務提供者不只能夠返回String,也能夠返回一個自定義類型的對象,好比個人服務提供者中有以下方法:

@RequestMapping(value = "/getbook1", method = RequestMethod.GET)
public Book book1() {
    return new Book("三國演義", 90, "羅貫中", "花城出版社");
}

對於該方法我能夠在服務消費者中經過以下方式來調用:

@RequestMapping("/book1")
public Book book1() {
    ResponseEntity<Book> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/getbook1", Book.class);
    return responseEntity.getBody();
}

運行結果以下:

圖片描述

第二種:getForObject

getForObject函數其實是對getForEntity函數的進一步封裝,若是你只關注返回的消息體的內容,對其餘信息都不關注,此時可使用getForObject,舉一個簡單的例子,以下:

@RequestMapping("/book2")
public Book book2() {
    Book book = restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class);
    return book;
}

getForObject也有幾個重載方法,以下:

圖片描述

這幾個重載方法參數的含義和getForEntity一致,我就再也不贅述了。

POST請求

在RestTemplate中,POST請求能夠經過以下三個方法來發起:

第一種:postForEntity

該方法和get請求中的getForEntity方法相似,以下例子:

@RequestMapping("/book3")
public Book book3() {
    Book book = new Book();
    book.setName("紅樓夢");
    ResponseEntity<Book> responseEntity = restTemplate.postForEntity("http://HELLO-SERVICE/getbook2", book, Book.class);
    return responseEntity.getBody();
}
  • 方法的第一參數表示要調用的服務的地址
  • 方法的第二個參數表示上傳的參數
  • 方法的第三個參數表示返回的消息體的數據類型

我這裏建立了一個Book對象,這個Book對象只有name屬性有值,將之傳遞到服務提供者那裏去,服務提供者代碼以下:

@RequestMapping(value = "/getbook2", method = RequestMethod.POST)
public Book book2(@RequestBody Book book) {
    System.out.println(book.getName());
    book.setPrice(33);
    book.setAuthor("曹雪芹");
    book.setPublisher("人民文學出版社");
    return book;
}

服務提供者接收到服務消費者傳來的參數book,給其餘屬性設置上值再返回,調用結果以下:

圖片描述

postForEntity的其餘重載方法以下:

圖片描述

這些方法的參數含義和getForEntity參數的含義一致,再也不贅述。

第二種:postForObject

若是你只關注,返回的消息體,能夠直接使用postForObject。用法和getForObject一致。

第三種:postForLocation

postForLocation也是提交新資源,提交成功以後,返回新資源的URI,postForLocation的參數和前面兩種的參數基本一致,只不過該方法的返回值爲Uri,這個只須要服務提供者返回一個Uri便可,該Uri表示新資源的位置。

PUT請求

在RestTemplate中,PUT請求能夠經過put方法調用,put方法的參數和前面介紹的postForEntity方法的參數基本一致,只是put方法沒有返回值而已。舉一個簡單的例子,以下:

@RequestMapping("/put")
public void put() {
    Book book = new Book();
    book.setName("紅樓夢");
    restTemplate.put("http://HELLO-SERVICE/getbook3/{1}", book, 99);
}

book對象是我要提交的參數,最後的99用來替換前面的佔位符{1}

DELETE請求

delete請求咱們能夠經過delete方法調用來實現,以下例子:

@RequestMapping("/delete")
public void delete() {
    restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100);
}

delete方法也有幾個重載的方法,不太重載的參數和前面基本一致,不贅述。

OK,以上就是咱們對RestTemplate可以發送的請求的一個詳細介紹,有問題歡迎留言討論。

本文案例地址:https://github.com/lenve/SimpleSpringCloud/tree/master/RestTemplate

更多JavaEE資料請關注公衆號:

圖片描述

以上。

相關文章
相關標籤/搜索