### GET
```java
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
public class Example {
public static void main(String[] args) {
// 建立 RestTemplate 物件
RestTemplate restTemplate = new RestTemplate();
// 設定 API 網址和參數
String url = "https://api.example.com/data";
String parameter1 = "value1";
String parameter2 = "value2";
// 使用 UriComponentsBuilder 建立包含參數的 URL
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
.queryParam("param1", parameter1)
.queryParam("param2", parameter2);
// 執行 GET 請求
ResponseEntity<String> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, null, String.class);
// 取得回應的結果
String responseBody = response.getBody();
System.out.println(responseBody);
}
}
```
### POST Json
```java
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
public class Example {
public static void main(String[] args) {
// 建立 RestTemplate 物件
RestTemplate restTemplate = new RestTemplate();
// 設定 API 網址
String url = "https://api.example.com/data";
// 建立請求頭
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 建立請求體,即要傳遞的 JSON 資料
String requestBody = "{\"key\": \"value\"}";
HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);
// 執行 POST 請求
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
// 取得回應的結果
String responseBody = response.getBody();
System.out.println(responseBody);
}
}
```
### POST application/x-www-form-urlencoded
```java
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
public class Example {
public static void main(String[] args) {
// 建立 RestTemplate 物件
RestTemplate restTemplate = new RestTemplate();
// 設定 API 網址
String url = "https://api.example.com/data";
// 建立請求頭
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// 建立請求體,即要傳遞的資料
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("param1", "value1");
requestBody.add("param2", "value2");
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);
// 執行 POST 請求
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
// 取得回應的結果
String responseBody = response.getBody();
System.out.println(responseBody);
}
}
```
### 執行 POST 請求並將 Java Object 轉換為 JSON 格式的範例
```java
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
MyObject myObject = new MyObject();
myObject.setName("John");
myObject.setAge(30);
HttpEntity<MyObject> request = new HttpEntity<>(myObject, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
```
### 根據不同 HTTP status code 執行不同的動作
```java
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
public class RestClient {
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
// 設置自定義的 ResponseErrorHandler
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
@Override
public boolean hasError(HttpStatus statusCode) {
return false; // 不要抛出任何異常
}
});
// 發送 GET 請求,並根據不同的狀態碼執行不同的操作
String url = "https://example.com/api/users";
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
HttpStatus statusCode = responseEntity.getStatusCode();
if (statusCode.is2xxSuccessful()) {
// 2xx 狀態碼表示成功,處理正常的響應
String response = responseEntity.getBody();
System.out.println(response);
} else if (statusCode.is4xxClientError()) {
// 4xx 狀態碼表示客戶端錯誤,處理錯誤的響應
throw new HttpClientErrorException(statusCode);
} else if (statusCode.is5xxServerError()) {
// 5xx 狀態碼表示服務器錯誤,處理錯誤的響應
throw new HttpServerErrorException(statusCode);
} else {
// 其他狀態碼,可以進行重試或重定向等操作
System.out.println("Received status code: " + statusCode);
}
}
}
```
上面的代碼首先創建了一個 RestTemplate 對象,然後設置了一個自定義的 ResponseErrorHandler,該處理程序將不會抛出任何異常,因為我們將在代碼中處理所有的 HTTP 狀態碼。
接下來,我們使用 RestTemplate 發送一個 GET 請求,獲取一個 ResponseEntity 對象,其中包含了 HTTP 響應的所有信息,包括狀態碼、響應主體等等。我們使用 getStatusCode 方法獲取狀態碼,然後根據狀態碼執行不同的操作
### Response 使用泛型 `Some<Another>` 回應
```java
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
public class Example {
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
String url = "http://example.com/api/some-endpoint";
// 設置請求主體
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("name", "John");
requestBody.add("age", "30");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<Some<Another>> response = restTemplate.exchange(
url,
HttpMethod.POST,
request,
new ParameterizedTypeReference<Some<Another>>() {}
);
Some<Another> result = response.getBody();
// 使用結果進行後續處理
}
}
```
上述範例中,我們使用 RestTemplate 的 exchange 方法來發送 HTTP POST 請求,並指定 ParameterizedTypeReference<Some<Another>> 作為結果類型。透過這樣的方式,我們可以正確地處理帶有泛型參數的類型。
請注意,為了創建 ParameterizedTypeReference,我們使用了匿名內部類的方式,因為 Java 語言的類型擦除機制限制了直接獲取帶有泛型參數的類型。
這是一個可以接收帶有泛型參數類型的 postForObject 範例,通過使用 ParameterizedTypeReference 可以確保正確處理帶有泛型的類型返回結果。
### Configuration Timeout
```java
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
int connectTimeout = 5000; // 連接超時時間,單位:毫秒
int readTimeout = 5000; // 讀取超時時間,單位:毫秒
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(connectTimeout);
factory.setReadTimeout(readTimeout);
return restTemplateBuilder
.requestFactory(() -> factory)
.build();
}
}
```
### RestTemplateService
```java
import java.net.URI;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
/**
* @author Adam Huang
* @since 2023-03-08
*/
@Slf4j
@Service
public class RestTemplateService {
@Autowired private RestTemplate restTemplate;
/**
* 利用 RestTemplate 執行 POST
* Request: T body → Json
* Response: S
* @param url 目標 url
* @param headers 標頭
* @param body Request 內容
* @param responseType Response 物件類別
*/
public <T, S> S post(String url, HttpHeaders headers, T body, ParameterizedTypeReference<S> responseType) {
HttpEntity<T> entity = new HttpEntity<>(body, headers);
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.POST, entity, responseType);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 POST
* Request: T body → Json
* Response: S
* @param url 目標 url
* @param body Request 內容
* @param responseType Response 物件類別
*/
public <T, S> S post(String url, T body, ParameterizedTypeReference<S> responseType) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<T> entity = new HttpEntity<>(body, headers);
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.POST, entity, responseType);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 POST
* @param url 目標 url
* @param headers 標頭
* @param body Request 內容
* @param clz Response 物件類別
* @param params url 中的變數對應值
* @since 2024-07-09
*/
public <T, S> S post(String url, HttpHeaders headers, T body, Class<S> clz, Map<String, String> params) {
HttpEntity<T> entity = new HttpEntity<>(body, headers);
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.POST, entity, clz, params);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 POST
* Request: T body → Json
* Response: S
* @param url 目標 url
* @param headers 標頭
* @param body Request 內容
* @param clz Response 物件類別
*/
public <T, S> S post(String url, HttpHeaders headers, T body, Class<S> clz) {
HttpEntity<T> entity = new HttpEntity<>(body, headers);
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.POST, entity, clz);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 POST
* Request: MultiValueMap(String, String) body
* Response: String
*/
public String post(String url, MultiValueMap<String, String> body) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
return post(url, headers, body, String.class);
}
/**
* 利用 RestTemplate 執行 POST
* Request: T body → Json
* Response: S
*/
public <T, S> S post(String url, T body, Class<S> clz) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return post(url, headers, body, clz);
}
/**
* 利用 RestTemplate 執行 POST
* 並將物件 T 轉成 Json 格式後帶入 Body 中,並轉換成 clz 物件傳回
* @since 2024-07-09
*/
public <T, S> S post(String url, T body, Class<S> clz, Map<String, String> params) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return post(url, headers, body, clz, params);
}
/**
* 利用 RestTemplate 執行 POST
* Request: T body → Json
* Response: String
*/
public <T> String post(String url, T body) {
return post(url, body, String.class);
}
/**
* 利用 RestTemplate 執行 POST
* Request: String message
* Response: String
*/
public String post(String url, String message) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
return post(url, headers, message, String.class);
}
/**
* 利用 RestTemplate 執行 POST,無 Body 的情況
* Response: String
*/
public String post(String url) {
HttpHeaders headers = new HttpHeaders();
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 GET
* @param url 目標 url
* @param headers 標頭
* @param params url 的變數
* @param responseType Response 物件類別
*/
public <S> S get(String url, HttpHeaders headers, Map<String, String> params, ParameterizedTypeReference<S> responseType) {
HttpEntity entity = new HttpEntity<>(headers);
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, params);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 GET
* @param url 目標 url
* @param headers 標頭
* @param params url 的變數
* @param clz Response 物件類別
*/
public <S> S get(String url, HttpHeaders headers, Map<String, String> params, Class<S> clz) {
HttpEntity entity = new HttpEntity<>(headers);
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.GET, entity, clz, params);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 GET
* @param url 目標 url
* @param headers 標頭
* @param responseType Response 物件類別
*/
public <S> S get(String url, HttpHeaders headers, ParameterizedTypeReference<S> responseType) {
HttpEntity entity = new HttpEntity<>(headers);
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.GET, entity, responseType);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 GET
* @param url 目標 url
* @param headers 標頭
* @param clz Response 物件類別
*/
public <S> S get(String url, HttpHeaders headers, Class<S> clz) {
HttpEntity entity = new HttpEntity<>(headers);
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.GET, entity, clz);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 GET
* e.g. get("https://is.gd/create.php?format={format}&url={url}", params, String.class);
* @param url 目標 url
* @param params url 的變數
* @param clz Response 物件類別
*/
public <S> S get(String url, Map<String, String> params, Class<S> clz) {
HttpEntity entity = new HttpEntity<>(new HttpHeaders());
ResponseEntity<S> response = restTemplate.exchange(url, HttpMethod.GET, entity, clz, params);
return response.getBody();
}
/**
* 利用 RestTemplate 執行 GET
* @param url 目標 url
* @param responseType Response 物件類別
*/
public <S> S get(String url, ParameterizedTypeReference<S> responseType) {
return get(url, new HttpHeaders(), responseType);
}
/**
* 利用 RestTemplate 執行 GET
* @param url 目標 url
* @param clz Response 物件類別
*/
public <S> S get(String url, Class<S> clz) {
return get(url, new HttpHeaders(), clz);
}
/**
* 利用 RestTemplate 執行 GET,直接回傳 String
* @param url 目標 url
*/
public String get(String url) {
return get(url, String.class);
}
}
```
### [The Guide to RestTemplate](https://www.baeldung.com/rest-template)
```java
private RestTemplate restTemplate = new RestTemplate();
@Test
public void show() {
Message message = restTemplate.getForObject("http://localhost:8080/messages/{id}", Message.class, "1");
assertNotNull(message.getText());
}
@Test
public void create() {
Message message = new Message("new message");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Message> request = new HttpEntity<>(message, headers);
message = restTemplate.postForObject("http://localhost:8080/messages", request, Message.class);
assertEquals(message.getText(), "new message");
}
@Test
public void delete() {
restTemplate.delete("http://localhost:8080/messages/{id}", "1");
Message message = restTemplate.getForObject("http://localhost:8080/messages/{id}", Message.class, "1");
assertEquals(message.getText(), "msg2");
}
@Test
public void index() {
RequestEntity<Void> request = RequestEntity
.get(URI.create("http://localhost:8080/messages/"))
.accept(MediaType.APPLICATION_JSON)
.build();
ResponseEntity<List<Message>> response = restTemplate
.exchange(request,new ParameterizedTypeReference<List<Message>>(){});
List<Message> messages = response.getBody();
assertTrue(messages.size() > 0);
}
```