obs文件存储服务

This commit is contained in:
jiang 2024-06-28 10:06:47 +08:00
parent 4881d1448e
commit 8d9fd8020f
5 changed files with 59 additions and 100 deletions

View File

@ -2,10 +2,10 @@ package com.bonus.obs.controller;
import com.bonus.common.core.domain.R; import com.bonus.common.core.domain.R;
import com.bonus.common.core.utils.file.FileUtils; import com.bonus.common.core.utils.file.FileUtils;
import com.bonus.obs.domain.ObsInfo;
import com.bonus.obs.service.ObsService; import com.bonus.obs.service.ObsService;
import com.obs.services.model.DeleteObjectResult; import com.obs.services.model.DeleteObjectResult;
import com.obs.services.model.ObsObject; import com.obs.services.model.ObsObject;
import com.obs.services.model.PutObjectResult;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -19,6 +19,7 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List;
@RestController @RestController
@RequestMapping("/obs") @RequestMapping("/obs")
@ -29,12 +30,12 @@ public class ObsController {
/** /**
* 文件上传 * 文件上传
* *
* @param param 文件流 * @param file 文件流
* @return 文件信息 * @return 文件信息
*/ */
@PostMapping("/upload") @PostMapping("/uploadFile")
public R<PutObjectResult> uploadFile(MultipartFile param) { public R<ObsInfo> uploadFile(MultipartFile file) {
return service.uploadFile(param); return service.uploadFile(file);
} }
/** /**
@ -42,7 +43,7 @@ public class ObsController {
* *
* @param objectKey 文件在OBS中的键 * @param objectKey 文件在OBS中的键
*/ */
@PostMapping("/delete") @PostMapping("/deleteFile")
public R<DeleteObjectResult> deleteFile(String objectKey) { public R<DeleteObjectResult> deleteFile(String objectKey) {
return service.deleteFile(objectKey); return service.deleteFile(objectKey);
} }
@ -87,4 +88,16 @@ public class ObsController {
} }
} }
/**
* 文件上传
*
* @param files 文件流
* @return 文件信息
*/
@PostMapping("/uploadFiles")
public R<List<ObsInfo>> uploadFiles(MultipartFile[] files) {
return service.uploadFiles(files);
}
} }

View File

@ -1,11 +1,14 @@
package com.bonus.obs.service; package com.bonus.obs.service;
import com.bonus.common.core.domain.R; import com.bonus.common.core.domain.R;
import com.bonus.obs.domain.ObsInfo;
import com.obs.services.model.DeleteObjectResult; import com.obs.services.model.DeleteObjectResult;
import com.obs.services.model.ObsObject; import com.obs.services.model.ObsObject;
import com.obs.services.model.PutObjectResult; import com.obs.services.model.PutObjectResult;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface ObsService { public interface ObsService {
/** /**
* 文件上传 * 文件上传
@ -13,7 +16,7 @@ public interface ObsService {
* @param file 文件流 * @param file 文件流
* @return 文件信息 * @return 文件信息
*/ */
R<PutObjectResult> uploadFile(MultipartFile file); R<ObsInfo> uploadFile(MultipartFile file);
/** /**
* 删除文件从OBS * 删除文件从OBS
@ -36,5 +39,5 @@ public interface ObsService {
* @param files 文件流 * @param files 文件流
* @return 文件信息 * @return 文件信息
*/ */
R<PutObjectResult> uploadFiles(MultipartFile[] files); R<List<ObsInfo>> uploadFiles(MultipartFile[] files);
} }

View File

@ -1,7 +1,9 @@
package com.bonus.obs.service.impl; package com.bonus.obs.service.impl;
import com.alibaba.nacos.common.utils.UuidUtils;
import com.bonus.common.core.domain.R; import com.bonus.common.core.domain.R;
import com.bonus.common.core.utils.file.FileUtils; import com.bonus.common.core.utils.file.FileUtils;
import com.bonus.obs.domain.ObsInfo;
import com.bonus.obs.service.ObsService; import com.bonus.obs.service.ObsService;
import com.bonus.obs.utils.ObsUtils; import com.bonus.obs.utils.ObsUtils;
import com.obs.services.model.DeleteObjectResult; import com.obs.services.model.DeleteObjectResult;
@ -12,6 +14,9 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Service @Service
public class ObsServiceImpl implements ObsService { public class ObsServiceImpl implements ObsService {
@ -25,11 +30,14 @@ public class ObsServiceImpl implements ObsService {
* @return 文件信息 * @return 文件信息
*/ */
@Override @Override
public R<PutObjectResult> uploadFile(MultipartFile file) { public R<ObsInfo> uploadFile(MultipartFile file) {
try { try {
String objectKey = file.getOriginalFilename(); String originalFilename = Objects.requireNonNull(file.getOriginalFilename(), "文件名不能为空");
String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
String objectKey = UuidUtils.generateUuid() + extension;
objectKey = FileUtils.generateObjectName(objectKey); objectKey = FileUtils.generateObjectName(objectKey);
return obsUtils.uploadFile(objectKey, FileUtils.multipartFileToFile(file)); ObsInfo obsInfo = obsUtils.uploadFile(objectKey, FileUtils.multipartFileToFile(file));
return R.ok(obsInfo);
} catch (Exception e) { } catch (Exception e) {
return R.fail(e.getMessage()); return R.fail(e.getMessage());
} }
@ -62,7 +70,19 @@ public class ObsServiceImpl implements ObsService {
* @return 文件信息 * @return 文件信息
*/ */
@Override @Override
public R<PutObjectResult> uploadFiles(MultipartFile[] files) { public R<List<ObsInfo>> uploadFiles(MultipartFile[] files) {
return null; try {
List<ObsInfo> obsInfos = new ArrayList<>();
for (MultipartFile multipartFile : files) {
String originalFilename = Objects.requireNonNull(multipartFile.getOriginalFilename(), "文件名不能为空");
String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
String objectKey = UuidUtils.generateUuid() + extension;
objectKey = FileUtils.generateObjectName(objectKey);
obsInfos.add(obsUtils.uploadFile(objectKey, FileUtils.multipartFileToFile(multipartFile)));
}
return R.ok(obsInfos, "文件上传成功");
} catch (Exception e) {
return R.fail("File upload failed.");
}
} }
} }

View File

@ -1,85 +0,0 @@
package com.bonus.obs.utils;
import com.bonus.common.core.utils.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileUtils {
/**
* 检查MultipartFile是否有效不为空且大小不超过5GB
*
* @param file MultipartFile对象
* @return 文件有效返回true否则返回false
*/
public static boolean isValidFile(MultipartFile file) {
if (file == null || file.isEmpty()) {
return false;
}
// 文件大小限制为5GB
long maxSizeInBytes = 5L * 1024 * 1024 * 1024;
return file.getSize() <= maxSizeInBytes;
}
/**
* 生成统一路径的objectName
*
* @param fileName 文件名
* @return 生成的objectName
*/
public static String generateObjectName(String fileName) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String datePath = sdf.format(new Date());
return "uploads/" + datePath + "/" + fileName;
}
public static boolean isValidOssFilePath(String ossFilePath) {
// 根据实际情况添加对ossFilePath的校验逻辑确保其只包含安全的字符
return StringUtils.hasText(ossFilePath) && ossFilePath.matches("^[\\w\\d\\-\\_\\.]+$");
}
public static String sanitizeFileName(String fileName) {
// 避免文件名注入移除或替换不安全的字符
return fileName.replaceAll("[^a-zA-Z0-9\\.\\-_]", "_");
}
/**
* 从文件路径中提取文件名
* @param ossFilePath 文件路径
* @return 文件名
*/
public static String getFileNameFromPath(String ossFilePath) {
Path path = Paths.get(ossFilePath);
return path.getFileName().toString();
}
/**
* MultipartFile File
*
* @param multiFile MultipartFile对象
* @return 转换后的File对象
*/
public static File multipartFileToFile(MultipartFile multiFile) {
try {
String fileName = multiFile.getOriginalFilename();
if (fileName == null) {
return null;
}
String prefix = fileName.substring(0, fileName.lastIndexOf("."));
String suffix = fileName.substring(fileName.lastIndexOf("."));
File file = File.createTempFile(prefix, suffix);
multiFile.transferTo(file);
return file;
} catch (Exception e) {
return null;
}
}
}

View File

@ -1,7 +1,9 @@
package com.bonus.obs.utils; package com.bonus.obs.utils;
import com.bonus.common.core.domain.R; import com.bonus.common.core.domain.R;
import com.bonus.common.core.utils.file.FileUtils;
import com.bonus.obs.config.ObsConfig; import com.bonus.obs.config.ObsConfig;
import com.bonus.obs.domain.ObsInfo;
import com.obs.services.ObsClient; import com.obs.services.ObsClient;
import com.obs.services.model.DeleteObjectResult; import com.obs.services.model.DeleteObjectResult;
import com.obs.services.model.GetObjectRequest; import com.obs.services.model.GetObjectRequest;
@ -42,8 +44,14 @@ public class ObsUtils {
* @param file 要上传的文件 * @param file 要上传的文件
* @return 上传结果 * @return 上传结果
*/ */
public R<PutObjectResult> uploadFile(String objectKey, File file) { public ObsInfo uploadFile(String objectKey, File file) {
return R.ok(obsClient.putObject(obsConfig.getBucket(), objectKey, file)); PutObjectResult putObjectResult = obsClient.putObject(obsConfig.getBucket(), objectKey, file);
return ObsInfo.builder()
.bucketName(obsConfig.getBucket())
.name(FileUtils.getName(objectKey))
.path(objectKey)
.build();
} }
/** /**