Springboot集成阿里云OSS上传
API 接口描述
DEMO提供的四个API接口,支持不同方式的文件和 JSON 数据上传:
1. 普通文件上传接口
上传任意类型的文件
2. JSON 字符串上传接口
上传 JSON 字符串
3. 单个 JSON 压缩上传接口
上传并压缩 JSON 字符串
4. 批量 JSON 压缩上传接口
批量上传并压缩多个 JSON 字符串
AliOssConfig
/**
* @author Melody
* @description:
* @date 2025-05-06
*/
@Data
@Configuration
public class AliOssConfig {
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.access-key-id}")
private String accessKeyId;
@Value("${aliyun.oss.access-key-secret}")
private String accessKeySecret;
@Value("${aliyun.oss.bucket-name}")
private String bucketName;
}
AliOssUtil
/**
* @author Melody
* @description:
* @date 2025-05-06
*/
@Component
@Slf4j
public class AliOssUtil {
private final AliOssConfig aliOssConfig;
private OSS ossClient;
@Autowired
public AliOssUtil(AliOssConfig aliOssConfig) {
this.aliOssConfig = aliOssConfig;
ossClient = new OSSClientBuilder().build(aliOssConfig.getEndpoint(), aliOssConfig.getAccessKeyId(), aliOssConfig.getAccessKeySecret());
}
public String uploadFile(MultipartFile file, String fileType) {
if (file.isEmpty()) {
throw new IllegalArgumentException("文件不能为空");
}
try {
// 生成文件名和路径
String fileName = generateUniqueFileName(file.getOriginalFilename());
String filePath = generateDateBasedFilePath(fileType, fileName);
// 上传文件
try (InputStream inputStream = file.getInputStream()) {
ossClient.putObject(aliOssConfig.getBucketName(), filePath, inputStream);
}
// 返回 URL
return buildOssUrl(filePath);
} catch (IOException e) {
throw new RuntimeException("文件读取失败: " + e.getMessage());
} catch (OSSException | ClientException e) {
throw new RuntimeException("OSS服务异常: " + e.getMessage());
}
}
/**
* 生成唯一文件名(UUID + 扩展名)
*/
private String generateUniqueFileName(String extension) {
return UUID.randomUUID() + extension;
}
/**
* 提取文件扩展名(处理无扩展名的情况)
*/
private String getFileExtension(String originalFilename) {
if (originalFilename == null) return ".dat";
int lastDotIndex = originalFilename.lastIndexOf(".");
return (lastDotIndex == -1) ? ".dat" : originalFilename.substring(lastDotIndex);
}
/**
* 生成基于日期的存储路径(如 images/2024/06/15/uuid.jpg)
*/
private String generateDateBasedFilePath(String fileType, String fileName) {
if (StringUtils.isEmpty(fileType)) {
fileType = "file";
}
String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
return String.format(fileType + "/%s/%s", datePath, fileName);
}
/**
* 构建 OSS 访问 URL
*/
private String buildOssUrl(String filePath) {
return String.format("https://%s.%s/%s",
aliOssConfig.getBucketName(),
aliOssConfig.getEndpoint(),
filePath);
}
/**
* 上传json文件到OSS
* @param json
* @param fileType
* @param fileName
*/
public String uploadJSONToOSS(String json, String fileType, String fileName) {
// 创建 OSSClient 实例
try {
String filePath = generateDateBasedFilePath(fileType, fileName + ".json");
// 将 JSON 字符串转换为字节数组输入流
ByteArrayInputStream inputStream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
PutObjectRequest putObjectRequest = new PutObjectRequest(aliOssConfig.getBucketName(), filePath, inputStream);
ossClient.putObject(putObjectRequest);
return buildOssUrl(filePath);
} catch (Exception e) {
log.error("文件上传失败:" + e.getMessage());
return "";
}
}
/**
* 将JSON内容压缩为ZIP并上传到OSS
* @param json JSON字符串
* @param fileType 文件分类(如images、docs)
* @param fileName 文件名(不含扩展名)
* @return 上传后的OSS访问URL
*/
public String uploadCompressedJSONToOSS(String json, String fileType, String fileName) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
// 创建ZIP条目并添加JSON内容
ZipEntry zipEntry = new ZipEntry(fileName + ".json");
zos.putNextEntry(zipEntry);
zos.write(json.getBytes(StandardCharsets.UTF_8));
zos.closeEntry();
// 确保ZIP流完全关闭后再获取字节数组
} catch (IOException e) {
log.error("JSON压缩失败", e);
return "";
}
// 生成带日期的ZIP文件路径
String filePath = generateDateBasedFilePath(fileType, fileName + ".zip");
// 上传到OSS
try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray())) {
OSS ossClient = new OSSClientBuilder().build(
aliOssConfig.getEndpoint(),
aliOssConfig.getAccessKeyId(),
aliOssConfig.getAccessKeySecret()
);
try {
PutObjectRequest putRequest = new PutObjectRequest(
aliOssConfig.getBucketName(),
filePath,
bais
);
ossClient.putObject(putRequest);
return buildOssUrl(filePath);
} finally {
ossClient.shutdown();
}
} catch (IOException e) {
log.error("ZIP文件上传失败", e);
return "";
}
}
/**
* 将多个JSON内容压缩为ZIP并上传到OSS
* @param jsonMap JSON字符串映射,键为文件名(不含扩展名),值为JSON内容
* @param fileType 文件分类(如images、docs)
* @param zipFileName 生成的ZIP文件名(不含扩展名)
* @return 上传后的OSS访问URL
*/
public String uploadMultipleJSONsToOSS(Map<String, String> jsonMap, String fileType, String zipFileName) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
// 遍历所有JSON内容,为每个JSON创建ZIP条目
for (Map.Entry<String, String> entry : jsonMap.entrySet()) {
String fileName = entry.getKey();
String jsonContent = entry.getValue();
// 创建ZIP条目并添加JSON内容
ZipEntry zipEntry = new ZipEntry(fileName + ".json");
zos.putNextEntry(zipEntry);
zos.write(jsonContent.getBytes(StandardCharsets.UTF_8));
zos.closeEntry();
}
} catch (IOException e) {
log.error("JSON压缩失败", e);
return "";
}
// 生成带日期的ZIP文件路径
String filePath = generateDateBasedFilePath(fileType, zipFileName + ".zip");
// 上传到OSS
try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray())) {
OSS ossClient = new OSSClientBuilder().build(
aliOssConfig.getEndpoint(),
aliOssConfig.getAccessKeyId(),
aliOssConfig.getAccessKeySecret()
);
try {
PutObjectRequest putRequest = new PutObjectRequest(
aliOssConfig.getBucketName(),
filePath,
bais
);
ossClient.putObject(putRequest);
return buildOssUrl(filePath);
} finally {
ossClient.shutdown();
}
} catch (IOException e) {
log.error("ZIP文件上传失败", e);
return "";
}
}
/**
* 删除文件
*/
public void deleteFile(String filePath) {
ossClient.deleteObject(aliOssConfig.getBucketName(), filePath);
}
}
AliOssController
/**
* @author Melody
* @description:
* @date 2025-05-06
*/
@RestController
@RequestMapping("/system/file")
public class AliOssController {
private final AliOssUtil aliOssUtil;
public AliOssController(AliOssUtil aliOssUtil) {
this.aliOssUtil = aliOssUtil;
}
/**
* 阿里云OSS文件上传
*/
@PostMapping("/upload")
public SysFileDTO uploadFile(MultipartFile file,
@RequestParam(value = "fileType", required = false) String fileType) {
String url = aliOssUtil.uploadFile(file, fileType);
logger.info("上传文件路径:" + url);
return SysFileDTO.builder().url(url).build();
}
/**
* 阿里云OSS文件上传
*/
@PostMapping("/uploadJSONToOSS")
public SysFileDTO uploadJSONToOSS(@RequestParam(value = "jsonData") String jsonData) {
String url = aliOssUtil.uploadJSONToOSS(jsonData, "json", "example");
logger.info("上传文件路径:" + url);
return SysFileDTO.builder().url(url).build();
}
/**
* 阿里云OSS文件上传压缩后的json文件
*/
@PostMapping("/uploadCompressedJSONToOSS")
public SysFileDTO uploadCompressedJSONToOSS(@RequestParam(value = "jsonData") String jsonData) {
String url = aliOssUtil.uploadCompressedJSONToOSS(jsonData, "json", "example");
logger.info("上传文件路径:" + url);
return SysFileDTO.builder().url(url).build();
}
/**
* 阿里云OSS文件上传压缩后的json文件
*/
@PostMapping("/uploadMultipleJSONsToOSS")
public SysFileDTO uploadMultipleJSONsToOSS(@RequestParam(value = "jsonData") String jsonData) {
Map<String, String> jsonMap = new HashMap<>();
jsonMap.put("data1", jsonData);
jsonMap.put("data2", "{\"key2\":\"value2\"}");
String url = aliOssUtil.uploadMultipleJSONsToOSS(jsonMap, "json", "combined");
logger.info("上传文件路径:" + url);
return SysFileDTO.builder().url(url).build();
}
}
application.yml
# 阿里云OSS配置
aliyun:
oss:
endpoint: endpoint
accessKeyId: accessKeyId
accessKeySecret: accessKeySecret
bucketName: bucketName