云服务器--阿里云OSS(2)【Springboot使用阿里云OSS】

📒 阿里云 OSS + Spring Boot + 异步任务(直接存 OSS)

1. 项目结构

Swift 复制代码
src/main/java/com/example/demo
  ├── controller
  │     └── UploadController.java  // 接收上传请求
  ├── service
  │     ├── AsyncUploadService.java // 异步上传逻辑
  │     └── OssService.java         // OSS 上传工具类
  └── DemoApplication.java          // 主启动类

2. Maven 依赖

XML 复制代码
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.17.4</version>
</dependency>

3. application.properties 配置

XML 复制代码
# OSS 配置
oss.endpoint=https://oss-cn-hangzhou.aliyuncs.com #你的Endpoint(地域节点)点击Bucket 列表点击概览滑到下面就能看到
oss.access-key-id=你的AccessKeyId
oss.access-key-secret=你的AccessKeySecret
oss.bucket-name=你的BucketName
oss.folder= images

4. OSS 上传工具类 OssService.java

oss上放置的资源分私有/公共读/公共读写,我们如果选择作为图片/文件服务器时,选择 公共读、私有写每个文件可以单独选择读写权限,通过springboot代码创建文件权限默认和Bucket的一致,如果这句话不太理解可以去看笔者的这篇博客: 云服务器--阿里云OSS(1)【阿里云OSS简单介绍以及环境准备】-CSDN博客

java 复制代码
package com.example.demo.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@Service
public class OssService {
    @Value("${oss.endpoint}")
    private String endpoint;

    @Value("${oss.access-key-id}")
    private String accessKeyId;

    @Value("${oss.access-key-secret}")
    private String accessKeySecret;

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

    @Value("${oss.folder}")
    private String folder;

    /**
     * 直接通过 MultipartFile 的输入流上传到 OSS
     */
    public String uploadFile(MultipartFile file, String fileName) throws IOException {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 上传文件(不落地到磁盘)
        ossClient.putObject(bucketName, fileName, file.getInputStream());
        ossClient.shutdown();
        //endpoint.replace("https://", ""),endpoint会带有https://,会与前面的矛盾要去掉,endpoint中的https://
        String path = "https://" + bucketName + "." + endpoint.replace("https://", "") + "/" folder + "/"+ fileName;
        //可以把路径保存到数据库中,前端就可以根据这个路径访问了
        save(path);
        // 返回 OSS 文件访问 URL
        return path;
    }
}

5 . 异步上传服务 AsyncUploadService.java

java 复制代码
package com.example.demo.service;

import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

@Service
public class AsyncUploadService {
    @Autowired
    private OssService ossService;

    /**
     * 异步上传文件到 OSS
     * @param file 上传的 MultipartFile
     * @param fileName 存储到 OSS 的文件名
     */
    @Async // 异步执行,不阻塞主线程
    public void upload(MultipartFile file, String fileName) {
        try {
            // 直接通过 InputStream 上传到 OSS
            ossService.uploadFile(file, fileName);
            System.out.println("文件异步上传完成:" + fileName);
        } catch (Exception e) {
            e.printStackTrace();
            // 这里可加失败重试机制
        }
    }
}

6. 控制器 UploadController.java

java 复制代码
package com.example.demo.controller;

import com.example.demo.service.AsyncUploadService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.UUID;

@RestController
@RequiredArgsConstructor
public class UploadController {

    private final AsyncUploadService asyncUploadService;

    /**
     * 接收文件上传请求
     */
    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) {
        // 生成唯一文件名,避免重名覆盖
        String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();

        // 异步上传到 OSS
        asyncUploadService.upload(file, fileName);

        // 直接返回提示(上传可能还在进行中)
        return "文件已接收,正在后台上传到 OSS...";
    }
}

7. 启用异步任务

java 复制代码
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync // 开启 @Async 支持
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

🔍 逻辑说明

  1. 用户上传文件 → 控制器接收 MultipartFile

  2. 生成唯一文件名(避免 OSS 覆盖旧文件)

  3. 异步执行上传@Async 标记的方法)

  4. 直接用 MultipartFile.getInputStream() 上传到 OSS(避免本地磁盘中转)

  5. 返回提示信息(上传还在后台进行)


📌 关键点

  • 使用 异步任务 避免上传过程阻塞 HTTP 请求

  • 使用 MultipartFile.getInputStream() 避免文件落地到本地磁盘

  • 生产环境可加 失败重试机制(例如 Spring Retry)

  • OSS Bucket 权限一般用 公共读 + 私有写

    • 公共读:用户可直接访问图片 URL

    • 私有写:只有服务器能写入,防止恶意上传

相关推荐
翼龙云_cloud11 分钟前
阿里云渠道商:轻量服务器远程协作性能优化指南
运维·服务器·阿里云·性能优化·云计算
菜鸡的升级之路15 分钟前
服务器卡死排查流程
运维·服务器
恒创科技HK17 分钟前
租用日本服务器价格便宜的原因
运维·服务器
FreeBuf_20 分钟前
新型PCPcat恶意软件利用React2Shell漏洞48小时内入侵超5.9万台服务器
运维·服务器
AI浩7 小时前
【Labelme数据操作】LabelMe标注批量复制工具 - 完整教程
运维·服务器·前端
Guheyunyi8 小时前
智慧消防管理系统如何重塑安全未来
大数据·运维·服务器·人工智能·安全
一条可有可无的咸鱼10 小时前
企业招聘信息,企业资讯进行公示
java·vue.js·spring boot·uni-app
雾削木11 小时前
k230 Pyhton三角形识别
运维·服务器·网络·stm32·智能路由器
北京聚信万通科技有限公司11 小时前
传输协议:AS3
服务器·网络·安全·电子数据交换·as3