OSS开通以及引入SpringCloud项目实践

发布于:2024-12-18 ⋅ 阅读:(144) ⋅ 点赞:(0)

1. 阿里云OSS简介

阿里云OSS(Object Storage Service)是阿里云提供的一种海量、安全、低成本、高可靠的云存储服务。

使用场景

  • 数据备份与存档:OSS提供高可靠性和耐久性的存储,适合数据备份和长期存档,可以存储文档、图片、音视频等。
  • 图片和音视频存储与处理:OSS支持存储和处理图片、音频和视频文件,提供图片处理和音视频处理功能。
  • 移动应用存储:OSS提供与移动应用开发相关的服务,可以在移动应用中集成对象存储功能。
  • 大数据分析:OSS可以作为大数据分析平台的存储后端,存储大规模数据集,并进行分析处理。

2. 开通OSS服务

对象存储 OSS_云存储服务_企业数据管理_存储-阿里云

3. 创建bucket

4. 集成OSS到项目中

4.1. 为OSS创建module

这里我选择的是微服务的方式来单独为OSS服务创建了一个子服务,因为现在的项目大多数都采取微服务的思想。

查看Java SDK参考文档:安装OSS Java SDK_对象存储(OSS)-阿里云帮助中心

将OSS单独作为一个子服务。新建一个module ,然后导入需要的依赖,如下图。

<dependencies>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.17.4</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- no more than 2.3.3-->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>
    </dependencies>

4.2. 创建OSS配置类


import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import jakarta.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AliyunOssConfig {

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


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


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

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

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

    /**
     * 配置 OSS 客户端
     */
    public OSS ossClient;

    @Bean
    public OSS ossClient() throws ClientException {
        DefaultCredentialProvider credentialsProvider = CredentialsProviderFactory.newDefaultCredentialProvider(
                accessKeyId, accessKeySecret);

        // 创建ClientBuilderConfiguration
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);

        // 使用内网endpoint进行上传
        ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();
        return ossClient;
    }

    @PreDestroy
    public void closeOSSClient() {
        ossClient.shutdown();
    }

}

nacos配置

这里的配置需要在Nacos中进行配置,配置的具体内容需要根据实际情况而定。

endpoint对应:OSS地域和访问域名_对象存储(OSS)-阿里云帮助中心

accessKeyId和Secret是自己阿里云帐号配置的。如果没有设置,点击首页的头像可以设置,这个需要保存好,因为无法再次查看自己的AK。

4.3. 封装OSS的service

这里是针对OSS使用的简单封装,在自己的项目中可以根据项目的具体业务进行更加符合自己业务逻辑的service封装。

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

@Service
public class AliyunOssService {

    private final OSS ossClient;
    private final String bucketName;

    public AliyunOssService(OSS ossClient, @Value("${aliyun.oss.bucketName}") String bucketName) {
        this.ossClient = ossClient;
        this.bucketName = bucketName;
    }

    /**
     * 上传文件
     *
     * @param file       文件对象
     * @param objectName OSS中的目标文件名(包含路径)
     * @return 文件的访问 URL
     */
    public String uploadFile(MultipartFile file, String objectName) throws Exception {
        try (InputStream inputStream = file.getInputStream()) {
            ossClient.putObject(new PutObjectRequest(bucketName, objectName, inputStream));
        }
        return getFileUrl(objectName);
    }

    /**
     * 下载文件到本地
     *
     * @param objectName OSS中的文件名(包含路径)
     * @param localPath  本地保存路径
     */
    public void downloadFile(String objectName, String localPath) {
        ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localPath));
    }

    /**
     * 删除文件
     *
     * @param objectName OSS中的文件名(包含路径)
     */
    public void deleteFile(String objectName) {
        ossClient.deleteObject(bucketName, objectName);
    }

    /**
     * 获取文件访问 URL(带有效期的签名 URL)
     *
     * @param objectName OSS中的文件名(包含路径)
     * @return 文件的访问 URL
     */
    public String getFileUrl(String objectName) {
        // 设置过期时间(1小时)
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
        return url.toString();
    }

    /**
     * 检查文件是否存在
     *
     * @param objectName OSS中的文件名(包含路径)
     * @return 是否存在
     */
    public boolean doesObjectExist(String objectName) {
        return ossClient.doesObjectExist(bucketName, objectName);
    }
}

4.4. 配置自动装配

如果在别的服务,想要使用OSS服务,就需要OSSBean能够被自动加载。这个配置类属于一个独立的模块或依赖包,该模块被引入其他 Spring Boot 应用时,如何实现这些配置会自动生效?

在该服务的resources下创建一个META-INF目录然后继续创建spring目录,然后创建一个 org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,在文件中写入需要被自动加载到其他SpringBoot项目中的 全限定名 ,也就是包名+类名。

com.guan.ojcommonfile.config.AliyunOssConfig
com.guan.ojcommonfile.service.AliyunOssService

4.5. 测试Service

@RestController
@RequestMapping("/test")
public class TestController extends BaseController {

    @Resource
    private AliyunOssService aliyunOssService;

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            String objectName = "uploads/" + file.getOriginalFilename(); // 自定义路径
            String url = aliyunOssService.uploadFile(file, objectName);
            return ResponseEntity.ok("File uploaded successfully. URL: " + url);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("File upload failed: " + e.getMessage());
        }
    }


}

调用接口上传图片(这里是因为我的测试中使用了网关,我直接调用了网关的接口):

点击返回的链接,下载刚才上传图片: