SpringBoot3 RestTemplate配置与使用详解

 更新时间:2024年12月02日 10:01:13   作者:CoderJia_  
本文详细介绍了在 SpringBoot 3.x 中如何配置和使用 RestTemplate,包括基本配置、高级配置以及各种使用场景,感兴趣的朋友跟随小编一起看看吧

1. 简介

RestTemplate 是 Spring 框架提供的一个用于发送 HTTP 请求的同步客户端工具类。在 SpringBoot 3.x 版本中,我们依然可以使用 RestTemplate 来进行 REST API 的调用。本文将详细介绍如何在 SpringBoot 3 项目中配置和使用 RestTemplate。

2. 环境要求

  • JDK 17+
  • Spring Boot 3.x
  • Maven/Gradle

3. 基础配置

3.1 添加依赖

首先在pom.xml中添加相关依赖:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

3.2 RestTemplate配置类

创建一个配置类来注册RestTemplate Bean:

package com.coderjia.springboot304web.config;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import java.time.Duration;
/**
 * @author CoderJia
 * @create 2024/12/1 下午 04:24
 * @Description
 **/
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder
                .setConnectTimeout(Duration.ofSeconds(5))
                .setReadTimeout(Duration.ofSeconds(5))
                .build();
    }
}

4. 高级配置

4.1 自定义连接池配置

为了提高性能,我们可以使用 Apache HttpClient 连接池:

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.2.1</version>
</dependency>

配置连接池:

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(200);             // 最大连接数为 200
        connectionManager.setDefaultMaxPerRoute(20);    // 每个路由的最大连接数为 20
        CloseableHttpClient httpClient = HttpClients.custom()   // 建 HTTP 客户端
                .setConnectionManager(connectionManager)
                .build();
        // 创建请求工
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
        // 返回 RestTemplate
        return new RestTemplate(factory);
    }
}

4.2 错误处理配置

自定义错误处理器:

public class CustomResponseErrorHandler implements ResponseErrorHandler {
    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return response.getStatusCode().is4xxClientError() || 
               response.getStatusCode().is5xxServerError();
    }
    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        if (response.getStatusCode().is5xxServerError()) {
            throw new RuntimeException("服务器错误: " + response.getStatusCode());
        } else if (response.getStatusCode().is4xxClientError()) {
            throw new RuntimeException("客户端错误: " + response.getStatusCode());
        }
    }
}

将错误处理器添加到 RestTemplate:

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder
                .errorHandler(new CustomResponseErrorHandler())
                .build();
    }

5. 使用示例

5.1 RestTemplate方法列表

方法组描述
getForObject通过GET请求获取资源的表示形式
getForEntity通过GET请求获取ResponseEntity(包含状态码、请求头和响应体)
headForHeaders通过HEAD请求获取资源的所有请求头信息
postForLocation通过POST请求创建新资源,并返回响应中的Location头信息
postForObject通过POST请求创建新资源,并返回响应的表示形式
postForEntity通过POST请求创建新资源,并返回响应的表示形式(包含完整的响应信息)
put通过PUT请求创建或更新资源
patchForObject通过PATCH请求更新资源并返回响应的表示形式(注意:JDK的HttpURLConnection不支持PATCH,但Apache HttpComponents等支持)
delete通过DELETE请求删除指定URI的资源
optionsForAllow通过ALLOW请求获取资源支持的HTTP方法
exchange更通用(且更灵活)的方法版本,提供额外的灵活性。接受RequestEntity作为输入(包括HTTP方法、URL、请求头和请求体),返回ResponseEntity。这些方法允许使用ParameterizedTypeReference代替Class来指定带有泛型的响应类型
execute执行请求的最通用方式,通过回调接口可以完全控制请求准备和响应提取过程

这个表格展示了 RestTemplate 提供的所有主要方法,每个方法都有其特定的用途和场景。从简单的GET请求到复杂的自定义请求处理,RestTemplate 都提供了相应的支持。

5.2 基本使用

@Slf4j
@RestController
public class RestTemplateController {
    @Resource
    private RestTemplate restTemplate;
    // get
    @GetMapping("/get")
    public JSONObject get(@RequestParam("q1")String q1, @RequestParam("q2")String q2) {
        log.info("get");
        String url = "https://echo.apifox.com/get";
        return restTemplate.getForObject(url, JSONObject.class, q1, q2);
    }
    // post
    @GetMapping("/post")
    public JSONObject post(@RequestParam("q1")String q1, @RequestParam("q2")String q2) {
        log.info("post");
        String url = "https://echo.apifox.com/post";
        JSONObject body = new JSONObject();
        body.put("q1", q1);
        body.put("q2", q2);
        return restTemplate.postForObject(url, body, JSONObject.class);
    }
    // delete
    @GetMapping("/delete")
    public String delete(@RequestParam("id") Long id) {
        log.info("delete");
        String url = "https://echo.apifox.com/delete";
        restTemplate.delete(url, id);
        return "Data deleted successfully!";
    }
    // put
    @GetMapping("/put")
    public String put(@RequestParam("id") Long id, @RequestParam("name") String name) {
        log.info("put");
        String url = "https://echo.apifox.com/put";
        JSONObject body = new JSONObject();
        body.put("id", id);
        body.put("name", name);
        restTemplate.put(url, body, id);
        return "Data updated successfully!";
    }
}

请求响应

5.3 使用请求头

public User getUserWithHeaders(Long id) {
    String url = "http://api.example.com/users/{id}";
    HttpHeaders headers = new HttpHeaders();
    headers.set("Authorization", "Bearer token123");
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<String> entity = new HttpEntity<>(headers);
    ResponseEntity<User> response = restTemplate.exchange(
        url,
        HttpMethod.GET,
        entity,
        User.class,
        id
    );
    return response.getBody();
}

使用请求头

5.4 处理复杂响应

    @GetMapping("/getAnyThing")
    public JSONObject getList(@RequestParam("q1")String q1, @RequestParam("q2")String q2) {
        log.info("getAnyThing");
        String url = "https://echo.apifox.com/post";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("q1", q1);
        jsonObject.put("q2", q2);
        HttpEntity<JSONObject> entity = new HttpEntity<>(jsonObject);
        // 定义了一个泛型类型的引用 typeRef,用于指定 restTemplate.exchange 方法返回的响应体类型为 JSONObject。
        ParameterizedTypeReference<JSONObject> typeRef = new ParameterizedTypeReference<>() {
        };
        ResponseEntity<JSONObject> response = restTemplate.exchange(
                url,
                HttpMethod.POST,
                entity,
                typeRef
        );
        return response.getBody();
    }

处理复杂响应

5.5 打印日志拦截器

package com.coderjia.springboot304web.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.IOException;
/**
 * @author CoderJia
 * @create 2024/12/1 下午 05:02
 * @Description
 **/
@Slf4j
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        log.info("Request: " + request.getMethod() + " " + request.getURI());
        ClientHttpResponse response = execution.execute(request, body);
        log.info("Response: " + response.getStatusCode());
        return response;
    }
}

RestTemplate设置拦截器:

        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new LoggingInterceptor());
        RestTemplate build = builder
                .errorHandler(new CustomResponseErrorHandler())
                .build();
        build.setInterceptors(interceptors);

打印日志

6. 最佳实践

  • 超时设置:始终设置合适的连接超时和读取超时时间。
  • 错误处理:实现自定义的错误处理器来处理异常情况。
  • 连接池:在高并发场景下使用连接池来提升性能。
  • 重试机制:对于不稳定的服务,考虑添加重试机制。
  • 日志记录:添加适当的日志记录来跟踪请求和响应。

7. 注意事项

  • RestTemplate 在 Spring 5.0 之后被标记为维护模式,建议在新项目中考虑使用 WebClient。
  • 在生产环境中,要注意设置合理的超时时间和连接池参数。
  • 处理响应时要注意检查响应状态和错误处理。
  • 使用 HTTPS 时需要适当配置SSL证书。

8. 总结

本文详细介绍了在 SpringBoot 3.x 中如何配置和使用 RestTemplate,包括基本配置、高级配置以及各种使用场景。虽然 RestTemplate 目前处于维护模式,但它仍然是一个稳定且易用的HTTP客户端工具。对于新项目,也可以考虑使用响应式的WebClient作为替代方案。

参考资料

Spring官方文档

SpringBoot官方文档

到此这篇关于SpringBoot3 RestTemplate配置与使用详解的文章就介绍到这了,更多相关SpringBoot3 RestTemplate配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 关键字break和continue的使用说明

    Java 关键字break和continue的使用说明

    这篇文章主要介绍了Java 关键字break和continue的使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • SpringMVC+MyBatis声明式事务管理

    SpringMVC+MyBatis声明式事务管理

    在最近的一个项目中,采用springMVC、mybatis,MySQL、tomcat,事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。Spring Framework对事务管理提供了一致的抽象,
    2015-08-08
  • SpringBoot通过注解监测Controller接口的代码示例

    SpringBoot通过注解监测Controller接口的代码示例

    在Spring Boot中,度量指标(Metrics)是监控和诊断应用性能与行为的重要工具,Spring Boot通过集成Micrometer和Spring Boot Actuator,提供了强大的度量指标收集与暴露功能,本文介绍了SpringBoot通过注解监测Controller接口,需要的朋友可以参考下
    2024-07-07
  • IDEA实现序列化时如何自动生成serialVersionUID的步骤

    IDEA实现序列化时如何自动生成serialVersionUID的步骤

    这篇文章主要介绍了IDEA实现序列化时如何自动生成serialVersionUID的步骤,首先安装GenerateSerialVersionUID插件,当出现添加serialVersionUID选项,选中则会自动生成serialVersionUID,感兴趣的朋友一起学习下吧
    2024-02-02
  • SpringBoot集成jersey打包jar找不到class的处理方法

    SpringBoot集成jersey打包jar找不到class的处理方法

    这篇文章主要介绍了SpringBoot集成jersey打包jar找不到class的处理方法,文中通过代码示例介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-03-03
  • Java中Json字符串直接转换为对象的方法(包括多层List集合)

    Java中Json字符串直接转换为对象的方法(包括多层List集合)

    下面小编就为大家带来一篇Java中Json字符串直接转换为对象的方法(包括多层List集合)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • Java之String.format()方法案例讲解

    Java之String.format()方法案例讲解

    这篇文章主要介绍了Java之String.format()方法案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Java成员变量的隐藏(实例讲解)

    Java成员变量的隐藏(实例讲解)

    下面小编就为大家带来一篇Java成员变量的隐藏(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • MyBatis多表连接查询的实例教程

    MyBatis多表连接查询的实例教程

    这篇文章主要给大家介绍了关于MyBatis多表连接查询的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Springboot中yml文件没有叶子图标的解决

    Springboot中yml文件没有叶子图标的解决

    这篇文章主要介绍了Springboot中yml文件没有叶子图标的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09

最新评论