minio文件直传(后端授权,前端直接上传)

发布时间:2022-04-11 01:01:27
修改时间:2023-02-18 15:29:19
总阅读数:3103
今日阅读数:0
昨日日阅读数:0
字数:4819

minio实现后端授权,前端直接上传

minio安装

安装方式(已安装可跳过此步骤)

https://min.io/download#/linux

后端授权

添加依赖

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.3.7</version>
</dependency>

代码

package com.controller;

import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.errors.*;
import io.minio.http.Method;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * @author qc
 * @version 1.0
 * @date 2022/4/10 16:53
 */
@RestController
@RequestMapping("/file")
public class FileController {

    private static final String BUCKET_NAME = "test";
    private static final String ENDPOINT = "http://localhost:9000";
    private static final String ACCESSKEY = "minioadmin";
    private static final String SECRETKEY = "minioadmin";

    /**
     * 获取minio上传路径
     *
     * @param name 文件名称
     * @return java.lang.String 上传的url
     * @author qc
     * @date 2022/4/10 16:56
     */
    @GetMapping("/upload/url")
    public String getUploadUrl(String name) {

        if (name == null || name.trim().length() == 0) {
            name = UUID.randomUUID().toString();
        }

        String url = null;

        MinioClient minioClient = MinioClient.builder()
                .endpoint(ENDPOINT)
                .credentials(ACCESSKEY, SECRETKEY)
                .build();
        try {
            url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs
                    .builder()
                    .bucket(BUCKET_NAME)
                    .object(name)
                    .method(Method.PUT)
                    .expiry(60 * 60 * 24)
                    .build());
        } catch (ErrorResponseException | NoSuchAlgorithmException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | XmlParserException | ServerException e) {
            e.printStackTrace();
        }
        return url;
    }

}

前端上传

<template>
  <div>
    <div style="width:30%;margin: auto">
      <el-upload
          v-loading="loading"
          class="avatar-uploader"
          multiple
          :show-file-list="false"
          :http-request="toUpload"
      >
        <img v-if="imgUrl" :src="imgUrl" class="avatar"/>
        <el-icon v-else class="avatar-uploader-icon">
          <Plus/>
        </el-icon>
      </el-upload>

      <div style="margin-top: 10px">
        <el-progress :text-inside="true" :stroke-width="20" v-if="progress>0&&progress<100" :percentage="progress" style="margin: auto;width:178px " />
      </div>

    </div>

  </div>
</template>

<script>
import {
  Plus
} from '@element-plus/icons-vue'
import axios from "axios";

export default {
  name: "FileUpload",
  components: {
    Plus
  },
  data() {
    return {
      imgUrl: null,
      loading:false,
      progress:0,
    }
  },
  methods: {
    toUpload(file) {

      //调用后端接口获取minio带签名的上传地址
      axios.get("http://localhost:8080/file/upload/url").then(res => {
        let url = res.data
        this.loading=true
        
        //将文件上传到后端返回的minio服务器
        axios.put(url, file.file, {
          headers: {"Content-Type": file.file.type}, onUploadProgress: this.onUploadProgress}).then(r => {
          this.imgUrl = url.split("?")[0]
          this.loading=false
          console.log(r);
        })
        
      })
      return true
    },
    onUploadProgress(progressEvent){
      this.progress=((progressEvent.loaded * 100) / progressEvent.total).toFixed(2)
    }
  }

}
</script>

<style scoped>
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

  <style>
  .avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
  }

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>