package com.ruoyi.lsfx.util; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.lsfx.exception.LsfxApiException; import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.FileSystemResource; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.io.File; import java.util.Map; /** * HTTP请求工具类 */ @Component public class HttpUtil { private static final Logger log = LoggerFactory.getLogger(HttpUtil.class); @Resource private RestTemplate restTemplate; @Resource private ObjectMapper objectMapper; /** * 发送GET请求(带查询参数和请求头) * @param url 请求URL * @param params 查询参数 * @param headers 请求头 * @param responseType 响应类型 * @return 响应对象 */ public T get(String url, Map params, Map headers, Class responseType) { try { // 构建URL with查询参数 UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); if (params != null && !params.isEmpty()) { params.forEach((key, value) -> { if (value != null) { builder.queryParam(key, value); } }); } String fullUrl = builder.toUriString(); log.debug("【HTTP GET】请求URL: {}", fullUrl); // 创建请求头 HttpHeaders httpHeaders = new HttpHeaders(); if (headers != null) { headers.forEach(httpHeaders::add); } // 构建请求实体 HttpEntity entity = new HttpEntity<>(httpHeaders); // 执行GET请求 ResponseEntity response = restTemplate.exchange( fullUrl, HttpMethod.GET, entity, String.class ); log.debug("【HTTP GET】响应状态: {}", response.getStatusCode()); log.debug("【HTTP GET】响应内容: {}", response.getBody()); // 解析响应 if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { return objectMapper.readValue(response.getBody(), responseType); } else { throw new LsfxApiException("GET请求失败: " + response.getStatusCode()); } } catch (Exception e) { log.error("【HTTP GET】请求异常: url={}, error={}", url, e.getMessage(), e); throw new LsfxApiException("GET请求异常: " + e.getMessage(), e); } } /** * 发送GET请求(带请求头) * @param url 请求URL * @param headers 请求头 * @param responseType 响应类型 * @return 响应对象 */ public T get(String url, Map headers, Class responseType) { try { HttpHeaders httpHeaders = createHeaders(headers); HttpEntity requestEntity = new HttpEntity<>(httpHeaders); ResponseEntity response = restTemplate.exchange( url, HttpMethod.GET, requestEntity, responseType ); if (!response.getStatusCode().is2xxSuccessful()) { throw new LsfxApiException("API调用失败,HTTP状态码: " + response.getStatusCode()); } T body = response.getBody(); if (body == null) { throw new LsfxApiException("API返回数据为空"); } return body; } catch (RestClientException e) { throw new LsfxApiException("网络请求失败: " + e.getMessage(), e); } } /** * 发送POST请求(JSON格式,带请求头) * @param url 请求URL * @param request 请求对象 * @param headers 请求头 * @param responseType 响应类型 * @return 响应对象 */ public T postJson(String url, Object request, Map headers, Class responseType) { try { HttpHeaders httpHeaders = createHeaders(headers); httpHeaders.setContentType(MediaType.APPLICATION_JSON); HttpEntity requestEntity = new HttpEntity<>(request, httpHeaders); ResponseEntity response = restTemplate.postForEntity(url, requestEntity, responseType); if (!response.getStatusCode().is2xxSuccessful()) { throw new LsfxApiException("API调用失败,HTTP状态码: " + response.getStatusCode()); } T body = response.getBody(); if (body == null) { throw new LsfxApiException("API返回数据为空"); } return body; } catch (RestClientException e) { throw new LsfxApiException("网络请求失败: " + e.getMessage(), e); } } /** * 发送POST请求(multipart/form-data格式,带请求头) * 用于提交表单数据(非文件上传场景) * @param url 请求URL * @param params 表单参数 * @param headers 请求头 * @param responseType 响应类型 * @return 响应对象 */ public T postFormData(String url, Map params, Map headers, Class responseType) { try { HttpHeaders httpHeaders = createHeaders(headers); httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap body = new LinkedMultiValueMap<>(); if (params != null) { params.forEach(body::add); } HttpEntity> requestEntity = new HttpEntity<>(body, httpHeaders); ResponseEntity response = restTemplate.postForEntity(url, requestEntity, responseType); if (!response.getStatusCode().is2xxSuccessful()) { throw new LsfxApiException("API调用失败,HTTP状态码: " + response.getStatusCode()); } T responseBody = response.getBody(); if (responseBody == null) { throw new LsfxApiException("API返回数据为空"); } return responseBody; } catch (RestClientException e) { throw new LsfxApiException("网络请求失败: " + e.getMessage(), e); } } /** * 上传文件(Multipart格式) * @param url 请求URL * @param params 参数(包含文件) * @param headers 请求头 * @param responseType 响应类型 * @return 响应对象 */ public T uploadFile(String url, Map params, Map headers, Class responseType) { try { HttpHeaders httpHeaders = createHeaders(headers); httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap body = new LinkedMultiValueMap<>(); if (params != null) { params.forEach((key, value) -> { // 如果是File对象,包装为FileSystemResource if (value instanceof File) { File file = (File) value; body.add(key, new FileSystemResource(file)); } else { body.add(key, value); } }); } HttpEntity> requestEntity = new HttpEntity<>(body, httpHeaders); ResponseEntity response = restTemplate.postForEntity(url, requestEntity, responseType); if (!response.getStatusCode().is2xxSuccessful()) { throw new LsfxApiException("文件上传失败,HTTP状态码: " + response.getStatusCode()); } T responseBody = response.getBody(); if (responseBody == null) { throw new LsfxApiException("文件上传返回数据为空"); } return responseBody; } catch (RestClientException e) { throw new LsfxApiException("文件上传请求失败: " + e.getMessage(), e); } } /** * 创建请求头 * @param headers 请求头Map * @return HttpHeaders对象 */ private HttpHeaders createHeaders(Map headers) { HttpHeaders httpHeaders = new HttpHeaders(); if (headers != null && !headers.isEmpty()) { headers.forEach(httpHeaders::set); } return httpHeaders; } }