阿里云分布式文件系统OSS实现文件上传、删除与下载

介绍

OSS:阿里云分布式文件系统

网址:OSS控制台

作用

如果在应用程序所在服务器上做文件上传与下载会给服务器造成很大压力,所以项目会使用独立的文件系统。

业务

用户头像功能

  • 文件上传:用户上传头像
  • 文件删除:用户上传了新头像之后,删除旧的头像
  • 文件下载:用户头像下载到本地

OSS控制台

创建Bucket(存储空间)

一个Bucket相当于一个文件系统服务器(可以理解为一个Nacos的namespace)

读写权限

  • 公共读:读不需要权限控制,写操作需要权限控制
  • 公共读写:读不需要权限控制,写不操作需要权限控制
  • 私有:读写都需要权限

上传文件到Bucket

获取图片的URL,在浏览器输入URL可以访问并下载图片

创建用户

给用户添加OSS的权限

获取AccessKey ID和AccessKey Secret

建议下载CSV文件,点击确定之后将无法查看AccessKey Secret

获取endPoint

获取endPoint:访问域名和数据中心

Java API使用

Java API文档:Java API文档地址

导入依赖(安装SDK)

SDK:是软件开发工具包的意思

 <!--aliyun分布式文件系统OSS-->
 <dependency>
     <groupId>com.aliyun.oss</groupId>
     <artifactId>aliyun-sdk-oss</artifactId>
     <version>3.10.2</version>
 </dependency>

配置文件

 aliyun:
   oss:
     endpoint: oss-cn-qingdao.aliyuncs.com
     keyId: ******
     keySecret: ********
     bucketName: lixianhe
     module: avatar

配置类

把配置文件中的内容赋值给静态变量

 import lombok.Getter;
 import lombok.Setter;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
 ​
 @Setter
 @Getter
 @Component
 @ConfigurationProperties(prefix = "aliyun.oss")
 public class OssConfig implements InitializingBean {
     private String endpoint;
     private String keyId;
     private String keySecret;
     private String bucketName;
     private String module;

     public static String ENDPOINT;
     public static String KEY_ID;
     public static String KEY_SECRET;
     public static String BUCKET_NAME;
     public static String MODULE;

 ​
     //当私有成员被赋值后,此方法自动被调用,从而初始化常量
     @Override
     public void afterPropertiesSet() throws Exception {
         ENDPOINT = endpoint;
         KEY_ID = keyId;
         KEY_SECRET = keySecret;
         BUCKET_NAME = bucketName;
         MODULE = module;
     }
 }

文件上传

返回文件在Oss的url

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.event.ProgressEvent;
import com.aliyun.oss.event.ProgressEventType;
import com.aliyun.oss.event.ProgressListener;
import com.aliyun.oss.model.PutObjectRequest;
import com.lixianhe.config.OssProperties;
import com.lixianhe.result.R;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

// 使用进度条,需要实现ProgressListener方法
@RestController
@RequestMapping("/api/oss/file")
public class PutObjectProgressListenerDemo implements ProgressListener {
    private long bytesWritten = 0;
    private long totalBytes = -1;

    @PostMapping("/upload")
    public R uploadFile(@RequestParam("file") MultipartFile file, @RequestParam String username) throws IOException {

        // 创建OSSClient实例(OSS客户端实例)
        OSS ossClient = new OSSClientBuilder().build(OssProperties.ENDPOINT,
                OssProperties.KEY_ID, OssProperties.KEY_SECRET);

        // 获取选择文件的输入流
        InputStream inputStream = file.getInputStream();

        // 获取文件名称
        String originalFilename = file.getOriginalFilename();

        // 拼接Oss中文件的路径
        String objectName = OssProperties.MODULE + "/" + originalFilename;

        // 判断文件上传是否成功
        boolean uploadSucceed = false;

        try {
            // 上传文件的同时指定进度条参数。此处PutObjectProgressListenerDemo为调用类的类名,请在实际使用时替换为相应的类名。
            ossClient.putObject(new PutObjectRequest(OssProperties.BUCKET_NAME, objectName, inputStream).
                    withProgressListener(new PutObjectProgressListenerDemo()));

            uploadSucceed = true;
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        if (uploadSucceed) {
            return R.ok().message("上传成功").data("URL", "https://" + OssProperties.BUCKET_NAME + "." + OssProperties.ENDPOINT + "/" + objectName);
        } else {
            return R.error().message("上传失败");
        }
    }

    // 使用进度条需要您重写回调方法,以下仅为参考示例。
    @Override
    public void progressChanged(ProgressEvent progressEvent) {
        long bytes = progressEvent.getBytes();
        ProgressEventType eventType = progressEvent.getEventType();
        switch (eventType) {
            case TRANSFER_STARTED_EVENT:
                System.out.println("Start to upload......");
                break;
            case REQUEST_CONTENT_LENGTH_EVENT:
                this.totalBytes = bytes;
                System.out.println(this.totalBytes + " bytes in total will be uploaded to OSS");
                break;
            case REQUEST_BYTE_TRANSFER_EVENT:
                this.bytesWritten += bytes;
                if (this.totalBytes != -1) {
                    int percent = (int) (this.bytesWritten * 100.0 / this.totalBytes);
                    System.out.println(bytes + " bytes have been written at this time, upload progress: " + percent + "%(" + this.bytesWritten + "/" + this.totalBytes + ")");
                } else {
                    System.out.println(bytes + " bytes have been written at this time, upload ratio: unknown" + "(" + this.bytesWritten + "/...)");
                }
                break;
            case TRANSFER_COMPLETED_EVENT:
                System.out.println("Succeed to upload, " + this.bytesWritten + " bytes have been transferred in total");
                break;
            case TRANSFER_FAILED_EVENT:
                System.out.println("Failed to upload, " + this.bytesWritten + " bytes have been transferred");
                break;
            default:
                break;
        }
    }
}

注意:要想重定向访问到文件资源下载链接要在oss工作台配置bucket跨域

文件删除

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.lixianhe.config.OssProperties;
import com.lixianhe.result.R;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/oss/file")
public class DeleteFile {

    @DeleteMapping("/del")
    public R deleteFile(@RequestParam String url) {
        // 创建OSSClient实例(OSS客户端实例)
        OSS ossClient = new OSSClientBuilder().build(OssProperties.ENDPOINT,
                OssProperties.KEY_ID, OssProperties.KEY_SECRET);

        //文件名(服务器上的文件路径)
        String host = "https://" + OssProperties.BUCKET_NAME + "." + OssProperties.ENDPOINT + "/";
        String objectName = url.substring(host.length());

        // 判断是否删除成功
        boolean deleteFileSucceed = false;

        try {
            // 删除文件或目录。如果要删除目录,目录必须为空。
            ossClient.deleteObject(OssProperties.BUCKET_NAME, objectName);

            deleteFileSucceed = true;
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        if (deleteFileSucceed) {
            return R.ok().message("删除成功");
        } else {
            return R.error().message("删除失败");
        }
    }
}

文件下载

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.event.ProgressEvent;
import com.aliyun.oss.event.ProgressEventType;
import com.aliyun.oss.event.ProgressListener;
import com.aliyun.oss.model.GetObjectRequest;
import com.lixianhe.config.OssProperties;
import com.lixianhe.result.R;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.util.Map;

@RestController
@RequestMapping("/api/oss/file")
public class GetObjectProgressListener implements ProgressListener {
    private long bytesRead = 0;
    private long totalBytes = -1;

    @PostMapping("/download")
    public R downloadFile(@RequestBody Map<String, Object> map) {
        // 获取用户名
        String username = (String) map.get("username");

        // 创建OSSClient实例(OSS客户端实例)
        OSS ossClient = new OSSClientBuilder().build(OssProperties.ENDPOINT,
                OssProperties.KEY_ID, OssProperties.KEY_SECRET);
        // 拼接文件名称
        String fileName = username + ".webp";

        // 拼接oss中文件的路径avatar/lixianhe.webp
        String objectName = OssProperties.MODULE + "/" + fileName;
        // 目标文件下载位置
        String pathName = "C:\\Users\\Administrator\\Downloads\\" + fileName;

        // 下载是否成功
        boolean downloadIsSucceed = false;

        try {
            // 下载文件的同时指定了进度条参数。
            ossClient.getObject(new GetObjectRequest(OssProperties.BUCKET_NAME, objectName).
                    withProgressListener(new GetObjectProgressListener()), new File(pathName));
            downloadIsSucceed = true;
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        if (downloadIsSucceed) {
            return R.ok().message("下载成功");
        } else {
            return R.error().message("下载失败");
        }
    }

    @Override
    public void progressChanged(ProgressEvent progressEvent) {
        long bytes = progressEvent.getBytes();
        ProgressEventType eventType = progressEvent.getEventType();
        switch (eventType) {
            case TRANSFER_STARTED_EVENT:
                System.out.println("Start to download......");
                break;
            case RESPONSE_CONTENT_LENGTH_EVENT:
                this.totalBytes = bytes;
                System.out.println(this.totalBytes + " bytes in total will be downloaded to a local file");
                break;
            case RESPONSE_BYTE_TRANSFER_EVENT:
                this.bytesRead += bytes;
                if (this.totalBytes != -1) {
                    int percent = (int) (this.bytesRead * 100.0 / this.totalBytes);
                    System.out.println(bytes + " bytes have been read at this time, download progress: " +
                            percent + "%(" + this.bytesRead + "/" + this.totalBytes + ")");
                } else {
                    System.out.println(bytes + " bytes have been read at this time, download ratio: unknown" +
                            "(" + this.bytesRead + "/...)");
                }
                break;
            case TRANSFER_COMPLETED_EVENT:
                System.out.println("Succeed to download, " + this.bytesRead + " bytes have been transferred in total");
                break;
            case TRANSFER_FAILED_EVENT:
                System.out.println("Failed to download, " + this.bytesRead + " bytes have been transferred");
                break;
            default:
                break;
        }
    }
}

测试

上传文件测试

删除文件测试

 下载文件测试

  • 7
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要从阿里云oss下载文件,可以使用Java SDK提供的OSSClient类。以下是使用Spring Boot实现阿里云oss下载文件的步骤: 1. 引入阿里云Java SDK和Spring Boot依赖 在pom.xml中添加以下依赖: ``` <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 2. 配置阿里云oss参数 在application.properties或application.yml中添加以下阿里云oss参数: ``` aliyun.oss.endpoint=<your endpoint> aliyun.oss.accessKeyId=<your accessKeyId> aliyun.oss.accessKeySecret=<your accessKeySecret> aliyun.oss.bucketName=<your bucketName> ``` 3. 实现文件下载接口 在Spring Boot的Controller中添加文件下载接口,使用OSSClient类下载指定文件: ``` @RestController public class FileController { @Autowired private OSSClient ossClient; @GetMapping("/download") public void download(@RequestParam String objectName, HttpServletResponse response) throws IOException { OSSObject ossObject = ossClient.getObject(bucketName, objectName); InputStream inputStream = ossObject.getObjectContent(); response.setHeader("Content-Disposition", "attachment;filename=" + objectName); response.setContentType("application/octet-stream"); IOUtils.copy(inputStream, response.getOutputStream()); response.flushBuffer(); } } ``` 在上面的例子中,我们使用了@RequestParam注解来获取文件名,然后使用OSSClient类下载文件。最后,使用response将文件返回给客户端。 注意:在使用完OSSClient后,需要及时关闭它以释放资源。可以在Spring Boot的配置类中添加@PreDestroy注解来关闭OSSClient: ``` @Configuration public class OSSConfig { @Value("${aliyun.oss.endpoint}") private String endpoint; @Value("${aliyun.oss.accessKeyId}") private String accessKeyId; @Value("${aliyun.oss.accessKeySecret}") private String accessKeySecret; @Value("${aliyun.oss.bucketName}") private String bucketName; @Bean public OSSClient ossClient() { return new OSSClient(endpoint, accessKeyId, accessKeySecret); } @PreDestroy public void destroy() { ossClient().shutdown(); } } ``` 以上就是使用Spring Boot阿里云oss下载文件的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙域、白泽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值