SpringBoot 对接阿里云 OSS 存储实现文件上传

下面是一个完整的指南,介绍如何在 SpringBoot 项目中集成阿里云 OSS 服务,实现图片、文档、表格等文件的上传功能。

1. 准备工作

1.1 开通阿里云 OSS 服务

  1. 登录 阿里云官网

  2. 开通 OSS 服务

  3. 创建 Bucket(存储空间)

  4. 获取 AccessKey ID 和 AccessKey Secret

1.2 添加 Maven 依赖



    com.aliyun.oss
    aliyun-sdk-oss
    3.15.1




    org.springframework.boot
    spring-boot-starter-web




    org.projectlombok
    lombok
    true

2. 配置阿里云 OSS

2.1 在 application.yml 中添加配置

aliyun:
  oss:
    endpoint: oss-cn-hangzhou.aliyuncs.com  # 根据你的Bucket所在地域填写
    access-key-id: your-access-key-id
    access-key-secret: your-access-key-secret
    bucket-name: your-bucket-name
    max-file-size: 10MB  # 最大文件大小限制
    allowed-extensions: jpg,jpeg,png,gif,pdf,doc,docx,xls,xlsx  # 允许的文件扩展名

2.2 创建配置类

@Data
@Configuration
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOSSConfig {
    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;
    private String maxFileSize;
    private String allowedExtensions;
}

3. 实现 OSS 服务

3.1 创建 OSS 服务类

@Service
@RequiredArgsConstructor
public class AliyunOSSService {
    
    private final AliyunOSSConfig aliyunOSSConfig;
    
    /**
     * 上传文件到OSS
     * @param file 文件
     * @param folder 上传到的文件夹
     * @return 文件访问URL
     */
    public String uploadFile(MultipartFile file, String folder) {
        // 验证文件
        validateFile(file);
        
        // 创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(
                aliyunOSSConfig.getEndpoint(), 
                aliyunOSSConfig.getAccessKeyId(), 
                aliyunOSSConfig.getAccessKeySecret());
        
        try {
            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileName = UUID.randomUUID().toString() + fileExtension;
            
            // 构建文件路径
            String filePath = folder + "/" + fileName;
            
            // 上传文件流
            ossClient.putObject(aliyunOSSConfig.getBucketName(), filePath, file.getInputStream());
            
            // 返回文件URL
            return generateFileUrl(filePath);
        } catch (Exception e) {
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
    
    /**
     * 验证文件是否符合要求
     */
    private void validateFile(MultipartFile file) {
        // 检查文件大小
        long maxSize = parseSize(aliyunOSSConfig.getMaxFileSize());
        if (file.getSize() > maxSize) {
            throw new RuntimeException("文件大小不能超过 " + aliyunOSSConfig.getMaxFileSize());
        }
        
        // 检查文件扩展名
        String originalFilename = file.getOriginalFilename();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        
        List allowedExtensions = Arrays.asList(aliyunOSSConfig.getAllowedExtensions().split(","));
        if (!allowedExtensions.contains(fileExtension)) {
            throw new RuntimeException("不支持的文件类型,仅支持: " + aliyunOSSConfig.getAllowedExtensions());
        }
    }
    
    /**
     * 生成文件访问URL
     */
    private String generateFileUrl(String filePath) {
        return "https://" + aliyunOSSConfig.getBucketName() + "." + aliyunOSSConfig.getEndpoint() + "/" + filePath;
    }
    
    /**
     * 将字符串格式的文件大小转换为字节数
     */
    private long parseSize(String size) {
        size = size.toUpperCase();
        if (size.endsWith("KB")) {
            return Long.parseLong(size.substring(0, size.length() - 2)) * 1024;
        } else if (size.endsWith("MB")) {
            return Long.parseLong(size.substring(0, size.length() - 2)) * 1024 * 1024;
        } else if (size.endsWith("GB")) {
            return Long.parseLong(size.substring(0, size.length() - 2)) * 1024 * 1024 * 1024;
        } else {
            return Long.parseLong(size);
        }
    }
}

4. 创建控制器

@RestController
@RequestMapping("/api/oss")
@RequiredArgsConstructor
public class OSSController {
    
    private final AliyunOSSService aliyunOSSService;
    
    /**
     * 上传文件
     * @param file 文件
     * @param folder 文件夹参数
     * @return 文件URL
     */
    @PostMapping("/upload")
    public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file,
                                             @RequestParam(value = "folder", defaultValue = "default") String folder) {
        try {
            String fileUrl = aliyunOSSService.uploadFile(file, folder);
            return ResponseEntity.ok(fileUrl);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }
    
    /**
     * 批量上传文件
     */
    @PostMapping("/upload/batch")
    public ResponseEntity> uploadFiles(@RequestParam("files") MultipartFile[] files,
                                                  @RequestParam(value = "folder", defaultValue = "default") String folder) {
        List fileUrls = new ArrayList<>();
        for (MultipartFile file : files) {
            try {
                String fileUrl = aliyunOSSService.uploadFile(file, folder);
                fileUrls.add(fileUrl);
            } catch (Exception e) {
                fileUrls.add("文件 " + file.getOriginalFilename() + " 上传失败: " + e.getMessage());
            }
        }
        return ResponseEntity.ok(fileUrls);
    }
}

5. 文件上传示例

5.1 使用 Postman 测试

  1. 选择 POST 方法

  2. 设置 URL: http://localhost:8080/api/oss/upload

  3. 选择 Body -> form-data

  4. 添加 key: file,类型选择 File,然后选择要上传的文件

  5. 可选参数: folder,设置文件上传到的文件夹

  6. 发送请求

5.2 前端 HTML 示例




    文件上传示例


    

上传文件到阿里云OSS


6. 高级功能扩展

6.1 文件下载

在 AliyunOSSService 中添加下载方法:

/**
 * 下载文件
 * @param filePath 文件路径
 * @return 文件流
 */
public InputStream downloadFile(String filePath) {
    OSS ossClient = new OSSClientBuilder().build(
            aliyunOSSConfig.getEndpoint(), 
            aliyunOSSConfig.getAccessKeyId(), 
            aliyunOSSConfig.getAccessKeySecret());
    
    try {
        OSSObject ossObject = ossClient.getObject(aliyunOSSConfig.getBucketName(), filePath);
        return ossObject.getObjectContent();
    } finally {
        // 注意:不要在这里关闭ossClient,因为流还在使用中
        // 调用者需要在使用完流后手动关闭ossClient
    }
}

6.2 文件删除

/**
 * 删除文件
 * @param filePath 文件路径
 */
public void deleteFile(String filePath) {
    OSS ossClient = new OSSClientBuilder().build(
            aliyunOSSConfig.getEndpoint(), 
            aliyunOSSConfig.getAccessKeyId(), 
            aliyunOSSConfig.getAccessKeySecret());
    
    try {
        ossClient.deleteObject(aliyunOSSConfig.getBucketName(), filePath);
    } finally {
        ossClient.shutdown();
    }
}

通过以上步骤,你就可以在SpringBoot项目中成功集成阿里云OSS服务,实现文件上传、下载和管理功能了。

你可能感兴趣的:(SpringBoot,spring,boot,阿里云,后端)