一、初始化客户端

1)引入 OSS 依赖

        <!--        阿里云oss-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.18.4</version>
        </dependency>

2)新建 OssClientConfig 类

负责读取配置文件,并创建一个OOS客户端的Bean。代码如下:

@Configuration
@ConfigurationProperties(prefix = "oos.client")
@Data
public class OosClientConfig {

    /**
     * 域名
     */
    private String host;

    /**
     * secretId
     */
    private String secretId;

    /**
     * 密钥(注意不要泄露)
     */
    private String secretKey;

    /**
     * 区域
     */
    private String region;

    /**
     * 桶名
     */
    private String bucket;

    @Bean
    public OSSClient ossClient() {
        return OSSClient.newBilder()
                .region(region) // // 设置bucket的区域
                .credentialsProvider(() -> new Credentials(secretId, secretKey)) // // 初始化用户身份信息(secretId, secretKey)
                .build();
    }
}

3) application-local.yml 配置

# 对象存储配置  
oos:  
  client:  
    host: xxx  
    secretId: xxx  
    secretKey: xxx  
    region: xxx  
    bucket: xxx

二、通用类

新建 OssManager 类

提供通用的对象存储操作,比如文件上传,文件下载,等。

@Component
public class OosManager {

    @Resource
    private OosClientConfig oosClientConfig;

    @Resource
    private OSSClient ossClient;

    /**
     * 上传文件
     *
     * @param key  文件路径
     * @param file 文件
     * @return 上传结果
     */
    public PutObjectResult putObject(String key, File file) {
        try (FileInputStream fis = new FileInputStream(file)) {
            BinaryData binaryData = BinaryData.fromStream(fis);

            PutObjectRequest putObjectRequest = PutObjectRequest.newBuilder()
                    .bucket(oosClientConfig.getBucket()) // 存储桶名称
                    .key(key) // 文件路径
                    .body(binaryData) // 文件内容
                    .build(); // 创建请求
            return ossClient.putObject(putObjectRequest);
        } catch (IOException e) {
            throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 下载文件
     *
     * @param key 文件路径
     */
    public InputStream getObject(String key) {
        GetObjectRequest getObjectRequest = GetObjectRequest.newBuilder()
                .bucket(oosClientConfig.getBucket()) // 存储桶名称
                .key(key) // 文件下载路径
                .build();
        GetObjectResult result = ossClient.getObject(getObjectRequest);
        return result.body();
    }

三、Controller测试

@RestController
@RequestMapping("/file")
@Slf4j
public class FileController {

    @Resource
    private OosManager oosManager;

    /**
     * 文件上传
     *
     * @param multipartFile 文件
     * @return 上传结果
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @PostMapping("test/upload")
    public BaseResponse<String> uploadFile(@RequestPart("file") MultipartFile multipartFile) {
        // 获取文件名
        String originalFilename = multipartFile.getOriginalFilename();
        // 拼接设置文件路径
        // 获取当前时间,设置格式
        String datePath = LocalDateTime.now()
                .format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        // 添加 UUID 防止同一天同文件名冲突
        String uuid = UUID.randomUUID().toString().replace("-", "");

        // 获取文件后缀
        // 确认文件名不为空和包含扩展名
        String suffix = originalFilename != null && originalFilename.contains(".")
                ? originalFilename.substring(originalFilename.lastIndexOf("."))
                : "";
        // 拼接文件名
        String fileName = uuid + suffix;
        // 拼接文件路径
        String filepath = String.format("%s/%s", datePath, fileName);

        File file = null;
        try {
            // 文件上传
            file = File.createTempFile(fileName, null);
            multipartFile.transferTo(file);
            oosManager.putObject(filepath, file);
            // 返回文件路径
            return ResultUtils.success(filepath);
        } catch (Exception e) {
            log.error("file upload error, filepath = {} ", filepath, e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败");
        } finally {
            // 释放临时文件
            if (file != null) {
                boolean res = file.delete();
                if (!res) {
                    log.error("file delete error, filepath = {}", filepath);
                }
            }
        }
    }

    /**
     * 文件下载
     *
     * @param filePath 文件路径
     * @param response 响应对象
     */
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @GetMapping("test/download")
    public void DownloadFile(String filePath, HttpServletResponse response) {
        // 获取文件输入流
        InputStream is = oosManager.getObject(filePath);
        try {
            byte[] bytes = IOUtils.toByteArray(is);
            // 设置响应头
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + filePath);
            // 写入响应
            response.getOutputStream().write(bytes);
            // 刷新缓冲区
            response.getOutputStream().flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            // 释放流
            if (is != null) {
                IOUtils.closeQuietly(is, log);
            }
        }

    }
}