Springboot集成阿里云OSS上传

发布于:2025-06-21 ⋅ 阅读:(18) ⋅ 点赞:(0)

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

网站公告

今日签到

点亮在社区的每一天
去签到