第三次课-阿里云对象存储

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

分类: springboot 专栏: 新版在线教育项目 标签: 对象存储 easyExcel

2024-03-27 09:37:24 502浏览

对象存储和easyExcel

对象存储

为了解决海量数据存储与弹性扩容,项目中我们采用云存储的解决方案- 阿里云OSS。

阿里云开通oss服务

(1)申请阿里云账号

(2)实名认证

(3)开通“对象存储OSS”服务

(4)进入管理控制台

创建Bucket

选择:标准存储、公共读、不开通

上传默认头像

创建文件夹avatar,上传默认的用户头像

拿到AccessKey ID 和 AccessKey Secret

AccessKey ID 和 AccessKey Secret 是您访问阿里云 API 的密钥

LTAI5tFicE3BjrB7XWCmjN2k
B0yaYi7PdlK023lznurimrG9nUOCIf

快速入门

  • 依赖
<dependency>
  <groupId>com.aliyun.oss</groupId>
  <artifactId>aliyun-sdk-oss</artifactId>
  <version>3.15.1</version>
</dependency>

<!--如果使用的是Java 9及以上的版本,则需要添加JAXB相关依赖,以下就是-->

<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>

参考文章:

https://help.aliyun.com/zh/oss/developer-reference/simple-upload-11?spm=a2c4g.11186623.0.0.540548c7WtgMDG

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import java.io.File;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "yourAccessKeyId";
        String accessKeySecret = "yourAccessKeySecret";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "exampledir/exampleobject.txt";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
        String filePath= "D:\\localpath\\examplefile.txt";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObjectRequest对象。            
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            // ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            // putObjectRequest.setMetadata(metadata);

            // 上传文件。
            ossClient.putObject(putObjectRequest);
        } 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();
            }
        }
    }
}            

注意:endpoint怎么写

  • 上传成功后拿到文件的成功路径
 String url = "https://"+bucketName+"."+endpoint+"/"+fileName;

剩下就是改造成controller

封装如下:

@RestController
@Tag(name = "oss文件上传")
public class UploadController {

    @Value("${ali.endpoint}")
    private String endpoint;
    @Value("${ali.endpoint2}")
    private String endpoint2;
    @Value("${ali.bucketName}")
    private String bucketName;
    @Value("${ali.accesskeyId}")
    private String accesskeyId;
    @Value("${ali.secretAccesskey}")
    private String secretAccesskey;


    @PostMapping("/oss/{type}")
    @Operation(summary = "上传接口")
    public ResultVo upload(@PathVariable String type, MultipartFile file){
        if (file==null || file.isEmpty()) {
            return ResultVo.error("文件必填");
        }

        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        SimpleDateFormat format= new SimpleDateFormat("yyyy/MM/dd");
        String dataPath = format.format(new Date());

        String fileName=dataPath+"/"+ UUID.randomUUID().toString().replace("-","")+suffix;

        StringBuffer objectName = new StringBuffer();
        switch (type){
            case Constant.UploadType.AVATAR:
            case Constant.UploadType.VIDEO:
            case Constant.UploadType.COVER:
                objectName.append(type+"/");
                break;
            default:
                return ResultVo.error("参数不对");
        }

        objectName.append(fileName);
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint,accesskeyId,secretAccesskey );

        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName.toString(), file.getInputStream());

            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);


            String url="https://"+bucketName+"."+endpoint2+"/"+objectName;

            System.out.println(url);

            //拿到最终上传成功的url

            return ResultVo.success(null,url);
        } catch (Exception e) {

            return ResultVo.error("上传阿里云失败");
        }   finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

    }
}

application.yml

ali:
  endpoint: https://oss-cn-hangzhou.aliyuncs.com
  endpoint2: oss-cn-hangzhou.aliyuncs.com
  bucketName: 70-edu
  accesskeyId: LTAI5tFicE3BjrB7XWCmjN2k
  secretAccesskey: B0yaYi7PdlK023lznurimrG9nUOCIf

涉及到的系统静态常量

public class Concat {

    public static class TokenException{
        // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;

        public static  final Integer IllegalToken=50008;
        public static final Integer OtherClientslogged=50012;
        public static final Integer TokenExpired=50014;
    }
    public static class FileType{
        public static  final String AVATAR="avatar";
        public static final String COVER="cover";
        public static final String VIDEO="video";

    }
}

由于我把oss模块单独拿出来了,所以要注意swagger扫码control的问题,

哪个模块用到oss上传,就把oss依赖加到哪个模块的依赖中

上传头像组件

从vue-element-admin中复制

主要的步骤如下:

复制头像上传组件

vue-element-admin复制组件:

vue-element-admin/src/components/ImageCropper

vue-element-admin/src/components/PanThumb

前端参考实现

src/views/components-demo/avatarUpload.vue

前端添加文件上传组件

<!-- 讲师头像 -->
<el-form-item label="讲师头像">
    <!-- 头衔缩略图 -->
    <pan-thumb :image="teacher.avatar"/>
    <!-- 文件上传按钮 -->
    <el-button type="primary" icon="el-icon-upload" @click="imagecropperShow=true">更换头像
    </el-button>
    <!--
v-show:是否显示上传组件
:key:类似于id,如果一个页面多个图片上传控件,可以做区分
:url:后台上传的url地址
@close:关闭上传组件
@crop-upload-success:上传成功后的回调 -->
    <image-cropper
                   v-show="imagecropperShow"
                   :width="300"
                   :height="300"
                   :key="imagecropperKey"
                   :url="BASE_API+'/admin/oss/file/upload'"
                   field="file"
                   @close="close"
                   @crop-upload-success="cropSuccess"/>
</el-form-item>
引入组件模块
 
import ImageCropper from '@/components/ImageCropper'
import PanThumb from '@/components/PanThumb'

设置默认头像

config/dev.env.js中添加阿里云oss bucket地址

OSS_PATH: '"https://jf3q.oss-cn-beijing.aliyuncs.com"'

组件中初始化头像默认地址

const defaultForm = {
  ......,
  avatar: process.env.OSS_PATH + '/avatar/default.jpg'
}

js脚本实现上传和图片回显

export default {
  components: { ImageCropper, PanThumb },
  data() {
    return {
      //其它数据模型
      ......,
        
      BASE_API: process.env.BASE_API, // 接口API地址
      imagecropperShow: false, // 是否显示上传组件
      imagecropperKey: 0 // 上传组件id
    }
  },
    
  ......,
    
  methods: {
    //其他函数
    ......,
    // 上传成功后的回调函数
    cropSuccess(data) {
      console.log(data)
      this.imagecropperShow = false
      this.teacher.avatar = data.url
      // 上传成功后,重新打开上传组件时初始化组件,否则显示上一次的上传结果
      this.imagecropperKey = this.imagecropperKey + 1
    },
    // 关闭上传组件
    close() {
      this.imagecropperShow = false
      // 上传失败后,重新打开上传组件时初始化组件,否则显示上一次的上传结果
      this.imagecropperKey = this.imagecropperKey + 1
    }
  }
}

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695