Java RestTemplate 通用请求工具类
在现代Java应用中,与外部服务进行HTTP通信是非常常见的需求。本文将介绍一个实用的工具类RestTemplateUtils
,它基于Spring框架的RestTemplate
,简化了各种HTTP请求的处理。
工具类概述
RestTemplateUtils
提供了三种主要的HTTP请求处理方法:
-
通用JSON请求方法:处理常规的JSON格式请求
-
扩展的通用JSON请求方法:支持任意对象作为请求体
-
文件上传方法:专门处理multipart/form-data格式的文件上传
1. 通用工具类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;import java.util.Map;@Slf4j
public class RestTemplateUtils {/*** 通用HTTP请求方法** @param requestBody 请求体内容* @param url 完整请求url* @param httpMethod 请求方法类型 (GET, POST, PUT, DELETE等)* @return 响应内容字符串,失败时返回null*/public static String executeRequest(Map<String, String> requestBody, String url, HttpMethod httpMethod) {RestTemplate restTemplate = new RestTemplate();try {// 请求头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);// 请求体HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);// 服务端地址、请求方法、请求实体(包含头和体、响应类型ResponseEntity<String> response = restTemplate.exchange(url, httpMethod, requestEntity, String.class);if (!response.getStatusCode().is2xxSuccessful()) {throw new RuntimeException("HTTP请求失败,状态码: " + response.getStatusCode());}return response.getBody();} catch (Exception e) {log.error("HTTP请求失败: {} {}, 错误: {}", httpMethod, url, e.getMessage());return null;}}/*** 通用HTTP请求方法(支持任意请求体类型)** @param requestBody 请求体内容,可以是Map、POJO或任何可序列化为JSON的对象* @param url 完整的请求URL(包含协议、主机、路径和参数)* @param httpMethod 请求方法类型(GET/POST/PUT/DELETE等)* @return 响应内容的字符串形式* @throws RuntimeException 当HTTP请求失败或返回非2xx状态码时抛出*/public static String executeRequest(Object requestBody, String url, HttpMethod httpMethod) {RestTemplate restTemplate = new RestTemplate();try {// 请求头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);// 请求体HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, headers);// 服务端地址、请求方法、请求实体(包含头和体、响应类型ResponseEntity<String> response = restTemplate.exchange(url, httpMethod, requestEntity, String.class);if (!response.getStatusCode().is2xxSuccessful()) {throw new RuntimeException("HTTP请求失败,状态码: " + response.getStatusCode());}return response.getBody();} catch (Exception e) {log.error("HTTP请求失败: {} {}, 错误: {}", httpMethod, url, e.getMessage());return null;}}/*** 文件上传专用方法 (multipart/form-data)** @param file 上传的文件* @param formData 其他表单字段* @param url 目标URL* @return 响应内容*/public static String uploadFile(MultipartFile file, Map<String, String> formData, String url, String fileName) {RestTemplate restTemplate = new RestTemplate();try {// 1. 构建 MultipartBodyHttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 关键!if (StringUtils.isNotEmpty(fileName)) {headers.set("accept", "application/json"); // 添加 accept 头}MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();// 设置文件名fileName = StringUtils.isEmpty(fileName)? "file": fileName;// 添加文件body.add(fileName, new ByteArrayResource(file.getBytes()) {@Overridepublic String getFilename() {return file.getOriginalFilename(); // 保留原始文件名}});// 添加其他表单字段(如果有)if (formData != null) {formData.forEach(body::add);}// 2. 发送请求HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);if (!response.getStatusCode().is2xxSuccessful()) {throw new RuntimeException("上传失败,状态码: " + response.getStatusCode());}return response.getBody();} catch (Exception e) {log.error("文件上传失败: {}, 错误: {}", url, e.getMessage());return null;}}
}
2. 使用示例
public AjaxResult retrieve() {try {// 使用Map构建请求体Map<String, String> requestBody = new HashMap<>();requestBody.put("user_id", "1");// 发送POST请求String bodyStr = RestTemplateUtils.executeRequest(requestBody, "url", HttpMethod.POST);// 解析JSON响应ObjectMapper objectMapper = new ObjectMapper();Map<String, Object> responseMap = objectMapper.readValue(bodyStr, new TypeReference<Map<String, Object>>() {});// 检查状态码Integer status = (Integer) responseMap.get("status");Object data = responseMap.get("data");if (status != null && status == 200) {return AjaxResult.success(data);}} catch (Exception e) {e.printStackTrace();}return AjaxResult.success(null);}
优点总结
-
简化代码:封装了重复的HTTP请求处理逻辑
-
统一错误处理:集中处理异常和错误状态码
-
类型安全:明确区分JSON请求和文件上传
-
灵活性:支持各种HTTP方法和请求体类型
-
易于维护:所有HTTP请求相关代码集中在一处
使用建议
-
对于简单的键值对请求,使用第一个方法
-
对于复杂对象请求,使用第二个方法
-
文件上传必须使用第三个专用方法
-
在生产环境中,可以考虑添加重试机制和更详细的日志记录
这个工具类非常适合中小型项目,可以显著减少HTTP请求相关的样板代码,让开发者更专注于业务逻辑的实现。
一线网资源-全网一站式平台