导读:本期聚焦于王柏年创作的《Spring Boot 如何整合阿里云 OSS 实现文件上传与云端管理?》,敬请观看详情。为什么越来越多的项目把文件存储迁移到对象存储服务上?本文围绕 Spring Boot 整合阿里云 OSS 这一常见需求,从创建 OSS Bucket、获取 AccessKey 开始,逐步讲解 SDK 依赖引入、客户端配置、文件上传、下载链接生成以及删除操作的完整实现,并给出按日期分目录、上传回调等实用技巧,同时分析直传与服务端转传两种方案的适用场景,帮助你快速搭建稳定可靠的文件云端存储模块。

传统的文件存储方案大多是把文件写到本地磁盘,或者在服务器上挂载一块专门的存储盘。这种做法在单体应用阶段没什么问题,一旦项目做了集群部署,就会立刻暴露缺陷:用户上传的文件散落在多台机器上,Nginx 做负载均衡后经常出现图片时有时无的尴尬情况。对象存储服务(OSS)就是为了解决这类问题而生的,文件统一存放在云端,应用服务器只负责业务逻辑,存储和访问全部交给专业的存储服务处理。阿里云 OSS 是国内使用最广泛的方案之一,下面详细介绍如何在 Spring Boot 项目中完成整合。

Spring Boot 如何整合阿里云 OSS 实现文件上传与云端管理?

一、准备工作:创建 Bucket 与获取 AccessKey

整合之前需要先在阿里云控制台完成两项准备。第一项是创建 Bucket,Bucket 可以理解为一个顶层的存储空间,名字在阿里云全网唯一。创建时建议把读写权限设置为「公共读」,这样上传后的文件可以直接通过 URL 访问;如果你的文件涉及隐私,比如身份证照片、合同扫描件,就应该设置为「私有」,访问时通过签名 URL 临时授权。

第二项是获取 AccessKey ID 和 AccessKey Secret。进入阿里云的 RAM 访问控制台,创建一个专门用于 OSS 的子账号,只授予 AliyunOSSFullAccess 权限,切勿直接使用主账号的 AccessKey。主账号密钥一旦泄露,攻击者可以操作你名下所有资源,而子账号即使泄露,损失范围也可控。密钥信息建议放在配置文件或者环境变量中,不要硬编码到代码里提交到 Git 仓库。

二、引入依赖与配置 OSS 客户端

阿里云官方提供了 Java SDK,在 pom.xml 中加入如下依赖即可:

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.17.4</version>
</dependency>

如果项目使用 Java 9 及以上版本,还需要额外补充 JAXB 相关依赖,否则运行时会抛出 ClassNotFound 异常,这是很多人初次整合时踩过的坑。接下来在 application.yml 中编写配置项:

aliyun:
  oss:
    endpoint: oss-cn-hangzhou.aliyuncs.com
    access-key-id: 你的AccessKeyId
    access-key-secret: 你的AccessKeySecret
    bucket-name: your-bucket-name

为了代码结构清晰,通常把配置封装成一个属性类,再通过配置类把 OSSClient 注册为 Spring 容器中的 Bean。需要注意的是,OSSClient 是线程安全的,全局持有一个实例即可,不需要每次请求都新建,频繁创建连接会带来明显的性能开销。

@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);
    }
}

三、实现文件上传、下载与删除

上传的核心逻辑是调用 ossClient.putObject 方法。上传前有一件事必须处理:文件名的唯一性。用户上传的图片经常叫 1.jpg、head.png 这类重名文件,如果不加处理直接上传,后上传的会把先上传的覆盖掉。常见的做法是用 UUID 生成新文件名,同时保留原始扩展名,并按照日期建立目录,方便后续按时间维度管理和清理。

@Service
public class OssService {

    @Autowired
    private OSS ossClient;

    @Value("${aliyun.oss.bucket-name}")
    private String bucketName;

    public String upload(MultipartFile file) throws IOException {
        // 按日期分目录,例如 2024/06/uuid.jpg
        String datePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
        String originalName = file.getOriginalFilename();
        String suffix = originalName.substring(originalName.lastIndexOf("."));
        String objectName = datePath + "/" + UUID.randomUUID() + suffix;

        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(file.getContentType());
        // 设置文件在浏览器中打开时的行为
        metadata.setContentDisposition("attachment;filename=" + originalName);

        ossClient.putObject(bucketName, objectName, file.getInputStream(), metadata);
        // 公共读 Bucket 可直接拼接 URL 返回
        return "https://" + bucketName + "." + "oss-cn-hangzhou.aliyuncs.com" + "/" + objectName;
    }

    public void delete(String objectName) {
        ossClient.deleteObject(bucketName, objectName);
    }
}

对于私有 Bucket,直接拼 URL 是访问不了的,需要生成带签名的临时链接。generatePresignedUrl 方法支持设置过期时间,比如生成一个 10 分钟内有效的下载地址,代码如下:

public String getSignedUrl(String objectName) {
    Date expiration = new Date(System.currentTimeMillis() + 10 * 60 * 1000);
    URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
    return url.toString();
}

删除操作比较简单,但要注意业务层面的处理:数据库里通常存的是完整 URL,而删除接口需要的是 objectName,也就是 URL 中去掉域名后的路径部分。建议在存储时就把 URL 和 objectName 分开存两个字段,避免每次删除都要做字符串截取。

四、服务端转传与客户端直传的选择

上面实现的是服务端转传模式:文件先上传到你的应用服务器,再由服务器转发到 OSS。这种模式实现简单,方便在服务端做权限校验、文件校验和名称处理,缺点是文件流会占用应用服务器的带宽,大文件场景下服务器容易成为瓶颈。

另一种是客户端直传模式,前端直接把文件传到 OSS,流程是前端先向服务端请求上传凭证,服务端用 STS 或 PostObject 签名方式生成临时凭证返回,前端拿到凭证后直接上传。这种模式完全绕开了应用服务器,适合图片量大、文件体积大的业务,比如视频网站、电商图床。当然,直传模式的校验逻辑要复杂一些,需要限制上传文件的大小和类型,防止凭证被滥用。

一般的项目初期可以直接用服务端转传,等流量上来后再切换为客户端直传,两种模式的文件管理接口是共用的,迁移成本并不高。另外提醒一点,OSS 会按存储量和外网流出流量计费,生产环境建议绑定 CDN 加速域名,既能提升访问速度,也能显著降低流量费用。

到这里,一个完整的文件云端存储模块就搭建完成了。核心步骤总结起来就是:创建 Bucket、配置客户端 Bean、封装上传下载删除三个方法,再根据业务规模决定采用转传还是直传。这套方案在实际项目中已经非常成熟稳定,配合定期清理策略和 CDN,足以支撑绝大多数业务的文件存储需求。

Spring Boot阿里云OSS文件上传修改时间:2026-09-07 05:58:32

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260907/52019.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。