當前位置:
首頁 > 知識 > 詳解 RestTemplate 操作

詳解 RestTemplate 操作

作為開發人員,我們經常關注於構建偉大的軟體來解決業務問題。數據只是軟體完成工作時

要處理的原材料。但是如果你問一下業務人員,數據和軟體誰更重要的話,他們很可能會選擇

數據。數據是許多業務的生命之血。軟體通常是可以替換的,但是多年積累的數據是永遠不能

替換的。

近幾年來,以信息為中心的表述性狀態轉移(Representational State Transfer,REST)已經稱為替代傳統SOAP Web 服務的流行方案.

SOAP關注的一般是行為和處理,而REST關注的是要處理的數據.

從Spring3.0開始,Spring為創建Rest API提供了良好的支持.

REST提供了一個更簡單的可選方案。另外,很多的現代化應用都會有移動或富JavaScript客戶端,它們都會使用運行在伺服器上REST API。

REST的基礎知識

參考我的這篇文章: Restful API 設計指南

當談論REST時,有一種常見的錯誤就是將其視為「基於URL的Web服務」——將REST作為另一

種類型的遠程過程調用(remote procedure call,RPC)機制,就像SOAP一樣,只不過是通過簡單

的HTTP URL來觸發,而不是使用SOAP大量的XML命名空間

恰好相反,REST與RPC幾乎沒有任何關係。RPC是面向服務的,並關注於行為和動作;而REST

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

更簡潔地講,REST就是將資源的狀態以最適合客戶端或服務端的形式從伺服器端轉移到客戶

端(或者反過來)。

在REST中,資源通過URL進行識別和定位。至於RESTful URL的結構並沒有嚴格的規則,但是

URL應該能夠識別資源,而不是簡單的發一條命令到伺服器上。再次強調,關注的核心是事

物,而不是行為。

Spring 中如何使用Rest資源

藉助 RestTemplate,Spring應用能夠方便地使用REST資源

Spring的 RestTemplate訪問使用了模版方法的設計模式.

模版方法將過程中與特定實現相關的部分委託給介面,而這個介面的不同實現定義了介面的不同行為.

RestTemplate定義了36個與REST資源交互的方法,其中的大多數都對應於HTTP的方法。

其實,這裡面只有11個獨立的方法,其中有十個有三種重載形式,而第十一個則重載了六次,這樣一共形成了36個方法。

delete() 在特定的URL上對資源執行HTTP DELETE操作

exchange()

在URL上執行特定的HTTP方法,返回包含對象的ResponseEntity,這個對象是從響應體中

映射得到的

execute() 在URL上執行特定的HTTP方法,返回一個從響應體映射得到的對象

getForEntity() 發送一個HTTP GET請求,返回的ResponseEntity包含了響應體所映射成的對象

getForObject() 發送一個HTTP GET請求,返回的請求體將映射為一個對象

postForEntity()

POST 數據到一個URL,返回包含一個對象的ResponseEntity,這個對象是從響應體中映射得

到的

postForObject() POST 數據到一個URL,返回根據響應體匹配形成的對象

headForHeaders() 發送HTTP HEAD請求,返回包含特定資源URL的HTTP頭

optionsForAllow() 發送HTTP OPTIONS請求,返回對特定URL的Allow頭信息

postForLocation() POST 數據到一個URL,返回新創建資源的URL

put() PUT 資源到特定的URL

實際上,由於Post 操作的非冪等性,它幾乎可以代替其他的CRUD操作.

Get請求

RestTemplate 的get方法有以上幾個,可以分為兩類: getForEntity() 和 getForObject()

首先看 getForEntity() 的返回值類型 ResponseEntity

<T> ResponseEntity<T> getForEntity()

1

看一下 ResponseEntity 的文檔描述:

可以看到 它繼承了HttpEntity. 封裝了返回的響應信息,包括 響應狀態,響應頭 和 響應體.

在測試之前我們首先 創建一個Rest服務,模擬提供Rest數據,這裡給出Controller層代碼,具體可以查看源碼,文章最後會給出:

/**

* @author itguang

* @create 2017-12-17 10:37

**/

@RestController

public class UserController {

@Autowired

private UserService userService;

@RequestMapping(value = "getAll")

public List<UserEntity> getUser() {

List<UserEntity> list = userService.getAll();

return list;

}

@RequestMapping("get/{id}")

public UserEntity getById(@PathVariable(name = "id") String id) {

return userService.getById(id);

}

@RequestMapping(value = "save")

public String save(UserEntity userEntity) {

return "保存成功";

}

@RequestMapping(value = "saveByType/{type}")

public String saveByType(UserEntity userEntity,@PathVariable("type")String type) {

return "保存成功,type="+type;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

測試: getForEntity

無參數的 getForEntity 方法

@RequestMapping("getForEntity")

public List<UserEntity> getAll2() {

ResponseEntity<List> responseEntity = restTemplate.getForEntity("http://localhost/getAll", List.class);

HttpHeaders headers = responseEntity.getHeaders();

HttpStatus statusCode = responseEntity.getStatusCode();

int code = statusCode.value();

List<UserEntity> list = responseEntity.getBody();

System.out.println(list.toString());

return list;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

有參數的 getForEntity 請求,參數列表,可以使用 {} 進行url路徑佔位符

//有參數的 getForEntity 請求,參數列表

@RequestMapping("getForEntity/{id}")

public UserEntity getById2(@PathVariable(name = "id") String id) {

ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", UserEntity.class, id);

UserEntity userEntity = responseEntity.getBody();

return userEntity;

}

1

2

3

4

5

6

7

8

有參數的 get 請求,使用map封裝參數

//有參數的 get 請求,使用map封裝參數

@RequestMapping("getForEntity/{id}")

public UserEntity getById4(@PathVariable(name = "id") String id) {

HashMap<String, String> map = new HashMap<>();

map.put("id",id);

ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", UserEntity.class, map);

UserEntity userEntity = responseEntity.getBody();

return userEntity;

}

1

2

3

4

5

6

7

8

9

10

11

12

通過斷點調試我們看下 返回的 responseEntity 的信息如圖:

因此我們可以獲取Http請求的全部信息.

但是,通常情況下我們並不想要Http請求的全部信息,只需要相應體即可.對於這種情況,RestTemplate提供了 getForObject() 方法用來只獲取 響應體信息.

getForObject 和 getForEntity 用法幾乎相同,指示返回值返回的是 響應體,省去了我們 再去 getBody() .

測試: getForObject

無參數的 getForObject 請求

//無參數的 getForObject 請求

@RequestMapping("getAll2")

public List<UserEntity> getAll() {

List<UserEntity> list = restTemplate.getForObject("http://localhost/getAll", List.class);

System.out.println(list.toString());

return list;

}

1

2

3

4

5

6

7

8

9

10

11

有參數的 getForObject 請求,使用參數列表

//有參數的 getForObject 請求

@RequestMapping("get2/{id}")

public UserEntity getById(@PathVariable(name = "id") String id) {

UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, id);

return userEntity;

}

1

2

3

4

5

6

7

8

9

有參數的 get 請求,使用map封裝請求參數

//有參數的 get 請求,使用map封裝請求參數

@RequestMapping("get3/{id}")

public UserEntity getById3(@PathVariable(name = "id") String id) {

HashMap<String, String> map = new HashMap<>();

map.put("id",id);

UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, map);

return userEntity;

}

1

2

3

4

5

6

7

8

9

10

11

Post請求

了解了get請求後,Post請求就變得很簡單了,我們可以看到post有如下方法:

測試: postForEntity

post 請求,保存 UserEntity 對像

//post 請求,提交 UserEntity 對像

@RequestMapping("saveUser")

public String save(UserEntity userEntity) {

ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/save", userEntity, String.class);

String body = responseEntity.getBody();

return body;

}

1

2

3

4

5

6

7

8

9

10

11

12

瀏覽器訪問: http://localhost/saveUser?username=itguang&password=123456&age=20&email=123@123.com

我們再次斷點調試,查看 responseEntity 中的信息:

有參數的 postForEntity 請求

// 有參數的 postForEntity 請求

@RequestMapping("saveUserByType/{type}")

public String save2(UserEntity userEntity,@PathVariable("type")String type) {

ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", userEntity, String.class, type);

String body = responseEntity.getBody();

return body;

}

// 有參數的 postForEntity 請求,使用map封裝

@RequestMapping("saveUserByType2/{type}")

public String save3(UserEntity userEntity,@PathVariable("type")String type) {

HashMap<String, String> map = new HashMap<>();

map.put("type", type);

ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", userEntity, String.class,map);

String body = responseEntity.getBody();

return body;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

我們瀏覽器訪問: localhost/saveUserByType/120?username=itguang&password=123456&age=20&email=123@123.com

就會返回: 保存成功,type=120

對與其它請求方式,由於不常使用,所以這裡就不再講述.

源碼地址: https://github.com/itguang/springcloud-learn/tree/master/resttemplate-test

詳解 RestTemplate 操作

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

Spring 定時任務Scheduled 開發詳細圖文
使用 Sonar 進行代碼質量管理

TAG:程序員小新人學習 |