Springboot集成阿里云OSS上传

Springboot集成阿里云OSS上传

API 接口描述

DEMO提供的四个API接口,支持不同方式的文件和 JSON 数据上传:

1. 普通文件上传接口

上传任意类型的文件

2. JSON 字符串上传接口

上传 JSON 字符串

3. 单个 JSON 压缩上传接口

上传并压缩 JSON 字符串

4. 批量 JSON 压缩上传接口

批量上传并压缩多个 JSON 字符串

AliOssConfig

java 复制代码
/**
 * @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

java 复制代码
/**
 * @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

java 复制代码
/**
 * @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

yml 复制代码
# 阿里云OSS配置
aliyun:
  oss:
    endpoint: endpoint
    accessKeyId: accessKeyId
    accessKeySecret: accessKeySecret
    bucketName: bucketName
相关推荐
谁在黄金彼岸3 分钟前
Spring Boot + WebFlux 全面使用指南
spring boot
希望永不加班7 分钟前
SpringBoot 主启动类解释:@SpringBootApplication 到底做了什么
java·spring boot·后端·spring
智能工业品检测-奇妙智能16 分钟前
国产化系统的性价比对比
人工智能·spring boot·后端·openclaw·奇妙智能
SmartBrain2 小时前
Spring Boot的高性能技术栈的工程实践
spring boot·后端·架构
小仓桑2 小时前
【Agent智能体项目实战三】LangChain调用通义千问保姆级教程
数据库·阿里云·langchain·agent
dreamxian2 小时前
苍穹外卖day09
java·spring boot·tomcat·log4j·maven
q5431470873 小时前
VScode 开发 Springboot 程序
java·spring boot·后端
学习要积极3 小时前
Springboot图片验证码-EasyCaptcha
java·spring boot·后端
yuyu_03044 小时前
畜牧(牛)数字化管理系统系统概要
spring boot
波波七4 小时前
SSM与Springboot是什么关系? -----区别与联系
java·spring boot·后端