Spring RestTemplate使用方法總結(jié)
2025-04-11 10:40 申城異鄉(xiāng)人 閱讀(82) 評(píng)論(0) 收藏 舉報(bào)1. 引入依賴
首先,需要確認(rèn)項(xiàng)目中是否直接或者間接引入過(guò)spring-web依賴,如果沒(méi)有引入過(guò),需要在pom.xml中添加以下代碼引入依賴:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.24.RELEASE</version>
</dependency>
2. 發(fā)送GET請(qǐng)求
使用RestTemplate發(fā)送GET請(qǐng)求主要有getForObject()和getForEntity()2個(gè)方法,每個(gè)方法分別提供了3種不同的重載。
2.1 使用getForObject發(fā)送GET請(qǐng)求(無(wú)參數(shù))
使用getForObject()實(shí)現(xiàn):
RestTemplate restTemplate = new RestTemplate();
String url = "https://www.example.com/getCurrentEnv";
String response = restTemplate.getForObject(url, String.class);
System.out.println(response);
假設(shè)以上接口返回的報(bào)文為:
{
"serverAddress": "www.example.dev.com",
"env": "dev"
}
也可以直接解析為自定義的類型:
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class EnvInfo {
private String serverAddress;
private String env;
}
RestTemplate restTemplate = new RestTemplate();
String url = "https://www.example.com/getCurrentEnv";
EnvInfo response = restTemplate.getForObject(url, EnvInfo.class);
System.out.println(JSON.toJSONString(response));
2.2 使用getForEntity發(fā)送GET請(qǐng)求(無(wú)參數(shù))
也可以使用getForEntity()實(shí)現(xiàn)和2.1同樣的功能,代碼如下所示:
RestTemplate restTemplate = new RestTemplate();
String url = "https://www.example.com/getCurrentEnv";
ResponseEntity<EnvInfo> responseEntity = restTemplate.getForEntity(url, EnvInfo.class);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
EnvInfo response = responseEntity.getBody();
System.out.println(JSON.toJSONString(response));
}
2.3 使用getForObject發(fā)送GET請(qǐng)求(帶參數(shù))
第一種方法是直接在url上拼接上參數(shù),如下所示:
RestTemplate restTemplate = new RestTemplate();
String url = "https://www.example.com/getDataList?pageIndex=1&pageSize=20";
EnvInfo response = restTemplate.getForObject(url, EnvInfo.class);
System.out.println(JSON.toJSONString(response));
第二種方法是使用占位符添加參數(shù),如下所示:
RestTemplate restTemplate = new RestTemplate();
String url = "https://www.example.com/getDataList?pageIndex={1}&pageSize={2}";
EnvInfo response = restTemplate.getForObject(url, EnvInfo.class, 1, 20);
System.out.println(JSON.toJSONString(response));
以上代碼也可以替換為:
RestTemplate restTemplate = new RestTemplate();
String url = "https://www.example.com/getDataList?pageIndex={pageIndex}&pageSize={pageSize}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("pageIndex", "1");
uriVariables.put("pageSize", "20");
EnvInfo response = restTemplate.getForObject(url, EnvInfo.class, uriVariables);
System.out.println(JSON.toJSONString(response));
注意事項(xiàng):
uriVariables中的key必須和url中的占位符名稱一致,否則會(huì)拋出異常:
java.lang.IllegalArgumentException: Map has no value for 'pageIndex'
第三種方法是使用UriComponentsBuilder添加參數(shù),該種方法相比于前兩種方法更加靈活,可以實(shí)現(xiàn)動(dòng)態(tài)添加參數(shù),代碼如下所示:
RestTemplate restTemplate = new RestTemplate();
String httpUrl = "https://www.example.com/getDataList";
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl);
uriComponentsBuilder.queryParam("pageIndex", 1);
uriComponentsBuilder.queryParam("pageSize", 20);
String url = uriComponentsBuilder.toUriString();
EnvInfo response = restTemplate.getForObject(url, EnvInfo.class);
System.out.println(JSON.toJSONString(response));
2.4 使用getForEntity發(fā)送GET請(qǐng)求(帶參數(shù))
也可以使用getForEntity()實(shí)現(xiàn)和2.3同樣的功能,代碼如下所示:
RestTemplate restTemplate = new RestTemplate();
String httpUrl = "https://www.example.com/getDataList";
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl);
uriComponentsBuilder.queryParam("pageIndex", 1);
uriComponentsBuilder.queryParam("pageSize", 20);
String url = uriComponentsBuilder.toUriString();
ResponseEntity<EnvInfo> responseEntity = restTemplate.getForEntity(url, EnvInfo.class);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
EnvInfo response = responseEntity.getBody();
System.out.println(JSON.toJSONString(response));
}
2.5 getForObject與getForEntity的區(qū)別
getForEntity()與getForObject()相比,返回值用了ResponseEntity進(jìn)行封裝,可以多獲取到以下2種信息:
- HTTP狀態(tài)碼
- Response Headers
代碼示例:
RestTemplate restTemplate = new RestTemplate();
String httpUrl = "https://www.example.com/getDataList";
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl);
uriComponentsBuilder.queryParam("pageIndex", 1);
uriComponentsBuilder.queryParam("pageSize", 20);
String url = uriComponentsBuilder.toUriString();
ResponseEntity<EnvInfo> responseEntity = restTemplate.getForEntity(url, EnvInfo.class);
System.out.println("statusCode: " + responseEntity.getStatusCode().toString());
System.out.println("statusCodeValue: " + responseEntity.getStatusCodeValue());
responseEntity.getHeaders().forEach((key, values) -> {
System.out.println(key + ": " + values);
});
輸出結(jié)果:
statusCode: 200
statusCodeValue: 200
Server: [openresty]
Date: [Thu, 10 Apr 2025 05:39:02 GMT]
Content-Type: [application/json]
Transfer-Encoding: [chunked]
Connection: [keep-alive]
其中Response Headers輸出部分和Chrome瀏覽器Network中的Response Headers是一致的:

2.6 發(fā)送GET請(qǐng)求(帶參數(shù)及請(qǐng)求頭)
一般情況下,請(qǐng)求第三方接口都需要簽名、時(shí)間戳等請(qǐng)求頭,但getForObject()和getForEntity()都不支持,
此時(shí)需要使用exchange()方法,代碼如下所示:
RestTemplate restTemplate = new RestTemplate();
String httpUrl = "https://www.example.com/getDataList";
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl);
uriComponentsBuilder.queryParam("pageIndex", 1);
uriComponentsBuilder.queryParam("pageSize", 20);
HttpHeaders headers = new HttpHeaders();
headers.set("signature", "3045022100875efcef9eb54626bb0168a6baa7c61265d0001d49243f");
headers.set("timestamp", String.valueOf(System.currentTimeMillis()));
String url = uriComponentsBuilder.toUriString();
ResponseEntity<EnvInfo> responseEntity = restTemplate.exchange(url,
HttpMethod.GET,
new HttpEntity<>(headers),
EnvInfo.class);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
EnvInfo response = responseEntity.getBody();
System.out.println(JSON.toJSONString(response));
}
3. 發(fā)送POST請(qǐng)求
使用RestTemplate發(fā)送POST請(qǐng)求主要有postForObject()和postForEntity()2個(gè)方法,每個(gè)方法分別提供了3種不同的重載。
3.1 發(fā)送POST請(qǐng)求(帶參數(shù)、json方式)
使用postForObject()實(shí)現(xiàn):
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
LoginParams loginParams = new LoginParams();
loginParams.setUsername("zhangsan");
loginParams.setPassword("123456");
HttpEntity<LoginParams> request = new HttpEntity<>(loginParams, headers);
String url = "https://www.example.com/login";
String response = restTemplate.postForObject(url, request, String.class);
System.out.println(response);
LoginParams的定義如下所示:
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class LoginParams {
private String username;
private String password;
}
假設(shè)以上接口返回的報(bào)文為:
{
"code": 200,
"expire": "2025-04-11 14:42:22",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDQzNTM3NDIsImlkZW50aXR5"
}
也可以直接解析為自定義的類型:
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class LoginResponse {
private Integer code;
private String expire;
private String token;
}
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
LoginParams loginParams = new LoginParams();
loginParams.setUsername("zhangsan");
loginParams.setPassword("123456");
HttpEntity<LoginParams> request = new HttpEntity<>(loginParams, headers);
String url = "https://www.example.com/login";
LoginResponse response = restTemplate.postForObject(url, request, LoginResponse.class);
System.out.println(JSON.toJSONString(response));
也可以使用postForEntity()實(shí)現(xiàn)同樣的功能,代碼如下所示:
ResponseEntity<LoginResponse> responseEntity = restTemplate.postForEntity(url, request, LoginResponse.class);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
LoginResponse response = responseEntity.getBody();
System.out.println(JSON.toJSONString(response));
}
3.2 發(fā)送POST請(qǐng)求(帶參數(shù)、form表單方式)
使用postForObject()實(shí)現(xiàn):
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("username", "zhangsan");
map.add("password", "123456");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
String url = "https://www.example.com/login";
LoginResponse response = restTemplate.postForObject(url, request, LoginResponse.class);
System.out.println(JSON.toJSONString(response));
也可以使用postForEntity()實(shí)現(xiàn)同樣的功能,代碼如下所示:
ResponseEntity<LoginResponse> responseEntity = restTemplate.postForEntity(url, request, LoginResponse.class);
if (responseEntity.getStatusCode() == HttpStatus.OK) {
LoginResponse response = responseEntity.getBody();
System.out.println(JSON.toJSONString(response));
}
3.3 postForObject與postForEntity的區(qū)別
postForObject()與postForEntity()的區(qū)別,與getForEntity()與getForObject()的區(qū)別一樣,
返回值用了ResponseEntity進(jìn)行封裝。
4. 超時(shí)時(shí)間設(shè)置
如果需要自定義HTTP請(qǐng)求的連接超時(shí)時(shí)間和數(shù)據(jù)傳輸超時(shí)時(shí)間,代碼如下所示:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Value("${restTemplate.connectTimeout:5000}")
private int connectTimeout;
@Value("${restTemplate.readTimeout:10000}")
private int readTimeout;
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
simpleClientHttpRequestFactory.setConnectTimeout(connectTimeout);
simpleClientHttpRequestFactory.setReadTimeout(readTimeout);
return new RestTemplate(simpleClientHttpRequestFactory);
}
}
文章持續(xù)更新,歡迎關(guān)注微信公眾號(hào)「申城異鄉(xiāng)人」第一時(shí)間閱讀!
浙公網(wǎng)安備 33010602011771號(hào)