Spring restTemplate 使用方法

一般來說很多請求的處理多半是透過前端進行,但也免不了有時候後端需要直接發送請求來處理,像是後端需要去特定 api 拿取資源又或是和其他 server 之間的溝通部分很常需要自己發送請求,Spring Boot 也有提供 RestTemplate 這個物件來輕鬆實踐,早期多半使用 Java 原生的 HttpConnectionUrl 來處理,那這次就介紹一下現在比較常用到的幾個常見  RestTemplate 方法。

這邊提供一個開放的 api 可以進行測試 (https://jsonplaceholder.typicode.com),裡面有詳細介紹有哪些路徑可以使用,可以直接用 postman 對特定位置來請求看看。下面介紹就會針對這個 api 進行請求。

getForObject()/postForObject()

只想取得回覆的 body,對於其他 header 等資訊不在意,所以 response 裡面只會單純回應對方要回傳的 body

寫一個 Class 來發送請求至 https://jsonplaceholder.typicode.com/posts/1,取得第一篇文章內容

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
public class RestTemplateDemo {
static RestTemplate restTemplate = new RestTemplate();
static String urlForGet = "https://jsonplaceholder.typicode.com/posts/1";
static String UrlForPost = "https://jsonplaceholder.typicode.com/posts";

public static void main(String[] args) {
getForObject();
}
/**
* getForObject
* GET
* response 只有回傳 api 回應內容,不帶有 header, response code...
*/
public static String getForObject(){
System.out.println("--- do getForObject ---");
String response = restTemplate.getForObject(urlForGet, String.class);
System.out.println(response);
return response;
}

public static String postForObject(){
System.out.println("--- do postForObject ---");
HashMap<String, String> mapPost = new HashMap<>();
mapPost.put("title", "新的文章標題");
mapPost.put("body", "大家好,我是Sean!!");
String response = restTemplate.postForObject(UrlForPost, mapPost, String.class);
System.out.println(response);
return response;
}
}

執行這個方法可以在 terminal 看到回應
https://ithelp.ithome.com.tw/upload/images/20240923/20150977ntQvAh9xoW.png

https://ithelp.ithome.com.tw/upload/images/20240923/20150977kdaUZU8qON.png

getForEntity()/postForEntity()

同時需要其他資訊如 header, response code 等等,其返回值是 ResponseEntity 物件,ResponseEntity 是 Spring 對 HTTP 請求的回覆封裝,getForObject 請求內部物件方法,getForEntity 都可以使用。

使用ResponseEntity<T> responseEntity來接收回覆結果。在配合用特定方法取得封裝物件內容:

  • getBody()
  • getHeaders()
  • getStatusCode()

寫一個方法來發送請求

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
/**
* getForEntity
* GET
* response 組成 ResponseEntity ,內含 body, header, response code...
*/
public static ResponseEntity<String> getForEntity(){
ResponseEntity<String> response = restTemplate.getForEntity(urlForGet, String.class);
System.out.println(response);
return response;
}

/**
* postForEntity
* POST
* 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
*/
public static ResponseEntity<String> postForEntity(){
System.out.println("--- do postForEntity ---");
HashMap<String, String> mapPost = new HashMap<>();
mapPost.put("title", "新的文章標題");
mapPost.put("body", "大家好,我是Sean!!");
ResponseEntity<String> response = restTemplate.postForEntity(UrlForPost, mapPost, String.class);
System.out.println(response);
return response;
}

main 下加入這方法且執行後可以看到回應不只有原本
https://ithelp.ithome.com.tw/upload/images/20240923/20150977AHjTcG84wq.png

https://ithelp.ithome.com.tw/upload/images/20240923/20150977W9G5wQ2fAH.png

exchange

更完整可以配置請求的相關內容,可以配置 header, HTTP method, Url 等等在送出請求之前,並且加入請求內容或是參數,最後和 get/postForEntity 一樣得到回應為封裝的 ResponseEntity。所以可以從中獲取你需要的各種資訊。

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
42
43
44
45
46
/**
* exchange
* (GET) 適用任何 http method。
* 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
*/
public static String exchangeWithGet(){
// 設定 header
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

// 建立 HttpEntity 物件,包含請求頭及請求內容(可以省略)
HttpEntity<String> request = new HttpEntity<>("", headers);

// 執行 GET 請求,並取得回應資料
ResponseEntity<String> response = restTemplate.exchange(urlForGet, HttpMethod.GET, request, String.class);

// 讀取回應內容
String responseBody = response.getBody();
System.out.println(responseBody);
return responseBody;
}

/**
* exchange
* (POST) 適用任何 http method。
* 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
*/
public static ResponseEntity<String> exchangeWithPost(){
System.out.println("--- do exchangeWithPost ---");

// 設定 header
HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_JSON);

// 建立 HttpEntity 物件,包含請求頭及請求內容(可以省略)
Post post = new Post("新的文章標題", "大家好,我是Sean!!");
HttpEntity<Post> request = new HttpEntity<>(post, headers);

// 執行 GET 請求,並取得回應資料
ResponseEntity<String> response = restTemplate.exchange(UrlForPost, HttpMethod.POST, request, String.class);

// 讀取回應內容
System.out.println(response);
return response;
}

回應部分就先省略,因為就如同上面的 getForEntity 和 postForEntity 範例一樣,

put()

1
2
3
4
5
6
7
8
9
10
/**
* put
* PUT
* 沒有回傳值
*/
public static void put(){
String url = "https://jsonplaceholder.typicode.com/posts/2";
Post post = new Post("修改文章標題", "修改文章內容");
restTemplate.put(url, post);
}

沒有回傳

delete()

1
2
3
4
5
6
7
8
9
/**
* delete
* DELETE
* 沒有回傳值
*/
public static void delete(){
String url = "https://jsonplaceholder.typicode.com/posts/3";
restTemplate.delete(url);
}

沒有回傳

完整範例

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.oseanchen.demotest.restTemplate;

import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;

public class RestTemplateDemo {
static RestTemplate restTemplate = new RestTemplate();
static String urlForGet = "https://jsonplaceholder.typicode.com/posts/1";
static String UrlForPost = "https://jsonplaceholder.typicode.com/posts";

public static void main(String[] args) {
// getForObject();
// getForEntity();
// postForObject();
postForEntity();
// exchangeWithGet();
// exchangeWithPost();
// put();
// delete();
}
/**
* getForObject
* GET
* response 只有回傳 api 回應內容,不帶有 header, response code...
*/
public static String getForObject(){
System.out.println("--- do getForObject ---");
String response = restTemplate.getForObject(urlForGet, String.class);
System.out.println(response);
return response;
}

public static String postForObject(){
System.out.println("--- do postForObject ---");
HashMap<String, String> mapPost = new HashMap<>();
mapPost.put("title", "新的文章標題");
mapPost.put("body", "大家好,我是Sean!!");
String response = restTemplate.postForObject(UrlForPost, mapPost, String.class);
System.out.println(response);
return response;
}

/**
* getForEntity
* GET
* response 組成 ResponseEntity ,內含 body, header, response code...
*/
public static ResponseEntity<String> getForEntity(){
System.out.println("--- do getForEntity ---");
ResponseEntity<String> response = restTemplate.getForEntity(urlForGet, String.class);
System.out.println(response);
return response;
}

/**
* postForEntity
* POST
* 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
*/
public static ResponseEntity<String> postForEntity(){
System.out.println("--- do postForEntity ---");
HashMap<String, String> mapPost = new HashMap<>();
mapPost.put("title", "新的文章標題");
mapPost.put("body", "大家好,我是Sean!!");
ResponseEntity<String> response = restTemplate.postForEntity(UrlForPost, mapPost, String.class);
System.out.println(response);
return response;
}

/**
* exchange
* (GET) 適用任何 http method。
* 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
*/
public static String exchangeWithGet(){
// 設定 header
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

// 建立 HttpEntity 物件,包含請求頭及請求內容(可以省略)
HttpEntity<String> request = new HttpEntity<>("", headers);

// 執行 GET 請求,並取得回應資料
ResponseEntity<String> response = restTemplate.exchange(urlForGet, HttpMethod.GET, request, String.class);

// 讀取回應內容
String responseBody = response.getBody();
System.out.println(responseBody);
return responseBody;
}

/**
* exchange
* (POST) 適用任何 http method。
* 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
*/
public static ResponseEntity<String> exchangeWithPost(){
System.out.println("--- do exchangeWithPost ---");

// 設定 header
HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_JSON);

// 建立 HttpEntity 物件,包含請求頭及請求內容(可以省略)
Post post = new Post("新的文章標題", "大家好,我是Sean!!");
HttpEntity<Post> request = new HttpEntity<>(post, headers);

// 執行 GET 請求,並取得回應資料
ResponseEntity<String> response = restTemplate.exchange(UrlForPost, HttpMethod.POST, request, String.class);

// 讀取回應內容
System.out.println(response);
return response;
}

/**
* put
* PUT
* 沒有回傳值
*/
public static void put(){
String url = "https://jsonplaceholder.typicode.com/posts/2";
Post post = new Post("修改文章標題", "修改文章內容");
restTemplate.put(url, post);
}

/**
* delete
* DELETE
* 沒有回傳值
*/
public static void delete(){
String url = "https://jsonplaceholder.typicode.com/posts/3";
restTemplate.delete(url);
}
}

總結

上述各類型的用法其實都很雷同,主要先看是否需要有進一步關於回應的各種資訊。

  • 如果不需要就可以考慮使用 get/postForObject 純粹獲取回應 body 就好。
  • 如果需要那些完整回應的資訊就可以考慮用 get/postForEntity 或 Exchange 來進行請求,這樣就可以從中獲取像是 status code, header 等的資訊。
  • 如果要細部指定 header 或是各類型的方法可以使用 exchange 來進行請求可以根據需求調整,詳細可以參考下表。
  • delete, put, patch 等如果不需要回應可以直接使用。
return type set header getStatusCode() getHeaders() getBody()
getForObject/postForObject String (response body) x x x x
getForEntity/postForEntity ResponseEntity x o o o
exchange ResponseEntity o o o o
put/delete void x x x x

Ref: