|
|
package com.example.demo.Util;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.FileSystemResource; import org.springframework.http.*; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate;
import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map;
/** * Excel文件上传工具类 */ public class ExcelUploadUtil { private static final Logger logger = LoggerFactory.getLogger(ExcelUploadUtil.class);
// 默认配置
private static final int DEFAULT_CONNECT_TIMEOUT = 30000; // 30秒
private static final int DEFAULT_READ_TIMEOUT = 60000; // 60秒
private final RestTemplate restTemplate; private final String uploadUrl; private final Map<String, String> defaultHeaders; private final Map<String, String> defaultParams;
/** * 构造方法 * * @param uploadUrl 上传接口URL */ public ExcelUploadUtil(String uploadUrl) { this(uploadUrl, new HashMap<>(), new HashMap<>()); }
/** * 构造方法 * * @param uploadUrl 上传接口URL * @param defaultHeaders 默认请求头 * @param defaultParams 默认请求参数 */ public ExcelUploadUtil(String uploadUrl, Map<String, String> defaultHeaders, Map<String, String> defaultParams) { this.uploadUrl = uploadUrl; this.defaultHeaders = new HashMap<>(defaultHeaders); this.defaultParams = new HashMap<>(defaultParams); this.restTemplate = createRestTemplate(DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT); }
/** * 创建RestTemplate (Spring Boot 1.x 兼容版本) */ private RestTemplate createRestTemplate(int connectTimeout, int readTimeout) { RestTemplate restTemplate = new RestTemplate();
// 添加字符串消息转换器 (Spring 1.x 使用Charset而不是StandardCharsets)
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
// 设置超时 (Spring 1.x 方式)
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(connectTimeout); factory.setReadTimeout(readTimeout); restTemplate.setRequestFactory(factory);
return restTemplate; }
/** * 上传Excel文件 * * @param excelFile Excel文件 * @param targetDir 目标目录 * @return 上传结果 * @throws IOException 文件操作异常 * @throws UploadException 上传异常 */ public String uploadExcel(File excelFile, String targetDir) throws IOException, UploadException { return uploadExcel(excelFile, targetDir, new HashMap<>(), new HashMap<>()); }
/** * 上传Excel文件(带自定义参数) * * @param excelFile Excel文件 * @param targetDir 目标目录 * @param customHeaders 自定义请求头 * @param customParams 自定义请求参数 * @return 上传结果 * @throws IOException 文件操作异常 * @throws UploadException 上传异常 */ public String uploadExcel(File excelFile, String targetDir, Map<String, String> customHeaders, Map<String, String> customParams) throws IOException, UploadException { // 验证文件
validateFile(excelFile);
try { // 准备请求
HttpEntity<MultiValueMap<String, Object>> requestEntity = prepareRequest(excelFile, targetDir, customHeaders, customParams);
// 执行上传
ResponseEntity<String> response = restTemplate.exchange( uploadUrl, HttpMethod.POST, requestEntity, String.class );
// 处理响应
return handleResponse(response, excelFile.getName()); } catch (Exception e) { logger.error("Excel文件上传失败: {}", excelFile.getAbsolutePath(), e); throw new UploadException("文件上传失败: " + e.getMessage(), e); } }
/** * 验证文件 */ private void validateFile(File file) throws IOException { if (file == null) { throw new IOException("文件不能为null"); } if (!file.exists()) { throw new IOException("文件不存在: " + file.getAbsolutePath()); } if (!file.isFile()) { throw new IOException("不是有效的文件: " + file.getAbsolutePath()); } if (file.length() == 0) { throw new IOException("文件内容为空: " + file.getAbsolutePath()); } if (!file.getName().toLowerCase().endsWith(".xlsx") && !file.getName().toLowerCase().endsWith(".xls")) { throw new IOException("仅支持Excel文件(.xlsx, .xls)"); } }
/** * 准备请求 */ private HttpEntity<MultiValueMap<String, Object>> prepareRequest(File file, String targetDir, Map<String, String> customHeaders, Map<String, String> customParams) { // 设置请求头
HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA);
// 添加默认和自定义请求头
defaultHeaders.forEach(headers::set); customHeaders.forEach(headers::set);
// 准备请求体
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>(); body.add("file", new FileSystemResource(file)); body.add("dir", targetDir);
// 添加默认和自定义参数
defaultParams.forEach(body::add); customParams.forEach(body::add);
return new HttpEntity<>(body, headers); }
/** * 处理响应 */ private String handleResponse(ResponseEntity<String> response, String filename) throws UploadException { if (response.getStatusCode() == HttpStatus.OK) { logger.info("文件上传成功: {}", filename); return response.getBody(); } else { String errorMsg = String.format("上传接口返回错误状态码: %d, 响应: %s", response.getStatusCodeValue(), response.getBody()); logger.error(errorMsg); throw new UploadException(errorMsg); } }
/** * 自定义上传异常 */ public static class UploadException extends Exception { public UploadException(String message) { super(message); }
public UploadException(String message, Throwable cause) { super(message, cause); } } }
|