springboot使用阿里云OSS实现文件上传

在Spring Boot中集成阿里云OSS(对象存储服务)可以通过以下步骤实现:


  1. 添加Maven依赖
    pom.xml中添加阿里云OSS SDK依赖:
xml 复制代码
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.16.1</version>
</dependency>

  1. 配置阿里云OSS参数
    application.ymlapplication.properties中配置OSS参数:
yaml 复制代码
aliyun:
  oss:
    endpoint: oss-cn-hangzhou.aliyuncs.com  # 根据实际填写(注意这个地方,不要带包名)
    access-key-id: your-access-key-id
    access-key-secret: your-access-key-secret
    bucket-name: your-bucket-name

  1. 创建OSS配置类
    创建OSSConfig类读取配置并初始化OSSClient
java 复制代码
@Configuration
public class OSSConfig {
    @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;

    @Bean
    public OSS ossClient() {
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }
}

  1. 实现OSS服务工具类
    创建AliOssUtil类封装上传、下载等方法:
java 复制代码
@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) {
        if (file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }

        try {
            // 生成文件名和路径
            String fileName = generateUniqueFileName(file.getOriginalFilename());
            String filePath = generateDateBasedFilePath(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 originalFilename) {
        String extension = getFileExtension(originalFilename);
        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 fileName) {
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        return String.format("images/%s/%s", datePath, fileName);
    }

    /**
     * 构建 OSS 访问 URL
     */
    private String buildOssUrl(String filePath) {
        return String.format("https://%s.%s/%s",
                aliOssConfig.getBucketName(),
                aliOssConfig.getEndpoint(),
                filePath);
    }

    /**
     * 删除文件
     */
    public void deleteFile(String filePath) {
        ossClient.deleteObject(aliOssConfig.getBucketName(), filePath);
    }
}    

  1. 创建Controller测试接口
java 复制代码
@RestController
@RequestMapping("/oss")
public class OSSController {
    @Autowired
    private OSSService ossService;

    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) {
        try {
            return ossService.uploadFile(file);
        } catch (IOException e) {
            return "上传失败: " + e.getMessage();
        }
    }

    @DeleteMapping("/delete")
    public String delete(@RequestParam String filePath) {
        ossService.deleteFile(filePath);
        return "删除成功";
    }
}

  1. 注意事项
  2. 权限管理:确保Bucket的读写权限(ACL)设置为允许当前操作。
  3. 异常处理:建议对OSS操作添加try-catch,处理网络异常或认证失败等情况。
  4. 客户端关闭:在Spring Bean生命周期结束时关闭OSSClient(需在配置类中添加@PreDestroy方法)。
  5. 文件名唯一性:建议使用UUID或时间戳生成唯一文件名,避免覆盖。

  1. 扩展功能
    • 分片上传:使用ossClient.initiateMultipartUpload处理大文件分片上传。

• STS临时凭证:通过STS服务获取临时Token,提升安全性。

• CDN加速:如果启用了CDN,可直接返回CDN域名而非OSS域名。


通过以上步骤,即可在Spring Boot中实现阿里云OSS的基本文件操作。

相关推荐
GoGeekBaird3 小时前
69天探索操作系统-第66天:为现代操作系统设计高级实时进程间通信机制
后端·操作系统
还是鼠鼠4 小时前
单元测试-概述&入门
java·开发语言·后端·单元测试·log4j·maven
一步一念4 小时前
Langchaine4j 流式输出 (6)
spring boot·ai·langchain4j
我最厉害。,。6 小时前
接口安全&SOAP&OpenAPI&RESTful&分类特征导入&项目联动检测
后端·restful
MyikJ6 小时前
Java求职面试:从Spring到微服务的技术挑战
java·数据库·spring boot·spring cloud·微服务·orm·面试技巧
MyikJ6 小时前
Java 面试实录:从Spring到微服务的技术探讨
java·spring boot·微服务·kafka·spring security·grafana·prometheus
AntBlack7 小时前
计算机视觉 : 端午无事 ,图像处理入门案例一文速通
后端·python·计算机视觉
福大大架构师每日一题9 小时前
2025-06-02:最小可整除数位乘积Ⅱ。用go语言,给定一个表示正整数的字符串 num 和一个整数 t。 定义:如果一个整数的每一位都不是 0,则称该整数为
后端
Code_Artist9 小时前
[Mybatis] 因 0 != null and 0 != '' 酿成的事故,害得我又过点啦!
java·后端·mybatis
程序员博博9 小时前
看到这种代码,我直接气到想打人
后端