Commit 24877f7d by zhangxingmin

oss-v1版本

parent 59fe034f
...@@ -3,13 +3,14 @@ package com.yd.oss.api.controller; ...@@ -3,13 +3,14 @@ package com.yd.oss.api.controller;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.api.service.ApiMaterialService; import com.yd.oss.api.service.ApiMaterialService;
import com.yd.oss.feign.client.ApiMaterialFeignClient; import com.yd.oss.feign.client.ApiMaterialFeignClient;
import com.yd.oss.feign.request.ApiMaterialDownloadRequest;
import com.yd.oss.feign.request.ApiMaterialListRequest; import com.yd.oss.feign.request.ApiMaterialListRequest;
import com.yd.oss.feign.response.ApiMaterialDownloadResponse;
import com.yd.oss.feign.response.ApiMaterialListResponse; import com.yd.oss.feign.response.ApiMaterialListResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
/** /**
...@@ -35,4 +36,15 @@ public class ApiMaterialController implements ApiMaterialFeignClient { ...@@ -35,4 +36,15 @@ public class ApiMaterialController implements ApiMaterialFeignClient {
public Result<List<ApiMaterialListResponse>> list(ApiMaterialListRequest request) { public Result<List<ApiMaterialListResponse>> list(ApiMaterialListRequest request) {
return apiMaterialService.list(request); return apiMaterialService.list(request);
} }
/**
* 下载-材料列表压缩包
* @param request
* @return
*/
@Override
public Result<ApiMaterialDownloadResponse> downloadCompressedFile(ApiMaterialDownloadRequest request) {
return apiMaterialService.downloadCompressedFile(request);
}
} }
package com.yd.oss.api.service; package com.yd.oss.api.service;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.feign.request.ApiMaterialDownloadRequest;
import com.yd.oss.feign.request.ApiMaterialListRequest; import com.yd.oss.feign.request.ApiMaterialListRequest;
import com.yd.oss.feign.response.ApiMaterialDownloadResponse;
import com.yd.oss.feign.response.ApiMaterialListResponse; import com.yd.oss.feign.response.ApiMaterialListResponse;
import java.util.List; import java.util.List;
public interface ApiMaterialService { public interface ApiMaterialService {
Result<List<ApiMaterialListResponse>> list(ApiMaterialListRequest request); Result<List<ApiMaterialListResponse>> list(ApiMaterialListRequest request);
Result<ApiMaterialDownloadResponse> downloadCompressedFile(ApiMaterialDownloadRequest request);
} }
...@@ -2,18 +2,20 @@ package com.yd.oss.api.service.impl; ...@@ -2,18 +2,20 @@ package com.yd.oss.api.service.impl;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.api.service.ApiMaterialService; import com.yd.oss.api.service.ApiMaterialService;
import com.yd.oss.feign.request.ApiMaterialDownloadRequest;
import com.yd.oss.feign.request.ApiMaterialListRequest; import com.yd.oss.feign.request.ApiMaterialListRequest;
import com.yd.oss.feign.response.ApiMaterialDownloadResponse;
import com.yd.oss.feign.response.ApiMaterialListResponse; import com.yd.oss.feign.response.ApiMaterialListResponse;
import com.yd.oss.service.dto.MaterialDto; import com.yd.oss.service.dto.MaterialDto;
import com.yd.oss.service.model.Material; import com.yd.oss.service.model.Material;
import com.yd.oss.service.service.CompressedFileService;
import com.yd.oss.service.service.IMaterialService; import com.yd.oss.service.service.IMaterialService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
...@@ -23,6 +25,9 @@ public class ApiMaterialServiceImpl implements ApiMaterialService { ...@@ -23,6 +25,9 @@ public class ApiMaterialServiceImpl implements ApiMaterialService {
@Autowired @Autowired
private IMaterialService iMaterialService; private IMaterialService iMaterialService;
@Autowired
private CompressedFileService compressedFileService;
/** /**
* 列表查询-材料基础信息 * 列表查询-材料基础信息
* @param request * @param request
...@@ -42,5 +47,15 @@ public class ApiMaterialServiceImpl implements ApiMaterialService { ...@@ -42,5 +47,15 @@ public class ApiMaterialServiceImpl implements ApiMaterialService {
return Result.success(); return Result.success();
} }
/**
* 下载-材料列表压缩包
* @param request
* @return
*/
@Override
public Result<ApiMaterialDownloadResponse> downloadCompressedFile(ApiMaterialDownloadRequest request) {
return compressedFileService.downloadCompressedFile(request);
}
} }
\ No newline at end of file
...@@ -2,12 +2,14 @@ package com.yd.oss.feign.client; ...@@ -2,12 +2,14 @@ package com.yd.oss.feign.client;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.feign.fallback.ApiMaterialFeignFallbackFactory; import com.yd.oss.feign.fallback.ApiMaterialFeignFallbackFactory;
import com.yd.oss.feign.request.ApiMaterialDownloadRequest;
import com.yd.oss.feign.request.ApiMaterialListRequest; import com.yd.oss.feign.request.ApiMaterialListRequest;
import com.yd.oss.feign.response.ApiMaterialDownloadResponse;
import com.yd.oss.feign.response.ApiMaterialListResponse; import com.yd.oss.feign.response.ApiMaterialListResponse;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import java.util.List; import java.util.List;
/** /**
...@@ -23,4 +25,12 @@ public interface ApiMaterialFeignClient { ...@@ -23,4 +25,12 @@ public interface ApiMaterialFeignClient {
*/ */
@PostMapping("/list") @PostMapping("/list")
Result<List<ApiMaterialListResponse>> list(@RequestBody ApiMaterialListRequest request); Result<List<ApiMaterialListResponse>> list(@RequestBody ApiMaterialListRequest request);
/**
* 下载-材料列表压缩包
* @param request
* @return
*/
@PostMapping("/download/compressed/file")
Result<ApiMaterialDownloadResponse> downloadCompressedFile(@Validated @RequestBody ApiMaterialDownloadRequest request);
} }
...@@ -41,4 +41,6 @@ public interface ApiRelObjectMaterialFeignClient { ...@@ -41,4 +41,6 @@ public interface ApiRelObjectMaterialFeignClient {
*/ */
@PostMapping("/add/relObjectMaterialList") @PostMapping("/add/relObjectMaterialList")
Result addRelObjectMaterialList(@Validated @RequestBody ApiRelObjectMaterialListAddRequest request); Result addRelObjectMaterialList(@Validated @RequestBody ApiRelObjectMaterialListAddRequest request);
} }
package com.yd.oss.feign.dto;
import lombok.Data;
import java.util.List;
@Data
public class ApiMaterialDto {
/**
* 资料人(字典)
*/
private String dataPerson;
/**
* 资料类型(字典)
*/
private String dataType;
/**
* 文件URL列表
*/
private List<String> fileUrlList;
}
...@@ -2,6 +2,7 @@ package com.yd.oss.feign.fallback; ...@@ -2,6 +2,7 @@ package com.yd.oss.feign.fallback;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.feign.client.ApiMaterialFeignClient; import com.yd.oss.feign.client.ApiMaterialFeignClient;
import com.yd.oss.feign.request.ApiMaterialDownloadRequest;
import com.yd.oss.feign.request.ApiMaterialListRequest; import com.yd.oss.feign.request.ApiMaterialListRequest;
import com.yd.oss.feign.response.ApiMaterialListResponse; import com.yd.oss.feign.response.ApiMaterialListResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -23,6 +24,11 @@ public class ApiMaterialFeignFallbackFactory implements FallbackFactory<ApiMater ...@@ -23,6 +24,11 @@ public class ApiMaterialFeignFallbackFactory implements FallbackFactory<ApiMater
public Result<List<ApiMaterialListResponse>> list(ApiMaterialListRequest request) { public Result<List<ApiMaterialListResponse>> list(ApiMaterialListRequest request) {
return null; return null;
} }
@Override
public Result downloadCompressedFile(ApiMaterialDownloadRequest request) {
return null;
}
}; };
} }
} }
package com.yd.oss.feign.request;
import com.yd.oss.feign.dto.ApiMaterialDto;
import lombok.Data;
import java.util.List;
@Data
public class ApiMaterialDownloadRequest {
/**
* 对象名(包名)
*/
private String objectName;
/**
* 对象业务ID
*/
private String objectBizId;
/**
* 材料列表
*/
private List<ApiMaterialDto> apiMaterialDtoList;
}
package com.yd.oss.feign.response;
import lombok.Data;
@Data
public class ApiMaterialDownloadResponse {
/**
* OSS文件URL
*/
private String url;
}
package com.yd.oss.service.service;
import com.yd.common.result.Result;
import com.yd.oss.feign.request.ApiMaterialDownloadRequest;
import com.yd.oss.feign.response.ApiMaterialDownloadResponse;
public interface CompressedFileService {
Result<ApiMaterialDownloadResponse> downloadCompressedFile(ApiMaterialDownloadRequest request);
}
package com.yd.oss.service.service.impl;
import com.yd.common.result.Result;
import com.yd.oss.feign.dto.ApiMaterialDto;
import com.yd.oss.feign.request.ApiMaterialDownloadRequest;
import com.yd.oss.feign.response.ApiMaterialDownloadResponse;
import com.yd.oss.service.service.CompressedFileService;
import com.yd.oss.service.service.OssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 压缩包服务
*/
@Slf4j
@Service
public class CompressedFileServiceImpl implements CompressedFileService {
@Autowired
private OssService ossService;
@Autowired
private String defaultBucket; // 注入默认存储桶
@Autowired
private String defaultEndpoint; // 注入默认服务端点
/**
* 下载-材料列表压缩包
* @param request
* @return
*/
@Override
public Result<ApiMaterialDownloadResponse> downloadCompressedFile(ApiMaterialDownloadRequest request) {
try {
// 验证请求参数
if (request == null || CollectionUtils.isEmpty(request.getApiMaterialDtoList())) {
return Result.fail("材料列表不能为空");
}
if (!StringUtils.hasText(request.getObjectName())) {
return Result.fail("对象名(包名)不能为空");
}
// 创建临时压缩文件
File tempZipFile = createTempZipFile();
int successFileCount = 0; // 成功添加的文件计数
try (FileOutputStream fos = new FileOutputStream(tempZipFile);
ZipOutputStream zos = new ZipOutputStream(fos, StandardCharsets.UTF_8)) {
// 处理每个材料
for (ApiMaterialDto materialDto : request.getApiMaterialDtoList()) {
String folderName = buildFolderName(materialDto);
// 处理每个文件的URL
if (!CollectionUtils.isEmpty(materialDto.getFileUrlList())) {
for (int i = 0; i < materialDto.getFileUrlList().size(); i++) {
String fileUrl = materialDto.getFileUrlList().get(i);
try {
// 下载文件并添加到压缩包
boolean success = addFileToZip(zos, fileUrl, folderName, i + 1);
if (success) {
successFileCount++;
}
} catch (Exception e) {
log.warn("文件下载失败,URL: {}", fileUrl, e);
// 继续处理其他文件
}
}
}
}
// 刷新并关闭流
zos.flush();
zos.finish();
// 如果没有成功添加任何文件,返回错误
if (successFileCount == 0) {
return Result.fail("没有有效的文件可下载");
}
log.info("成功添加 {} 个文件到压缩包,压缩包大小: {} 字节",
successFileCount, tempZipFile.length());
// 上传压缩包到OSS
String ossUrl = uploadZipToOss(tempZipFile, request.getObjectName());
// 构建响应
ApiMaterialDownloadResponse response = new ApiMaterialDownloadResponse();
response.setUrl(ossUrl);
return Result.success(response);
} catch (Exception e) {
log.error("创建压缩包失败", e);
return Result.fail("创建压缩包失败: " + e.getMessage());
} finally {
// 清理临时文件
if (tempZipFile.exists()) {
try {
tempZipFile.delete();
} catch (Exception e) {
log.warn("清理临时文件失败", e);
}
}
}
} catch (Exception e) {
log.error("下载材料压缩包失败", e);
return Result.fail("下载材料压缩包失败: " + e.getMessage());
}
}
/**
* 创建临时压缩文件
*/
private File createTempZipFile() throws IOException {
String tempDir = System.getProperty("java.io.tmpdir");
String fileName = "material_zip_" + System.currentTimeMillis() + "_" + UUID.randomUUID() + ".zip";
File tempFile = new File(tempDir, fileName);
log.debug("创建临时压缩文件: {}", tempFile.getAbsolutePath());
return tempFile;
}
/**
* 构建文件夹名称:资料人-资料类型
*/
private String buildFolderName(ApiMaterialDto materialDto) {
String dataPerson = StringUtils.hasText(materialDto.getDataPerson()) ?
materialDto.getDataPerson() : "未知资料人";
String dataType = StringUtils.hasText(materialDto.getDataType()) ?
materialDto.getDataType() : "未知类型";
// 清理非法文件名字符
String folderName = dataPerson + "-" + dataType;
folderName = folderName.replaceAll("[\\\\/:*?\"<>|]", "_");
return folderName;
}
/**
* 下载文件并添加到压缩包
*/
private boolean addFileToZip(ZipOutputStream zos, String fileUrl, String folderName, int fileIndex) throws Exception {
// 从URL中提取文件名
String fileName = extractFileNameFromUrl(fileUrl, fileIndex);
// 构建zip中的完整路径
String zipEntryName = folderName + "/" + fileName;
// 从OSS下载文件
InputStream fileInputStream = downloadFileFromUrl(fileUrl);
if (fileInputStream == null) {
throw new IOException("无法下载文件: " + fileUrl);
}
try {
// 创建zip entry
ZipEntry zipEntry = new ZipEntry(zipEntryName);
zos.putNextEntry(zipEntry);
// 将文件内容写入zip
byte[] buffer = new byte[8192];
int length;
int totalBytes = 0;
while ((length = fileInputStream.read(buffer)) > 0) {
zos.write(buffer, 0, length);
totalBytes += length;
}
zos.closeEntry();
log.debug("成功添加文件到压缩包: {} ({} 字节)", zipEntryName, totalBytes);
return true;
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
log.warn("关闭文件流失败", e);
}
}
}
/**
* 从URL中提取文件名
*/
private String extractFileNameFromUrl(String fileUrl, int fileIndex) {
if (!StringUtils.hasText(fileUrl)) {
return "file_" + fileIndex;
}
try {
// 尝试从URL中提取文件名
int lastSlashIndex = fileUrl.lastIndexOf('/');
if (lastSlashIndex >= 0 && lastSlashIndex < fileUrl.length() - 1) {
String fileName = fileUrl.substring(lastSlashIndex + 1);
// 清理文件名
int queryIndex = fileName.indexOf('?');
if (queryIndex > 0) {
fileName = fileName.substring(0, queryIndex);
}
if (StringUtils.hasText(fileName) && fileName.length() < 255) {
return fileName;
}
}
} catch (Exception e) {
log.warn("从URL提取文件名失败: {}", fileUrl, e);
}
// 默认文件名
return "file_" + fileIndex + getFileExtensionFromUrl(fileUrl);
}
/**
* 从URL获取文件扩展名
*/
private String getFileExtensionFromUrl(String fileUrl) {
if (!StringUtils.hasText(fileUrl)) {
return "";
}
try {
// 获取扩展名
int dotIndex = fileUrl.lastIndexOf('.');
if (dotIndex > 0 && dotIndex < fileUrl.length() - 1) {
String ext = fileUrl.substring(dotIndex);
int queryIndex = ext.indexOf('?');
if (queryIndex > 0) {
ext = ext.substring(0, queryIndex);
}
// 只保留常见的文件扩展名
if (ext.length() <= 5 && ext.matches("\\.[a-zA-Z0-9]{1,4}")) {
return ext;
}
}
} catch (Exception e) {
log.warn("获取文件扩展名失败", e);
}
return "";
}
/**
* 从URL下载文件
*/
private InputStream downloadFileFromUrl(String fileUrl) {
try {
// 方法1: 尝试从OSS下载(如果URL是我们OSS的)
String fileKey = extractFileKeyFromUrl(fileUrl);
if (StringUtils.hasText(fileKey)) {
log.debug("从OSS下载文件,fileKey: {}", fileKey);
return ossService.downloadFile(fileKey);
}
// 方法2: 尝试HTTP下载
log.debug("尝试HTTP下载文件: {}", fileUrl);
return downloadFileByHttp(fileUrl);
} catch (Exception e) {
log.error("下载文件失败: {}", fileUrl, e);
return null;
}
}
/**
* 从完整URL中提取OSS文件key
*/
private String extractFileKeyFromUrl(String fileUrl) {
if (!StringUtils.hasText(fileUrl)) {
return null;
}
try {
// 你提供的URL格式: https://yd-ali-oss.oss-cn-shanghai-finance-1-pub.aliyuncs.com/docx/2026/01/06/166b192397f84055aaec968d20e57977.docx
// 移除协议前缀
String url = fileUrl;
if (url.startsWith("https://")) {
url = url.substring(8);
} else if (url.startsWith("http://")) {
url = url.substring(7);
}
// 从配置获取endpoint
String endpoint = defaultEndpoint;
// 查找bucket.endpoint组合
String bucketEndpoint = defaultBucket + "." + endpoint;
int bucketEndpointIndex = url.indexOf(bucketEndpoint);
if (bucketEndpointIndex >= 0) {
// 提取bucket.endpoint之后的部分
int startIndex = bucketEndpointIndex + bucketEndpoint.length();
if (url.charAt(startIndex) == '/') {
startIndex++;
}
String fileKey = url.substring(startIndex);
// 移除查询参数
int queryIndex = fileKey.indexOf('?');
if (queryIndex > 0) {
fileKey = fileKey.substring(0, queryIndex);
}
log.debug("从URL提取fileKey: {} -> {}", fileUrl, fileKey);
return fileKey;
}
// 尝试其他可能的格式
int firstSlashIndex = url.indexOf('/');
if (firstSlashIndex > 0) {
String fileKey = url.substring(firstSlashIndex + 1);
// 移除查询参数
int queryIndex = fileKey.indexOf('?');
if (queryIndex > 0) {
fileKey = fileKey.substring(0, queryIndex);
}
log.debug("从URL提取fileKey(备选): {} -> {}", fileUrl, fileKey);
return fileKey;
}
} catch (Exception e) {
log.warn("从URL提取文件key失败: {}", fileUrl, e);
}
return null;
}
/**
* HTTP下载文件
*/
private InputStream downloadFileByHttp(String fileUrl) {
try {
URL url = new URL(fileUrl);
URLConnection connection = url.openConnection();
connection.setConnectTimeout(10000); // 10秒连接超时
connection.setReadTimeout(30000); // 30秒读取超时
// 设置User-Agent,避免被某些服务器拒绝
connection.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
return connection.getInputStream();
} catch (Exception e) {
log.error("HTTP下载文件失败: {}", fileUrl, e);
return null;
}
}
/**
* 上传压缩包到OSS
*/
private String uploadZipToOss(File zipFile, String objectName) throws Exception {
if (!zipFile.exists() || zipFile.length() == 0) {
throw new IOException("压缩文件不存在或为空");
}
try (FileInputStream fis = new FileInputStream(zipFile)) {
// 生成压缩包文件名
String zipFileName = generateZipFileName(objectName);
log.info("上传压缩包到OSS,文件大小: {} 字节,文件名: {}",
zipFile.length(), zipFileName);
// 检查是否使用阿里云OSS实现
if (ossService instanceof AliYunOssServiceImpl) {
AliYunOssServiceImpl aliYunOssService = (AliYunOssServiceImpl) ossService;
// 使用反射调用upload方法(兼容性更好)
try {
// 方法1: 直接调用public方法
java.lang.reflect.Method uploadMethod = AliYunOssServiceImpl.class
.getMethod("upload", InputStream.class, String.class);
String ossUrl = (String) uploadMethod.invoke(aliYunOssService, fis, zipFileName);
log.info("压缩包上传成功,URL: {}", ossUrl);
return ossUrl;
} catch (NoSuchMethodException e) {
// 方法2: 尝试其他可能的upload方法
log.warn("未找到upload(InputStream, String)方法,尝试其他方法");
// 转换为字节数组上传
byte[] zipBytes = readFileToBytes(zipFile);
try {
java.lang.reflect.Method uploadMethod2 = AliYunOssServiceImpl.class
.getMethod("upload", byte[].class, String.class);
String ossUrl = (String) uploadMethod2.invoke(aliYunOssService, zipBytes, zipFileName);
log.info("压缩包上传成功,URL: {}", ossUrl);
return ossUrl;
} catch (NoSuchMethodException e2) {
// 最后尝试:使用现有的uploadFile方法
log.info("尝试使用现有的uploadFile方法");
return uploadUsingExistingMethod(fis, zipFileName, "system");
}
}
} else {
throw new UnsupportedOperationException("不支持的OSS服务类型");
}
}
}
/**
* 使用现有的uploadFile方法上传
*/
private String uploadUsingExistingMethod(InputStream inputStream, String fileName, String uploadUser) throws Exception {
// 这里需要根据你的OssService接口的具体方法进行调整
// 假设有uploadFile(InputStream, String, String)方法
try {
// 读取整个文件到字节数组
byte[] fileData = readInputStreamToBytes(inputStream);
// 使用反射调用upload(byte[], String)方法
java.lang.reflect.Method uploadMethod = AliYunOssServiceImpl.class
.getMethod("upload", byte[].class, String.class);
AliYunOssServiceImpl aliYunOssService = (AliYunOssServiceImpl) ossService;
return (String) uploadMethod.invoke(aliYunOssService, fileData, fileName);
} catch (Exception e) {
log.error("使用现有方法上传失败", e);
throw e;
}
}
/**
* 读取文件到字节数组
*/
private byte[] readFileToBytes(File file) throws IOException {
try (FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[8192];
int length;
while ((length = fis.read(buffer)) > 0) {
bos.write(buffer, 0, length);
}
return bos.toByteArray();
}
}
/**
* 读取输入流到字节数组
*/
private byte[] readInputStreamToBytes(InputStream inputStream) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[8192];
int length;
while ((length = inputStream.read(buffer)) > 0) {
bos.write(buffer, 0, length);
}
return bos.toByteArray();
}
}
/**
* 生成压缩包文件名
*/
private String generateZipFileName(String objectName) {
// 清理非法字符
String safeObjectName = objectName.replaceAll("[\\\\/:*?\"<>|]", "_");
// 添加时间戳和扩展名
String fileName = safeObjectName + "_" +
new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) +
".zip";
log.debug("生成的压缩包文件名: {}", fileName);
return fileName;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment