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
相关推荐
bug攻城狮17 小时前
Spring Boot Banner
java·spring boot·后端
MadPrinter17 小时前
SpringBoot学习日记 Day11:博客系统核心功能深度开发
java·spring boot·后端·学习·spring·mybatis
Java水解18 小时前
Spring Boot 启动流程详解
spring boot·后端
网安Ruler19 小时前
第49天:Web开发-JavaEE应用&SpringBoot栈&模版注入&Thymeleaf&Freemarker&Velocity
java·spring boot·后端
奔跑吧邓邓子19 小时前
【Java实战㉟】Spring Boot与MyBatis:数据库交互的进阶之旅
java·spring boot·实战·mybatis·数据库交互
kong@react21 小时前
springboot项目详细配置rabbitmq及使用rabbitmq完成评论功能
spring boot·rabbitmq·java-rabbitmq
九转苍翎21 小时前
星辰诞愿——生日快乐
spring boot
JIngJaneIL21 小时前
汽车租赁|基于Java+vue的汽车租赁系统(源码+数据库+文档)
java·vue.js·spring boot·汽车·论文·毕设·汽车租赁系统
Clownseven1 天前
CN2 GIA线路深度解析:阿里云/腾讯云选哪个?(附三网评测)
阿里云·云计算·腾讯云
Linux运维技术栈1 天前
Terraform 从入门到实战:历史、原理、功能与阿里云/Azure 上手指南
运维·阿里云·kubernetes·azure·terraform