spring mvc 中 RestTemplate 全面详解及示例


RestTemplate 全面详解及示例


1. RestTemplate 简介
  • 定义:Spring 提供的同步 HTTP 客户端,支持多种 HTTP 方法(GET/POST/PUT/DELETE 等),用于调用 RESTful API。
  • 核心特性
    • 支持请求头、请求体、URI 参数的灵活配置。
    • 可直接返回 ResponseEntity 获取状态码和响应头。
    • 支持对象序列化(如 JSON)和反序列化。
  • 依赖(Spring Boot 项目):
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

2. 示例代码详解

示例 1:GET 请求(带请求头,获取状态码和响应头)
// 1. 创建 RestTemplate 实例
RestTemplate restTemplate = new RestTemplate();// 2. 构建请求 URI(包含路径参数)
String uri = "http://api.example.com/users/{id}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("id", "123");// 3. 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer token_123");
headers.setContentType(MediaType.APPLICATION_JSON);// 4. 发送 GET 请求并获取 ResponseEntity
ResponseEntity<User> response = restTemplate.exchange(uri,HttpMethod.GET,new HttpEntity<>(headers), // 请求体为空,仅传递头User.class, // 响应体反序列化类型uriVariables
);// 5. 处理响应
int statusCode = response.getStatusCodeValue(); // 获取状态码
HttpHeaders responseHeaders = response.getHeaders(); // 获取响应头
User user = response.getBody(); // 获取响应体对象

示例 2:POST 请求(传递 JSON 请求体)
// 1. 创建请求体对象(使用 Jackson 自动序列化)
User newUser = new User("John", 25);// 2. 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);// 3. 创建 HttpEntity(包含头和请求体)
HttpEntity<User> request = new HttpEntity<>(newUser, headers);// 4. 发送 POST 请求
ResponseEntity<String> response = restTemplate.postForEntity("http://api.example.com/users",request,String.class // 返回的响应类型(如成功返回 "Created")
);// 5. 处理响应
String locationHeader = response.getHeaders().getFirst("Location"); // 获取 Location 头

示例 3:PUT/PATCH 请求(更新资源)
// 1. 更新对象
User updatedUser = new User("John Doe", 26);// 2. 构建请求头和请求体
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<User> request = new HttpEntity<>(updatedUser, headers);// 3. 发送 PUT 请求
ResponseEntity<Void> response = restTemplate.exchange("http://api.example.com/users/123",HttpMethod.PUT,request,Void.class // 无响应体时使用 Void
);// 4. 检查状态码
if (response.getStatusCode() == HttpStatus.OK) {System.out.println("Update successful");
}

示例 4:DELETE 请求
// 发送 DELETE 请求
ResponseEntity<Void> response = restTemplate.exchange("http://api.example.com/users/123",HttpMethod.DELETE,null, // 无请求体Void.class
);if (response.getStatusCode() == HttpStatus.NO_CONTENT) {System.out.println("Resource deleted");
}

示例 5:自定义响应类型(如 Map)
// 将响应体反序列化为 Map
ResponseEntity<Map<String, Object>> response = restTemplate.getForEntity("http://api.example.com/data",new ParameterizedTypeReference<Map<String, Object>>() {}
);Map<String, Object> data = response.getBody();

示例 6:使用 ResponseExtractor 定制响应
// 自定义提取器:提取响应体中的某个字段
ResponseExtractor<String> extractor = response -> {if (response.getStatusCode() == HttpStatus.OK) {return response.getHeaders().getFirst("X-Custom-Header"); // 提取自定义头}return null;
};// 使用 exchange 方法
String customHeader = restTemplate.exchange("http://api.example.com/headers",HttpMethod.GET,null,extractor // 传递自定义提取器
);

示例 7:批量操作(查询多个资源)
// 使用 UriComponentsBuilder 构建带查询参数的 URI
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://api.example.com/users").queryParam("page", 1).queryParam("size", 10);// 发送 GET 请求并获取列表
ResponseEntity<User[]> response = restTemplate.getForEntity(builder.toUriString(),User[].class
);User[] users = response.getBody();

3. 核心方法对比表格
方法HTTP 方法返回类型关键代码片段适用场景
getForObjectGET对象(如 User)restTemplate.getForObject(url, User.class);简单 GET 请求,直接返回对象
getForEntityGETResponseEntity<User>restTemplate.getForEntity(url, User.class);需获取状态码或响应头
postForObjectPOST对象(如 String)restTemplate.postForObject(url, request, String.class);POST 请求,直接返回结果
postForEntityPOSTResponseEntity<Void>restTemplate.postForEntity(url, request, Void.class);需检查状态码或 Location 头
exchange任意方法ResponseEntity<?>restTemplate.exchange(url, HttpMethod.POST, request, Class<T>);自定义 HTTP 方法和响应类型
deleteDELETEvoidrestTemplate.delete(url);简单删除操作

4. 关键配置与注意事项
  • 设置连接池(提升性能):

    RestTemplate restTemplate = new RestTemplate(new HttpClientErrorException.Factory(),new HttpComponentsClientHttpRequestFactory()
    );
    
  • 异常处理

    try {// 发送请求
    } catch (HttpClientErrorException e) {System.out.println("Client error: " + e.getStatusCode());
    } catch (HttpServerErrorException e) {System.out.println("Server error: " + e.getStatusCode());
    }
    
  • 自定义序列化器

    ObjectMapper objectMapper = new ObjectMapper();
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setObjectMapper(objectMapper);
    restTemplate.getMessageConverters().add(converter);
    

5. 总结对比表格
需求实现方法关键代码注意事项
发送 JSON 请求体使用 HttpEntity<User>HttpEntity<String>HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON);确保序列化配置正确
获取状态码和响应头返回 ResponseEntity<T>response.getStatusCode(); response.getHeaders();处理 2xx/4xx/5xx 状态码
自定义响应类型使用 ParameterizedTypeReference 或泛型new ParameterizedTypeReference<List<User>>() {}处理复杂泛型类型
响应提取器实现 ResponseExtractor 接口或使用预定义提取器restTemplate.exchange(url, HttpMethod.GET, null, extractor);简化复杂响应处理逻辑

关键总结

  1. 核心类
    • RestTemplate:核心客户端,提供所有 HTTP 方法。
    • HttpEntity:封装请求头和请求体。
    • ResponseEntity:封装响应头、状态码和响应体。
  2. 最佳实践
    • 使用 exchange 方法统一处理复杂场景。
    • 通过 ResponseEntity 获取完整响应信息。
    • 自定义 HttpMessageConverter 处理特殊序列化需求。
  3. 替代方案
    Spring Boot 3.x 已弃用 RestTemplate,推荐使用 WebClient(响应式、非阻塞)。

通过以上示例和配置,开发者可以灵活实现 REST API 的全场景调用需求。

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

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

相关文章

北大:LLM在NL2SQL中任务分解

&#x1f4d6;标题&#xff1a;LearNAT: Learning NL2SQL with AST-guided Task Decomposition for Large Language Models &#x1f310;来源&#xff1a;arXiv, 2504.02327 &#x1f31f;摘要 &#x1f538;自然语言到SQL&#xff08;NL2SQL&#xff09;已成为实现与数据库…

STM32LL库编程系列第八讲——ADC模数转换

系列文章目录 往期文章 STM32LL库编程系列第一讲——Delay精准延时函数&#xff08;详细&#xff0c;适合新手&#xff09; STM32LL库编程系列第二讲——蓝牙USART串口通信&#xff08;步骤详细、原理清晰&#xff09; STM32LL库编程系列第三讲——USARTDMA通信 STM32LL库编程…

网络5 TCP/IP 虚拟机桥接模式、NAT、仅主机模式

TCP/IP模型 用于局域网和广域网&#xff1b;多个协议&#xff1b;每一层呼叫下一层&#xff1b;四层&#xff1b;通用标准 TCP/IP模型 OSI七层模型 应用层 应用层 表示层 会话层 传输层 传输层 网络层 网络层 链路层 数据链路层 物理层 链路层&#xff1a;传数据帧&#xff0…

【C语言】预处理(下)(C语言完结篇)

一、#和## 1、#运算符 这里的#是一个运算符&#xff0c;整个运算符会将宏的参数转换为字符串字面量&#xff0c;它仅可以出现在带参数的宏的替换列表中&#xff0c;我们可以将其理解为字符串化。 我们先看下面的一段代码&#xff1a; 第二个printf中是由两个字符串组成的&am…

【高性能缓存Redis_中间件】一、快速上手redis缓存中间件

一、铺垫 在当今的软件开发领域&#xff0c;消息队列扮演着至关重要的角色。它能够帮助我们实现系统的异步处理、流量削峰以及系统解耦等功能&#xff0c;从而提升系统的性能和可维护性。Redis 作为一款高性能的键值对数据库&#xff0c;不仅提供了丰富的数据结构&#xff0c;…

Java如何获取文件的编码格式?

Java获取文件的编码格式 在计算机中&#xff0c;文件编码是指将文件内容转换成二进制形式以便存储和传输的过程。常见的文件编码格式包括UTF-8、GBK等。不同的编码使用不同的字符集和字节序列&#xff0c;因此在读取文件时需要正确地确定文件的编码格式 Java提供了多种方式以获…

客户端负载均衡与服务器端负载均衡详解

客户端负载均衡与服务器端负载均衡详解 1. 客户端负载均衡&#xff08;Client-Side Load Balancing&#xff09; 核心概念 定义&#xff1a;负载均衡逻辑在客户端实现&#xff0c;客户端主动选择目标服务实例。典型场景&#xff1a;微服务内部调用&#xff08;如Spring Cloud…

Quartus II的IP核调用及仿真测试

目录 第一章 什么是IP核&#xff1f;第二章 什么是LPM&#xff1f;第一节 设置LPM_COUNTER模块参数第二节 仿真 第三章 什么是PLL&#xff1f;第一节 设置ALTPLL&#xff08;嵌入式锁相环&#xff09;模块参数第二节 仿真 第四章 什么是RAM&#xff1f;第一节 RAM_1PORT的调用第…

各地物价和生活成本 东欧篇

东欧地区的物价差异相对较大&#xff0c;一些国家的物价较高&#xff0c;而另一些国家则相对便宜。这些差异主要受当地经济发展水平、工资水平、旅游业发展以及国际关系等因素影响。以下是一些典型的东欧国家&#xff0c;按物价高低进行分类&#xff1a; &#x1f30d; 物价较高…

改进神经风格迁移

改进神经风格迁移&#xff08;Neural Style Transfer, NST&#xff09;可以从多个方向入手&#xff0c;包括模型结构优化、损失函数设计、计算效率提升、应用场景扩展等。以下是一些关键的改进方向及具体方法&#xff1a; 1. 模型结构优化 &#xff08;1&#xff09;轻量化网络…

1、从零搭建魔法工坊:React 19 新手村生存指南

一、开篇&#xff1a;新世界的入场券 "你好&#xff0c;年轻的魔法学徒&#xff01;欢迎来到React魔法世界。我是你的向导赫敏韦斯莱&#xff0c;今天我们将用React 19这根全新魔杖&#xff0c;搭建属于你的第一座魔法工坊。" ——以对话形式开场&#xff0c;消除技…

基于 Redis 实现一套动态配置中心 DCC 服务与反射基础知识讲解

目录 动态配置中心核心价值 轻量级 Redis 方案与 ZooKeeper 的对比分析 为什么选择自定义 Redis 方案&#xff1f; 1. 技术决策背景 一、活动降级拦截 1. 定义与作用 2. 实现原理 二、活动切量拦截 1. 定义与作用 2. 实现原理 三、两者的核心区别 四、实际应用案例 1. 电商大促…

如何从项目目标到成功标准:构建可量化、可落地的项目评估体系

引言 在项目管理领域&#xff0c;"项目成功"的定义往往比表面看起来更复杂。根据PMI的行业报告&#xff0c;67%的项目失败源于目标与成功标准的不匹配。当项目团队仅关注"按时交付"或"预算达标"时&#xff0c;常会忽视真正的价值创造。本文将通…

深度学习基础--CNN经典网络之分组卷积与ResNext网络实验探究(pytorch复现)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 ResNext是分组卷积的开始之作&#xff0c;这里本文将学习ResNext网络&#xff1b;本文复现了ResNext50神经网络&#xff0c;并用其进行了猴痘病分类实验…

SQL 全文检索原理

全文检索(Full-Text Search)是SQL中用于高效搜索文本数据的技术&#xff0c;与传统的LIKE操作或简单字符串比较相比&#xff0c;它能提供更强大、更灵活的文本搜索能力。 基本概念 全文检索的核心思想是将文本内容分解为可索引的单元(通常是词或词组)&#xff0c;然后建立倒排…

【Linux】Orin NX编译 linux 内核及内核模块

1、下载交叉编译工具:gcc 1)下载地址:https://developer.nvidia.com/embedded/jetson-linux 选择TOOLS中的交叉编译工具:gcc 11.3 2)解压 将gcc编译器解压到指定目录中,如:/home/laoer/nvidia/gcc 3)配置环境变量 创建: ~/nvidia/gcc/env.sh添加: #!/bin/bash e…

Transformers 是工具箱,BERT 是工具。

Transformers 是工具箱&#xff0c;BERT 是工具。 &#x1f50d; 详细解释&#xff1a; 名称作用比喻理解举例&#x1f916; transformers&#xff08;库&#xff09;一个框架&#xff0c;提供很多 NLP 模型的“使用方式”&#xff0c;包括文本分类、问答、摘要等相当于一个“…

k8s之Service类型详解

1.ClusterIP 类型 2.NodePort 类型 3.LoadBalancer 类型 4.ExternalName 类型 类型为 ExternalName 的 Service 将 Service 映射到 DNS 名称&#xff0c;而不是典型的选择算符&#xff0c; 例如 my-service 或者 cassandra。你可以使用 spec.externalName 参数指定这些服务…

find指令中使用正则表达式

linux查找命令能结合正则表达式吗 find命令要使用正则表达式需要结合-regex参数 另&#xff0c;-type参数可以指定查找类型(f为文件&#xff0c;d为文件夹) rootlocalhost:~/regular_expression# ls -alh 总计 8.0K drwxr-xr-x. 5 root root 66 4月 8日 16:26 . dr-xr-…

《穿透表象,洞察分布式软总线“无形”之奥秘》

分布式系统已成为众多领域的关键支撑技术&#xff0c;而分布式软总线作为实现设备高效互联的核心技术&#xff0c;正逐渐走入大众视野。它常被描述为一条“无形”的总线&#xff0c;这一独特属性不仅是理解其技术内涵的关键&#xff0c;更是把握其在未来智能世界中重要作用的切…