Springboot 开发之 RestTemplate 简介

一、什么是RestTemplate

RestTemplate 是Spring框架提供的一个用于应用中调用REST服务的类。它简化了与HTTP服务的通信,统一了RESTFul的标准,并封装了HTTP连接,我们只需要传入URL及其返回值类型即可。RestTemplate的设计原则与许多其他Spring的模板类(如JdbcTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。

二、RestTemplate 的常用方法

RestTemplate提供了多种方法来进行HTTP请求,主要方法包括:

1. GET请求:

  • getForObject(String url, Class responseType, Object... uriVariables): 直接返回响应体中的数据。
  • getForEntity(String url, Class responseType, Object... uriVariables): 返回一个ResponseEntity对象,其中包含了响应的详细信息,如状态码、响应头等。

2. POST请求:

  • postForObject(String url, Object request, Class responseType): 发送POST请求,并返回响应体中的数据。
  • postForEntity(String url, Object request, Class responseType): 发送POST请求,并返回一个ResponseEntity对象。

3. PUT请求:

  • put(String url, Object request): 发送PUT请求。
  • putForObject(String url, Object request, Class responseType): 发送PUT请求,并返回响应体中的数据。

4. DELETE请求:

  • delete(String url): 发送DELETE请求。
    其他方法:
  • exchange(RequestEntity<?> request, Class responseType): 这是一个通用的方法,可以根据RequestEntity对象发送请求,并返回ResponseEntity对象。

三、RestTemplate基本使用

1. pom 文件依赖

Spring Boot的 web starter 已经内置了RestTemplate的Bean,我们主需要将它引入到我们的Spring Context中,再进行下简单的配置就可以直接使用了。

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

2. 配置 RestTemplate

(1)默认配置:

RestTemplate默认使用 SimpleClientHttpRequestFactory,内部调用JDK的HttpURLConnection进行HTTP请求,默认的超时时间为-1(即无限期等待)。

java 复制代码
@Configuration  
public class RestClientConfig {  
  
    @Bean  
    public RestTemplate restTemplate(RestTemplateBuilder builder) {  
        return builder.build();  
    }  
  
    // 或者自定义请求工厂  
    @Bean  
    public RestTemplate restTemplate() {  
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();  
        factory.setReadTimeout(5000); // 设置读取超时时间  
        factory.setConnectTimeout(5000); // 设置连接超时时间  
        return new RestTemplate(factory);  
    }  
}

(2)自定义配置:

可以通过设置ClientHttpRequestFactory来自定义RestTemplate的配置,如使用HttpComponentsClientHttpRequestFactory(基于Apache HttpClient)或OkHttp3ClientHttpRequestFactory(基于OkHttp)等。

可以配置连接池、超时时间、请求和响应的编解码等。

java 复制代码
@Configuration
public class RestTemplateConfig {
   @Bean 
    public HttpClientConnectionManager poolingHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        // 设置最大连接数
        poolingHttpClientConnectionManager.setMaxTotal(500);
        // 设置每个路由的最大连接数
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
        return poolingHttpClientConnectionManager;
    }

    @Bean
    public HttpClient httpClient(HttpClientConnectionManager poolingHttpClientConnectionManager) {
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // 设置 HttpClient 的连接管理器
        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
        return httpClientBuilder.build();
    }

    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) {
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        // 设置 HttpClient
        clientHttpRequestFactory.setHttpClient(httpClient);
        // 设置连接超时时间(毫秒)
        clientHttpRequestFactory.setConnectTimeout(5 * 1000);
        // 设置读取超时时间(毫秒)
        clientHttpRequestFactory.setReadTimeout(10 * 1000);
        // 设置从连接池获取连接的超时时间(毫秒)
        clientHttpRequestFactory.setConnectionRequestTimeout(10 * 1000);
        return clientHttpRequestFactory;
    }

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory clientHttpRequestFactory) {
        RestTemplate restTemplate = new RestTemplate();
        // 设置请求工厂
        restTemplate.setRequestFactory(clientHttpRequestFactory);
        return restTemplate;
    }

}

四、服务端代码实战

1. 服务端接口类

java 复制代码
@RestController
public class RestControllerDemo {

	/**
     * 普通Get
     *
     * @param name
     * @return
     */
    @GetMapping("/get")
    private String getMethod(@RequestParam("name") String name) {
        System.out.println("getMethod : name=" + name);
        return name;
    }

    /**
     * Restful Get
     *
     * @param name
     * @return
     */
    @GetMapping("/getName/{name}")
    private String getRestName(@PathVariable("name") String name) {
        System.out.println("getRestName : name=" + name);
        return name;
    }

    /**
     * post
     *
     * @param name
     * @return
     */
    @PostMapping("/post")
    private String postMethod(@RequestParam("name") String name) {
        System.out.println("postMethod : name=" + name);
        return name;
    }

    /**
     * post json
     *
     * @param stu
     * @return
     */
    @PostMapping("/postBody")
    public String postBodyMethod(@RequestBody String stu) {
        Student student = JSONObject.parseObject(stu, Student.class);
        System.out.println("postBodyMethod : student=" + student);
        return student.toString();
    }
}

2. 测试类

java 复制代码
@SpringBootTest
class DemoApplicationTests {
	// 引入 restTemplate
    @Resource
    private RestTemplate restTemplate;

    @Test
    void getTest() {
        String str = restTemplate.getForObject("http://localhost:8888/get?name=zs", String.class);
        System.out.println(str);
    }

    @Test
    void getRestTest() {
        String name = "ls";
        String str = restTemplate.getForObject("http://localhost:8888/getName/" + name, String.class);
        System.out.println(str);
    }

    @Test
    void postTest() {
        LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.set("name", "zs");
        String str = restTemplate.postForObject("http://localhost:8888/post", map, String.class);
        System.out.println(str);
    }

    @Test
    void postBodyTest() {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HashMap<String, Object> map = new HashMap<>();
        map.put("name", "zs");
        map.put("age", 23);
        String stu = JSON.toJSONString(map);
        HttpEntity<String> formEntity = new HttpEntity<String>(stu, headers);
        String str = restTemplate.postForObject("http://localhost:8888/postBody", formEntity, String.class);
        System.out.println(str);
    }

}

3. exchange 使用示例

通过 HttpHeaders 和 UriComponentsBuilder 可以方便地添加自定义请求头和构建带参数的 URL。

java 复制代码
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)  
    .queryParam("param1", "value1")  
    .queryParam("param2", "value2");  
  
String finalUrl = builder.toUriString();  
HttpHeaders headers = new HttpHeaders();  
headers.add("Custom-Header", "HeaderValue");  
HttpEntity<String> request = new HttpEntity<>(null, headers);  
  
ResponseEntity<String> response = restTemplate.exchange(  
    finalUrl,  
    HttpMethod.GET,  
    request,  
    String.class  
);
相关推荐
阿丰资源1 分钟前
SpringBoot+MySQL+MyBatis-Plus+Vue前后端分离仓库管理系统 (附资料)
spring boot·mysql·mybatis
小信丶2 分钟前
Spring Cloud Stream EnableBinding注解详解:定义、应用场景与示例代码
java·spring boot·后端·spring
s1mple“”4 分钟前
互联网大厂Java面试实录:谢飞机的AIGC求职之旅 - JVM并发编程到Spring Cloud微服务
spring boot·aigc·微服务架构·java面试·分布式系统·rag技术·redis数据库
无限进步_6 分钟前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
亚历克斯神7 分钟前
Spring Cloud 2026 架构演进
java·spring·微服务
七夜zippoe10 分钟前
Spring Cloud与Dubbo架构哲学对决
java·spring cloud·架构·dubbo·配置中心
海派程序猿11 分钟前
Spring Cloud Config拉取配置过慢导致服务启动延迟的优化技巧
java
阿维的博客日记21 分钟前
为什么不逃逸代表不需要锁,JIT会直接删掉锁
java
William Dawson23 分钟前
CAS的底层实现
java
ffqws_27 分钟前
Spring Boot入门:通过简单的注册功能串联Controller,Service,Mapper。(含有数据库建立,连接,及一些关键注解的讲解)
数据库·spring boot·后端