当前位置: 首页 > news >正文

关于Spring RestTemplate


一、概述


RestTemplate 是 Spring Framework 提供的一个同步 HTTP 客户端工具,用于简化与 RESTful API 的交互。它封装了底层 HTTP 通信细节,提供了统一的 API 来发送各种 HTTP 请求(GET、POST、PUT、DELETE 等),并自动处理响应数据的序列化和反序列化。

二、依赖配置


如果使用 Maven 项目,需要在 pom.xml 中添加以下依赖:

xml

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

三、基本使用流程

RestTemplate restTemplate = new RestTemplate();

// 示例:发送 GET 请求获取用户信息

String url = "https://api.example.com/users/{id}";
User user = restTemplate.getForObject(url, User.class, 123);

四、HTTP 请求方法详解


1. GET 请求
获取资源的基本方法有两种:

1.1 getForObject() - 直接返回响应体

String url = "https://api.example.com/users/{id}";
User user = restTemplate.getForObject(url, User.class, 123);

参数说明:
url:请求 URL,可以包含占位符(如 {id})
responseType:响应数据类型(通常是实体类)
uriVariables:占位符参数值(可变参数或 Map)
1.2 getForEntity() - 返回完整响应实体

ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, 123);
if (response.getStatusCode() == HttpStatus.OK) {User user = response.getBody();HttpHeaders headers = response.getHeaders();
}

2. POST 请求
用于创建资源,常用方法有三种:

2.1 postForObject() - 直接返回响应体

User newUser = new User("Alice", 25);
String url = "https://api.example.com/users";
User createdUser = restTemplate.postForObject(url, newUser, User.class);

参数说明:
url:请求 URL
request:请求体对象(会自动序列化为 JSON/XML)
responseType:响应数据类型
2.2 postForEntity() - 返回完整响应实体

ResponseEntity<User> response = restTemplate.postForEntity(url, newUser, User.class);

2.3 postForLocation() - 返回新创建资源的 URL

URI location = restTemplate.postForLocation(url, newUser);

3. PUT 请求
用于更新资源(全量更新):

User updatedUser = new User(123, "Bob", 30);
String url = "https://api.example.com/users/{id}";
restTemplate.put(url, updatedUser, 123);

4. DELETE 请求
用于删除资源:

String url = "https://api.example.com/users/{id}";
restTemplate.delete(url, 123);

5. PATCH 请求(部分更新)
使用通用的 exchange() 方法:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

// 创建包含部分更新数据的 Map

Map<String, Object> updates = new HashMap<>();
updates.put("age", 31);HttpEntity<Map<String, Object>> request = new HttpEntity<>(updates, headers);
String url = "https://api.example.com/users/{id}";ResponseEntity<User> response = restTemplate.exchange(url, HttpMethod.PATCH, request, User.class, 123
);

五、处理复杂请求


1. 自定义请求头
使用 HttpEntity 包装请求体和请求头:

HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer token123");
headers.setContentType(MediaType.APPLICATION_JSON);User requestBody = new User("Charlie", 35);
HttpEntity<User> request = new HttpEntity<>(requestBody, headers);String url = "https://api.example.com/secure/users";
ResponseEntity<User> response = restTemplate.exchange(url, HttpMethod.POST, request, User.class);

2. 处理查询参数
使用 UriComponentsBuilder 构建带查询参数的 URL:

UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://api.example.com/users").queryParam("page", 1).queryParam("size", 20).build();String url = uriComponents.toUriString();
ResponseEntity<User[]> response = restTemplate.getForEntity(url, User[].class);

3. 处理文件上传
使用 MultiValueMap 和 HttpEntity:

MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource(new File("path/to/file.jpg")));
body.add("name", "test-file");HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
String url = "https://api.example.com/upload";ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);

六、异常处理


RestTemplate 在遇到 HTTP 错误(4xx/5xx)时会抛出异常:

HttpClientErrorException:4xx 客户端错误
HttpServerErrorException:5xx 服务器错误
ResourceAccessException:网络连接错误
使用 try-catch 块捕获并处理异常:

try {User user = restTemplate.getForObject(url, User.class, 999);
} catch (HttpClientErrorException e) {if (e.getStatusCode() == HttpStatus.NOT_FOUND) {System.out.println("用户不存在");} else if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {System.out.println("未授权访问");}System.out.println("错误响应体: " + e.getResponseBodyAsString());
} catch (HttpServerErrorException e) {System.out.println("服务器内部错误: " + e.getStatusCode());
} catch (ResourceAccessException e) {System.out.println("网络连接失败: " + e.getMessage());
}

七、自定义配置


1. 注册消息转换器

RestTemplate restTemplate = new RestTemplate();
// 添加 JSON 消息转换器(默认使用 Jackson)
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
// 添加 XML 消息转换器
restTemplate.getMessageConverters().add(new Jaxb2RootElementHttpMessageConverter());

2. 配置超时

使用 SimpleClientHttpRequestFactory:SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(5000); // 连接超时 5 秒
requestFactory.setReadTimeout(5000);    // 读取超时 5 秒RestTemplate restTemplate = new RestTemplate(requestFactory);


3. 配置错误处理器

自定义 ResponseErrorHandler:restTemplate.setErrorHandler(new ResponseErrorHandler() {@Overridepublic boolean hasError(ClientHttpResponse response) throws IOException {return response.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR|| response.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR;}@Overridepublic void handleError(ClientHttpResponse response) throws IOException {// 自定义错误处理逻辑if (response.getStatusCode() == HttpStatus.NOT_FOUND) {throw new MyResourceNotFoundException("资源未找到");}}
});


八、使用示例


1. 完整的 GET 请求示例

RestTemplate restTemplate = new RestTemplate();
String url = "https://api.github.com/users/{username}";try {ResponseEntity<User> response = restTemplate.exchange(url,HttpMethod.GET,null,User.class,"octocat");if (response.getStatusCode() == HttpStatus.OK) {User user = response.getBody();System.out.println("用户名: " + user.getLogin());System.out.println("ID: " + user.getId());}
} catch (HttpClientErrorException e) {System.out.println("GitHub API 错误: " + e.getStatusCode());
} catch (Exception e) {System.out.println("发生异常: " + e.getMessage());
}

2. 完整的 POST 请求示例

// 创建请求对象
Map<String, String> requestBody = new HashMap<>();
requestBody.put("title", "foo");
requestBody.put("body", "bar");
requestBody.put("userId", "1");// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);// 创建 HttpEntity 对象
HttpEntity<Map<String, String>> request = new HttpEntity<>(requestBody, headers);// 发送 POST 请求
RestTemplate restTemplate = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts";ResponseEntity<Post> response = restTemplate.exchange(url,HttpMethod.POST,request,Post.class
);// 处理响应
if (response.getStatusCode() == HttpStatus.CREATED) {Post createdPost = response.getBody();System.out.println("创建的帖子 ID: " + createdPost.getId());
}

九、替代方案


从 Spring 5 开始,推荐使用 WebClient 替代 RestTemplate,因为它支持响应式编程和非阻塞 I/O:

WebClient webClient = WebClient.create();// 异步 GET 请求示例
Mono<User> userMono = webClient.get().uri("https://api.example.com/users/{id}", 123).retrieve().bodyToMono(User.class);

// 订阅并处理结果

userMono.subscribe(user -> System.out.println("用户: " + user.getName()));

十、总结


RestTemplate 是 Spring 框架中处理 REST API 的经典工具,适合同步、阻塞的 HTTP 通信场景。它提供了简洁的 API 和强大的消息转换机制,能大幅简化与外部服务的交互。不过,对于高并发场景,建议使用更现代的 WebClient。

http://www.dtcms.com/a/288506.html

相关文章:

  • Java多线程进阶
  • 【计算机网络架构】树型架构简介
  • openmv循迹
  • 基于Scrapy-Redis的分布式爬虫系统:工业级实现与深度优化
  • Linux系统日志管理入门:journalctl命令完全指南
  • Python关于numpy的基础知识
  • 物理AI是什么技术?
  • LVS实验步骤解析
  • yolo8实时识别目标(和平精英敌人+骨骼关键点)
  • 云计算与 DevOps(开发与运维)
  • 分立元件线性稳压器12V转5VMultisim仿真
  • [FFmpeg] 输入输出访问 | 管道系统 | AVIOContext 与 URLProtocol | 门面模式
  • LP wizard 软件安装教程
  • 嵌入式学习-PyTorch(8)-day24
  • Mybatis学习之简介(一)
  • 强化学习入门-免模型预测
  • 动态规划——数位DP经典题目
  • 关于饥饿加载(Eager Loading)
  • 智能体上下文压缩-裁剪和摘要
  • Compose笔记(三十六)--SearchBar
  • 人脸识别独立部署解决方案:一劳永逸的本地化对接方案
  • python的多线程无法并行只能并发,why?
  • 80、【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈空间对齐
  • kubeadm方式部署Kubernetes v1.22.2集群
  • 零基础学习性能测试第二章-linux服务器监控:磁盘监控
  • 如何设计一个高效的网页爬虫?
  • 7月19日 暴雨蓝色预警:全国多地迎强降雨,需防范次生灾害
  • Linux练习二
  • 信息系统风险的安全技术防范思路
  • 零基础学习性能测试第二章-linux服务器监控:CPU监控