Spring RestTemplate使用方法总结

[复制链接]
发表于 2025-4-11 09:21:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1. 引入依赖

首先,需要确认项目中是否直接大概间接引入过spring-web依赖,如果没有引入过,需要在pom.xml中添加以下代码引入依赖:
  1. <dependency>
  2.     <groupId>org.springframework</groupId>
  3.     <artifactId>spring-web</artifactId>
  4.     <version>4.3.24.RELEASE</version>
  5. </dependency>
复制代码
2. 发送GET请求

使用RestTemplate发送GET请求主要有getForObject()和getForEntity()2个方法,每个方法分别提供了3种不同的重载。
2.1 使用getForObject发送GET请求(无参数)

使用getForObject()实现:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String url = "https://www.example.com/getCurrentEnv";
  3. String response = restTemplate.getForObject(url, String.class);
  4. System.out.println(response);
复制代码
假设以上接口返回的报文为:
  1. {
  2.     "serverAddress": "www.example.dev.com",
  3.     "env": "dev"
  4. }
复制代码
也可以直接解析为自定义的范例:
  1. import lombok.Getter;
  2. import lombok.Setter;
  3. @Getter
  4. @Setter
  5. public class EnvInfo {
  6.     private String serverAddress;
  7.     private String env;
  8. }
复制代码
  1. RestTemplate restTemplate = new RestTemplate();
  2. String url = "https://www.example.com/getCurrentEnv";
  3. EnvInfo response = restTemplate.getForObject(url, EnvInfo.class);
  4. System.out.println(JSON.toJSONString(response));
复制代码
2.2 使用getForEntity发送GET请求(无参数)

也可以使用getForEntity()实现和2.1同样的功能,代码如下所示:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String url = "https://www.example.com/getCurrentEnv";
  3. ResponseEntity<EnvInfo> responseEntity = restTemplate.getForEntity(url, EnvInfo.class);
  4. if (responseEntity.getStatusCode() == HttpStatus.OK) {
  5.     EnvInfo response = responseEntity.getBody();
  6.     System.out.println(JSON.toJSONString(response));
  7. }
复制代码
2.3 使用getForObject发送GET请求(带参数)

第一种方法是直接在url上拼接上参数,如下所示:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String url = "https://www.example.com/getDataList?pageIndex=1&pageSize=20";
  3. EnvInfo response = restTemplate.getForObject(url, EnvInfo.class);
  4. System.out.println(JSON.toJSONString(response));
复制代码
第二种方法是使用占位符添加参数,如下所示:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String url = "https://www.example.com/getDataList?pageIndex={1}&pageSize={2}";
  3. EnvInfo response = restTemplate.getForObject(url, EnvInfo.class, 1, 20);
  4. System.out.println(JSON.toJSONString(response));
复制代码
以上代码也可以替换为:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String url = "https://www.example.com/getDataList?pageIndex={pageIndex}&pageSize={pageSize}";
  3. Map<String, String> uriVariables = new HashMap<>();
  4. uriVariables.put("pageIndex", "1");
  5. uriVariables.put("pageSize", "20");
  6. EnvInfo response = restTemplate.getForObject(url, EnvInfo.class, uriVariables);
  7. System.out.println(JSON.toJSONString(response));
复制代码
留意事项:
uriVariables中的key必须和url中的占位符名称一致,否则会抛出非常:
java.lang.IllegalArgumentException: Map has no value for 'pageIndex'
第三种方法是使用UriComponentsBuilder添加参数,该种方法相比于前两种方法更加机动,可以实现动态添加参数,代码如下所示:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String httpUrl = "https://www.example.com/getDataList";
  3. UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl);
  4. uriComponentsBuilder.queryParam("pageIndex", 1);
  5. uriComponentsBuilder.queryParam("pageSize", 20);
  6. String url = uriComponentsBuilder.toUriString();
  7. EnvInfo response = restTemplate.getForObject(url, EnvInfo.class);
  8. System.out.println(JSON.toJSONString(response));
复制代码
2.4 使用getForEntity发送GET请求(带参数)

也可以使用getForEntity()实现和2.3同样的功能,代码如下所示:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String httpUrl = "https://www.example.com/getDataList";
  3. UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl);
  4. uriComponentsBuilder.queryParam("pageIndex", 1);
  5. uriComponentsBuilder.queryParam("pageSize", 20);
  6. String url = uriComponentsBuilder.toUriString();
  7. ResponseEntity<EnvInfo> responseEntity = restTemplate.getForEntity(url, EnvInfo.class);
  8. if (responseEntity.getStatusCode() == HttpStatus.OK) {
  9.     EnvInfo response = responseEntity.getBody();
  10.     System.out.println(JSON.toJSONString(response));
  11. }
复制代码
2.5 getForObject与getForEntity的区别

getForEntity()与getForObject()相比,返回值用了ResponseEntity进行封装,可以多获取到以下2种信息:

  • HTTP状态码
  • Response Headers
代码示例:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String httpUrl = "https://www.example.com/getDataList";
  3. UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl);
  4. uriComponentsBuilder.queryParam("pageIndex", 1);
  5. uriComponentsBuilder.queryParam("pageSize", 20);
  6. String url = uriComponentsBuilder.toUriString();
  7. ResponseEntity<EnvInfo> responseEntity = restTemplate.getForEntity(url, EnvInfo.class);
  8. System.out.println("statusCode: " + responseEntity.getStatusCode().toString());
  9. System.out.println("statusCodeValue: " + responseEntity.getStatusCodeValue());
  10. responseEntity.getHeaders().forEach((key, values) -> {
  11.     System.out.println(key + ": " + values);
  12. });
复制代码
输出结果:
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 发送GET请求(带参数及请求头)

一般情况下,请求第三方接口都需要签名、时间戳等请求头,但getForObject()和getForEntity()都不支持,
此时需要使用exchange()方法,代码如下所示:
  1. RestTemplate restTemplate = new RestTemplate();
  2. String httpUrl = "https://www.example.com/getDataList";
  3. UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl);
  4. uriComponentsBuilder.queryParam("pageIndex", 1);
  5. uriComponentsBuilder.queryParam("pageSize", 20);
  6. HttpHeaders headers = new HttpHeaders();
  7. headers.set("signature", "3045022100875efcef9eb54626bb0168a6baa7c61265d0001d49243f");
  8. headers.set("timestamp", String.valueOf(System.currentTimeMillis()));
  9. String url = uriComponentsBuilder.toUriString();
  10. ResponseEntity<EnvInfo> responseEntity = restTemplate.exchange(url,
  11.         HttpMethod.GET,
  12.         new HttpEntity<>(headers),
  13.         EnvInfo.class);
  14. if (responseEntity.getStatusCode() == HttpStatus.OK) {
  15.     EnvInfo response = responseEntity.getBody();
  16.     System.out.println(JSON.toJSONString(response));
  17. }
复制代码
3. 发送POST请求

使用RestTemplate发送POST请求主要有postForObject()和postForEntity()2个方法,每个方法分别提供了3种不同的重载。
3.1 发送POST请求(带参数、json方式)

使用postForObject()实现:
  1. RestTemplate restTemplate = new RestTemplate();
  2. HttpHeaders headers = new HttpHeaders();
  3. headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
  4. LoginParams loginParams = new LoginParams();
  5. loginParams.setUsername("zhangsan");
  6. loginParams.setPassword("123456");
  7. HttpEntity<LoginParams> request = new HttpEntity<>(loginParams, headers);
  8. String url = "https://www.example.com/login";
  9. String response = restTemplate.postForObject(url, request, String.class);
  10. System.out.println(response);
复制代码
LoginParams的定义如下所示:
  1. import lombok.Getter;
  2. import lombok.Setter;
  3. @Getter
  4. @Setter
  5. public class LoginParams {
  6.     private String username;
  7.     private String password;
  8. }
复制代码
假设以上接口返回的报文为:
  1. {
  2.     "code": 200,
  3.     "expire": "2025-04-11 14:42:22",
  4.     "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDQzNTM3NDIsImlkZW50aXR5"
  5. }
复制代码
也可以直接解析为自定义的范例:
  1. import lombok.Getter;
  2. import lombok.Setter;
  3. @Getter
  4. @Setter
  5. public class LoginResponse {
  6.     private Integer code;
  7.     private String expire;
  8.     private String token;
  9. }
复制代码
  1. RestTemplate restTemplate = new RestTemplate();
  2. HttpHeaders headers = new HttpHeaders();
  3. headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
  4. LoginParams loginParams = new LoginParams();
  5. loginParams.setUsername("zhangsan");
  6. loginParams.setPassword("123456");
  7. HttpEntity<LoginParams> request = new HttpEntity<>(loginParams, headers);
  8. String url = "https://www.example.com/login";
  9. LoginResponse response = restTemplate.postForObject(url, request, LoginResponse.class);
  10. System.out.println(JSON.toJSONString(response));
复制代码
也可以使用postForEntity()实现同样的功能,代码如下所示:
  1. ResponseEntity<LoginResponse> responseEntity = restTemplate.postForEntity(url, request, LoginResponse.class);
  2. if (responseEntity.getStatusCode() == HttpStatus.OK) {
  3.     LoginResponse response = responseEntity.getBody();
  4.     System.out.println(JSON.toJSONString(response));
  5. }
复制代码
3.2 发送POST请求(带参数、form表单方式)

使用postForObject()实现:
  1. RestTemplate restTemplate = new RestTemplate();
  2. HttpHeaders headers = new HttpHeaders();
  3. headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
  4. MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
  5. map.add("username", "zhangsan");
  6. map.add("password", "123456");
  7. HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
  8. String url = "https://www.example.com/login";
  9. LoginResponse response = restTemplate.postForObject(url, request, LoginResponse.class);
  10. System.out.println(JSON.toJSONString(response));
复制代码
也可以使用postForEntity()实现同样的功能,代码如下所示:
  1. ResponseEntity<LoginResponse> responseEntity = restTemplate.postForEntity(url, request, LoginResponse.class);
  2. if (responseEntity.getStatusCode() == HttpStatus.OK) {
  3.     LoginResponse response = responseEntity.getBody();
  4.     System.out.println(JSON.toJSONString(response));
  5. }
复制代码
3.3 postForObject与postForEntity的区别

postForObject()与postForEntity()的区别,与getForEntity()与getForObject()的区别一样,
返回值用了ResponseEntity进行封装。
4. 超时时间设置

如果需要自定义HTTP请求的毗连超时时间和数据传输超时时间,代码如下所示:
[code]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);
    }
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表