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  
);
相关推荐
小曲程序2 分钟前
vue3 封装request请求
java·前端·typescript·vue
陈王卜19 分钟前
django+boostrap实现发布博客权限控制
java·前端·django
小码的头发丝、20 分钟前
Spring Boot 注解
java·spring boot
午觉千万别睡过22 分钟前
RuoYI分页不准确问题解决
spring boot
java亮小白199725 分钟前
Spring循环依赖如何解决的?
java·后端·spring
飞滕人生TYF31 分钟前
java Queue 详解
java·队列
2301_8112743141 分钟前
大数据基于Spring Boot的化妆品推荐系统的设计与实现
大数据·spring boot·后端
武子康1 小时前
大数据-230 离线数仓 - ODS层的构建 Hive处理 UDF 与 SerDe 处理 与 当前总结
java·大数据·数据仓库·hive·hadoop·sql·hdfs
武子康1 小时前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
苏-言1 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring