77import com .qcloud .cos .model .ObjectMetadata ;
88import com .qcloud .cos .model .PutObjectRequest ;
99import com .qcloud .cos .region .Region ;
10- import org .springframework .http .codec .multipart .FilePart ;
1110import org .springframework .web .multipart .MultipartFile ;
12- import reactor .core .publisher .Mono ;
1311
1412import java .io .File ;
15- import java .io .FileInputStream ;
1613import java .io .IOException ;
1714import java .io .InputStream ;
1815import java .nio .file .Files ;
@@ -67,36 +64,6 @@ public static String uploadFile(String baseDir, String relativePath, String file
6764 return filePath .toString ();
6865 }
6966
70- /**
71- * 上传FilePart文件
72- *
73- * @param baseDir 基础目录
74- * @param relativePath 相对路径
75- * @param fileName 文件名
76- * @param filePart 文件部分
77- * @return 包含文件完整路径的Mono
78- */
79- public static Mono <String > uploadFilePart (String baseDir , String relativePath , String fileName , FilePart filePart ) {
80- // 创建目录
81- String fullPath = baseDir + File .separator + relativePath ;
82- Path uploadPath = Paths .get (fullPath );
83-
84- try {
85- if (!Files .exists (uploadPath )) {
86- Files .createDirectories (uploadPath );
87- }
88-
89- // 保存文件
90- Path filePath = uploadPath .resolve (fileName );
91-
92- // 使用FilePart的transferTo方法将内容写入目标文件
93- return filePart .transferTo (filePath )
94- .then (Mono .just (filePath .toString ()));
95- } catch (IOException e ) {
96- return Mono .error (e );
97- }
98- }
99-
10067 /**
10168 * 检查文件大小和类型
10269 *
@@ -109,16 +76,17 @@ public static void assertAllowed(MultipartFile file) {
10976 }
11077
11178 /**
112- * 智能上传FilePart文件 (根据配置决定上传到本地还是腾讯云COS)
79+ * 智能上传文件 (根据配置决定上传到本地还是腾讯云COS)
11380 *
11481 * @param baseDir 本地基础目录
11582 * @param relativePath 相对路径
11683 * @param fileName 文件名
117- * @param filePart 文件部分
118- * @return 包含文件访问路径的Mono
84+ * @param file 文件
85+ * @return 文件访问路径
86+ * @throws IOException 如果上传过程中发生IO错误
11987 */
120- public static Mono < String > smartUploadFilePart (String baseDir , String relativePath , String fileName ,
121- FilePart filePart ) {
88+ public static String smartUpload (String baseDir , String relativePath , String fileName ,
89+ MultipartFile file ) throws IOException {
12290 // 检查配置文件中是否有腾讯云COS的配置
12391 Properties properties = new Properties ();
12492 try (InputStream inputStream = FileUploadUtils .class .getClassLoader ()
@@ -144,90 +112,18 @@ public static Mono<String> smartUploadFilePart(String baseDir, String relativePa
144112 cosPath = cosPath + "/" ;
145113 }
146114
147- // 先将FilePart保存到临时文件,然后上传到COS
148- return uploadFilePartToTempAndThenToCos ( filePart , bucketName , secretId , secretKey , region ,
115+ // 上传到COS
116+ return uploadToCos ( file , bucketName , secretId , secretKey , region ,
149117 cosPath + relativePath + "/" );
150118 }
151119 }
152120 } catch (Exception e ) {
153121 // 如果读取配置或上传到COS出错,则回退到本地上传
154- return uploadFilePart (baseDir , relativePath , fileName , filePart );
122+ return uploadFile (baseDir , relativePath , fileName , file );
155123 }
156124
157125 // 如果没有COS配置或配置不完整,则上传到本地
158- return uploadFilePart (baseDir , relativePath , fileName , filePart );
159- }
160-
161- /**
162- * 将FilePart先保存到临时文件,然后上传到腾讯云COS
163- *
164- * @param filePart 文件部分
165- * @param bucketName 存储桶名称
166- * @param secretId 腾讯云SecretId
167- * @param secretKey 腾讯云SecretKey
168- * @param region 地域信息
169- * @param cosPath COS路径
170- * @return 包含文件访问URL的Mono
171- */
172- private static Mono <String > uploadFilePartToTempAndThenToCos (FilePart filePart , String bucketName , String secretId ,
173- String secretKey , String region , String cosPath ) {
174- try {
175- // 创建临时文件
176- Path tempFile = Files .createTempFile ("cos_upload_" , ".tmp" );
177-
178- // 将FilePart内容写入临时文件
179- return filePart .transferTo (tempFile )
180- .then (Mono .fromCallable (() -> {
181- try {
182- // 生成唯一文件名
183- String originalFilename = filePart .filename ();
184- String suffix = originalFilename .substring (originalFilename .lastIndexOf ("." ));
185- String fileName = UUID .randomUUID ().toString ().replaceAll ("-" , "" ) + suffix ;
186-
187- // 构建完整的对象键(Key)
188- String key = cosPath + fileName ;
189-
190- // 创建 COSClient 实例
191- COSCredentials cred = new BasicCOSCredentials (secretId , secretKey );
192- ClientConfig clientConfig = new ClientConfig (new Region (region ));
193- COSClient cosClient = new COSClient (cred , clientConfig );
194-
195- try {
196- // 获取临时文件大小
197- long fileSize = Files .size (tempFile );
198-
199- // 上传文件
200- ObjectMetadata metadata = new ObjectMetadata ();
201- metadata .setContentLength (fileSize );
202-
203- // 尝试设置内容类型
204- String contentType = determineContentType (originalFilename );
205- if (contentType != null ) {
206- metadata .setContentType (contentType );
207- }
208-
209- try (InputStream fileInputStream = new FileInputStream (tempFile .toFile ())) {
210- PutObjectRequest putObjectRequest = new PutObjectRequest (bucketName , key ,
211- fileInputStream , metadata );
212- cosClient .putObject (putObjectRequest );
213- }
214-
215- // 生成文件访问URL
216- return "https://" + bucketName + ".cos." + region + ".myqcloud.com/" + key ;
217- } finally {
218- cosClient .shutdown ();
219- // 删除临时文件
220- Files .deleteIfExists (tempFile );
221- }
222- } catch (Exception e ) {
223- // 确保临时文件被删除
224- Files .deleteIfExists (tempFile );
225- throw e ;
226- }
227- }));
228- } catch (IOException e ) {
229- return Mono .error (e );
230- }
126+ return uploadFile (baseDir , relativePath , fileName , file );
231127 }
232128
233129 /**
@@ -303,7 +199,13 @@ public static String uploadToCos(MultipartFile file, String bucketName, String s
303199 // 上传文件
304200 ObjectMetadata metadata = new ObjectMetadata ();
305201 metadata .setContentLength (file .getSize ());
306- metadata .setContentType (file .getContentType ());
202+
203+ // 设置内容类型
204+ String contentType = file .getContentType ();
205+ if (contentType == null || contentType .isEmpty ()) {
206+ contentType = determineContentType (originalFilename );
207+ }
208+ metadata .setContentType (contentType );
307209
308210 PutObjectRequest putObjectRequest = new PutObjectRequest (bucketName , key , file .getInputStream (), metadata );
309211 cosClient .putObject (putObjectRequest );
0 commit comments