【springboot应用-RestTemplate】

news2024/10/25 1:28:58

简介

RestTemplate 提供了一个高层次的抽象来访问 HTTP 资源,支持通过模板方法执行常见的 HTTP 请求操作,如 GET、POST、PUT、DELETE 等。它简化了与 HTTP 服务的交互,使得代码更简洁、易读。

功能特点

  • 多种请求方式:支持 GET、POST、PUT、DELETE 等多种 HTTP 方法。
  • 连接管理:内部使用连接池来管理 HTTP 连接,提高性能。
  • 错误处理:提供了异常处理机制,方便错误管理。
  • 消息转换:支持多种消息转换方式,如 JSON、XML 等。
  • 模板方法:提供了模板方法来简化请求参数的设置。

使用步骤

  1. 添加依赖
    如果您使用的是 Maven,确保在 pom.xml 文件中添加了 Spring Web 依赖:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.10</version>
</dependency>
  1. 创建 RestTemplate 实例
@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}
  1. 执行 GET 请求
    使用 RestTemplate 发送 GET 请求并接收响应:
String url = "http://example.com/api/data";
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
String responseBody = response.getBody();
  1. 执行 POST 请求
    发送一个包含请求体的 POST 请求:
MyRequestData data = new MyRequestData();
data.setName("lixiaoyi");
ResponseEntity<MyResponseData> response = restTemplate.postForEntity(url, data, MyResponseData.class);
MyResponseData responseBody = response.getBody();
  1. 配置请求
    可以配置 RestTemplate 以自定义连接工厂、消息转换器等:
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(5000);
restTemplate.setRequestFactory(factory);
  1. 异常处理
    RestTemplate 可能会抛出 RestClientException,您可以捕获并处理这个异常:
try {
    restTemplate.getForObject(url, String.class);
} catch (RestClientException e) {
    // 处理异常
}

注意事项

  • 异常处理:RestTemplate 抛出的异常应该被捕获并适当处理。
  • 线程安全:RestTemplate 是线程安全的,可以在多个线程中使用同一个实例。
  • 响应类型:在定义响应类型时,确保与返回的数据类型匹配。

实战项目

封装请求工具类

  • RestUtil
/**
     * RestAPI 调用器
     */
    private final static RestTemplate RT;

    static {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(30000);
        requestFactory.setReadTimeout(4000000);
        RT = new RestTemplate(requestFactory);
        // 解决乱码问题
        RT.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        // 新增个性化日志
        List<ClientHttpRequestInterceptor> interceptors = Optional.ofNullable(RT.getInterceptors()).orElse(new ArrayList<>());
        RestTemplateLogInterceptor restTemplateLogInterceptor = SpringContextUtils.getBean(RestTemplateLogInterceptor.class);
        interceptors.add(restTemplateLogInterceptor);
        RT.setInterceptors(interceptors);
    }

    public static RestTemplate getRestTemplate() {
        return RT;
    }
    
 	public static <T> ResponseEntity<T> request(String url, HttpMethod method, HttpHeaders headers, JSONObject variables, JSONObject params, Class<T> responseType) {
        if (StringUtils.isEmpty(url)) {
            throw new RuntimeException("url 不能为空");
        }
        if (method == null) {
            throw new RuntimeException("method 不能为空");
        }
        if (headers == null) {
            headers = new HttpHeaders();
        }
        // 请求体
        String body = "";
        if (params != null) {
            body = JSONArray.toJSONString(params, SerializerFeature.WriteMapNullValue);
        }
        // 拼接 url 参数
        if (variables != null) {
            url += ("?" + asUrlVariables(variables));
        }
        // 发送请求
        HttpEntity<String> request = new HttpEntity<>(body, headers);
        return RT.exchange(url, method, request, responseType);
    }
  • RestTemplateLogInterceptor 定义的抽象接口,实现交给各个业务模块
/**
 * @author: lixiaoyi
 * @date: 2024年10月20日20:09:03
 * @description: 记录restTemplate日志 , 实现交给各个模块
 */
public interface RestTemplateLogInterceptor extends ClientHttpRequestInterceptor {
}

  • LoggingInterceptor 日志实现
@Component
public class LoggingInterceptor implements RestTemplateLogInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        ClientHttpResponse response = execution.execute(request, body);
        try {
            // 记录日志
            ApiForOtherRestUtil.saveLog(request.getURI().toString(), getRequest(request,body), getResponseBody(response));
        }catch (Exception e){
            e.printStackTrace();
        }
        return response;
    }

    private String getRequest(HttpRequest request, byte[] body) {
        // 记录请求方法、URL、头信息和请求体
        return new String(body);
    }

    private String getResponseBody(ClientHttpResponse response) throws IOException {
        InputStream inputStream = response.getBody();
        // 记录响应状态码、头信息和响应体
        StringBuilder responseBody = new StringBuilder();
        // 使用try-with-resources语句自动关闭流
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                responseBody.append(line).append(System.lineSeparator());
            }
        } catch (IOException e) {
            // 处理或记录异常
            e.printStackTrace();
        }
        // 打印响应状态码和响应体
        return responseBody.toString();
    }
}

和HttpClient 对比

  • RestTemplate 优势
    • 集成性:RestTemplate 是 Spring 框架的一部分,与 Spring 框架集成良好,提供了多种便捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率
    • 易用性:RestTemplate 提供了同步的 API 来发送 HTTP 请求,使用起来相对简单,适合快速开发。
      模板方法:提供了模板方法来简化请求参数的设置,使得代码更加简洁。
      错误处理:提供了异常处理机制,方便错误管理。
  • RestTemplate 劣势
    • 性能:默认情况下,RestTemplate 使用 HttpURLConnection,没有连接池,性能相对较低。
    • 非异步:RestTemplate 是同步的,不适合需要异步处理的场景。
    • 资源管理:需要手动管理连接的关闭,否则可能会导致资源泄露。
  • HttpClient 优势
    • 连接池:HttpClient 支持连接池,可以提高频繁请求的性能。
    • 异步支持:HttpClient 支持异步请求,适合需要异步处理的场景。
    • 配置灵活:HttpClient 提供了灵活的配置选项,包括超时设置、重试策略等。
    • 协议支持:HttpClient 支持多种 HTTP 协议的方法,包括但不限于 GET、POST、PUT、DELETE 等。
  • HttpClient 劣势
    • 复杂性:HttpClient 的 API 相对复杂,需要更多的配置和手动管理。
    • 资源管理:虽然支持连接池,但也意味着需要正确管理资源,否则可能会导致资源泄露。
    • 社区活跃度:由于 Android 等平台的更新,HttpClient 的社区活跃度有所下降,一些新的优化和改进可能不如其他库及时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2222853.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

未来医疗:大语言模型如何改变临床实践、研究和教育|文献精析·24-10-23

小罗碎碎念 这篇文章探讨了大型语言模型在医学领域的潜在应用和挑战&#xff0c;并讨论了它们在临床实践、医学研究和医学教育中的未来发展。 姓名单位名称&#xff08;中文&#xff09;Jan Clusmann德国德累斯顿工业大学埃尔朗根弗雷斯尼乌斯中心数字化健康研究所Jakob Nikola…

html 轮播图效果

轮播效果&#xff1a; 1、鼠标没有移入到banner,自动轮播 2、鼠标移入&#xff1a;取消自动轮播、移除开始自动轮播 3、点击指示点开始轮播到对应位置 4、点击前一个后一个按钮&#xff0c;轮播到上一个下一个图片 注意 最后一个图片无缝滚动&#xff0c;就是先克隆第一个图片…

动态量化:大模型在端侧CPU快速推理方案

作为一款高性能的推理引擎框架&#xff0c;MNN高度关注Transformer模型在移动端的部署并持续探索优化大模型在端侧的推理方案。本文介绍权重量化的模型在MNN CPU后端的推理方案&#xff1a;动态量化。动态量化指在运行时对浮点型feature map数据进行8bit量化&#xff0c;然后与…

(gersemi) CMake 格式化工具

文章目录 &#x1f9ee;介绍&#x1f9ee;安装&#x1f9ee;使用&#x1f5f3;️模式 modes&#x1f5f3;️样式配置 config ⭐END&#x1f31f;help&#x1f31f;交流方式 &#x1f9ee;介绍 BlankSpruce/gersemi: A formatter to make your CMake code the real treasure A f…

Leetcode 最长公共前缀

java solution class Solution {public String longestCommonPrefix(String[] strs) {if(strs null || strs.length 0) {return "";}//用第一个字符串作为模板,利用indexOf()方法匹配,由右至左逐渐缩短第一个字符串的长度String prefix strs[0];for(int i 1; i …

【Java】反射概述与详解

目录 引言 一、概述 二、获取Class对象 三、反射获取构造方法 代码示例&#xff1a; 四、反射获取成员变量 代码示例&#xff1a; 五、反射获取成员方法 代码示例&#xff1a; 结语 引言 Java中的反射&#xff08;Reflection&#xff09;是一种强大的机制&#…

热门的四款PDF合并工具大比拼!!!

在现代的数字化办公环境中&#xff0c;PDF文件已经成为了一种重要的文件格式&#xff0c;用于保存和共享各种类型的文档。然而&#xff0c;有时候我们需要将多个PDF文件合并成一个文件&#xff0c;这时候就离不开好用的PDF合并工具了。选择一个好的PDF合并工具是一个长期的投资…

Python基于OpenCV的实时疲劳检测

2.检测方法 1&#xff09;方法 与用于计算眨眼的传统图像处理方法不同&#xff0c;该方法通常涉及以下几种组合&#xff1a; 1、眼睛定位。 2、阈值找到眼睛的白色。 3、确定眼睛的“白色”区域是否消失了一段时间&#xff08;表示眨眼&#xff09;。 相反&#xff0c;眼睛长…

【Power Query】List.Select 筛选列表

List.Select 筛选列表 ——在列表中返回满足条件的元素 List.Select(列表,判断条件) 不是列表的可以转成列表再筛选&#xff0c;例如 Record.ToList 不同场景的判断条件参考写法 (1)单条件筛选 列表中小于50的数字 List.Select({1,99,8,98,5},each _<50) (2)多条件筛…

红黑树(Java数据结构)

前言&#xff1a; 红黑树的学习需要大家对二叉搜索树与AVL树有深刻的理解&#xff0c;如果话没有看过我对二叉搜索树与AVL树的讲解的铁子们可以先看看上一篇文章&#xff1a;二叉搜索树与AVL树(java数据结构)-CSDN博客 红黑树&#xff1a; 什么是红黑树&#xff1f; 红黑树&a…

CenterTrack算法详解

背景&#xff1a; 早期追踪器在缺乏强的低水平线索下&#xff0c;容易失败检测后跟踪的模型依赖于检测器&#xff0c;且需要一个单独的阶段匹配关联策略的时间长 简介&#xff1a; 基于点的跟踪思想&#xff0c;通过预测目标的中心点来进行跟踪&#xff0c;同时实现检测与跟…

LLM在Reranker任务上的最佳实践?A simple experiment report(with code)

知乎&#xff1a;车中草同学(已授权)链接&#xff1a;https://zhuanlan.zhihu.com/p/987727357 引言 在BERT时代&#xff0c;对于Reranker任务&#xff0c;我们使用encoder-only的BERT为基座&#xff0c;拼接query和doc输入到BERT中去&#xff0c;在使用CLS的向量通过一个MLP&a…

身份证识别JAVA+OPENCV+OCR

一、相关的地址 https://github.com/tesseract-ocr/tessdata Releases - OpenCV opencv要装好&#xff0c;我装的是4.5.3的&#xff0c;最新版的没试过。 tessdata就下载了需要用的。好像还有best和fast的版本&#xff0c;我试了一下报错&#xff0c;不知道是不是版本不支持…

华为配置 之 远程管理配置

目录 简介&#xff1a; 知识点&#xff1a; Telnet远程管理 &#xff08;1&#xff09;配置接口IP并确保R1和R2处于同一个网段 &#xff08;2&#xff09;使用password认证模式远程登录 &#xff08;3&#xff09;使用AAA认证模式远程登录 SSH远程管理 &#xff08;1&a…

基于springboot的网上服装商城推荐系统的设计与实现

基于springboot的网上服装商城推荐系统的设计与实现 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;idea 源码获取&#xf…

【deathStarBench】2.安装k8s集群

安装docker 通过以下命令安装docker&#xff1a; sudo yum install docker-ce-26.1.4 docker-ce-cli-26.1.4 containerd.io随后通过查看docker --version&#xff0c;可以确定是否安装的版本一样 启动docker systemctl start docker && systemctl enable docker.se…

《纳瓦尔宝典:财富和幸福指南》读书随笔

最近在罗胖的得到听书中听到一本书&#xff0c;感觉很有启发&#xff0c;书的名字叫《纳瓦尔宝典》&#xff0c;从书名上看给人的感觉应该财富知识类、鸡汤爆棚哪类。纳瓦尔&#xff0c;这个名字之前确实没有听说过&#xff0c;用一句话介绍一下&#xff0c;一个印度裔的硅谷中…

【LeetCode】修炼之路-0006-Zigzag Conversion (Z 字形变换)【python】

题目 The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line: “PAHNAPLSIIGYIR” …

荣耀电脑管家-系统重装之查询设备序列号

winr输入cmd&#xff0c;再命令行中输入 wmic bios get serialnumber 如下所示

代码随想录算法训练营第六天|454四数相加II、 383赎金信、15三数之和、18四数之和

day06 1. 454四数相加II 首先定义 一个unordered_map&#xff0c;key放a和b两数之和&#xff0c;value 放a和b两数之和出现的次数。遍历大A和大B数组&#xff0c;统计两个数组元素之和&#xff0c;和出现的次数&#xff0c;放到map中。定义int变量count&#xff0c;用来统计 …