springCloud 微服務通過minio實現檔案上傳和檔案下載介面

changlinlo發表於2022-05-11

 直接上程式碼吧,好多文章的下載都寫的不明不白的,讓人理解錯,氣死了!!

檔案上傳功能

檔案上傳很簡單,首先你得部署好minio,然後寫好配置資訊,我的是動態讀取nacos上配置的yml

 @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient client;
  
    @Autowired
    private FileInfoMapper fileInfoMapper;

/**
 * 本地檔案上傳介面
 * @param file 上傳的檔案
 * @return 訪問地址
 * @throws Exception
 */
@Override
public String uploadFile(MultipartFile file) throws Exception
{
    String fileName = FileUploadUtils.extractFilename(file);
    PutObjectArgs args = PutObjectArgs.builder()
            .bucket(minioConfig.getBucketName())
            .object(fileName)
            .stream(file.getInputStream(), file.getSize(), -1)
            .contentType(file.getContentType())
            .build();
    client.putObject(args);
    return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
}
     /**
   * 這個屬於業務了,可以參考 
     * 檔案儲存路徑:
     * 業務功能名資料夾+檔案UUID+檔案型別字尾
     * @param file 上傳的檔案
     * @param fileInfo 檔案資訊表:儲存了上傳標識等資訊(用於區分各個微服務下的各個業務,後面可通過這個標識區分這檔案是哪個業務的)
     * @return 
     * @throws Exception
     */
    @Override
    public int uploadFile(MultipartFile file, FileInfo fileInfo) throws Exception
    {
        //檔案UUID
        String uuid= IdUtils.fastSimpleUUID();
        //檔案目錄名稱
        String fileName = FileUploadUtils.extractFilenameByUuid(file, uuid);
        // 檔案路徑
        String url = fileInfo.getSid()+ "/" + fileName;

        PutObjectArgs args = PutObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileInfo.getSid()+ "/" + fileName)
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(file.getContentType())
                .build();
        client.putObject(args);

        //上傳到minio後,將檔案資訊儲存
        fileInfo.setUid(uuid);
        fileInfo.setFileName(file.getOriginalFilename());
        fileInfo.setFileSize(file.getSize());
        fileInfo.setFileType(FileUploadUtils.getExtension(file));
        fileInfo.setFilePath(url);
        fileInfo.setCreateBy(SecurityUtils.getUsername());
        fileInfo.setCreateTime(DateUtils.getNowDate());
        return fileInfoMapper.insertFileInfo(fileInfo);
    } 

檔案下載功能

這裡遇到個理解錯誤的訊息,minio提供的getObject方法和downloadObject方法:

1. getObject

GetObject介面用於獲取某個檔案(Object)。

此操作需要對此Object具有讀許可權。

獲取物件的資料。

InputStream使用後返回必須關閉以釋放網路資源。

2. downloadObject

將物件的資料下載到檔案

我以為downloadObject就是下載的意思(畢竟英文名也是下載的意思),結果他就是不是下載,而是下載到檔案。

下載主要引數是檔案儲存的目錄地址,如:system/task/2022/05/11/daebcc866c7f4c7dad34c55b8abff687.png,而不是這樣子的:http://192.168.8.116:9000/test/2022/05/11/logo_20220511103344A001.png

因為:http://192.168.1.1:9000/test/   minio會直接在這下面開始查,test為桶名稱bucketName

業務層:

   @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient client;
    
    /**
     * 下載檔案
     * @param fileName 下載目錄地址 如:system/task/2022/05/11/daebcc866c7f4c7dad34c55b8abff687.png
     * @param outputStream http請求中的outputStream
     */
    @Override
    public void  download(String fileName, ServletOutputStream outputStream)
    {
        try (InputStream inputStream = client.getObject(GetObjectArgs
                .builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .build()))
        {
            IOUtils.copy(inputStream, outputStream);
        }
        catch (Exception e)
        {
            log.error("檔案下載異常");
            e.printStackTrace();
        }
    }

控制層

     /**
     * 下載檔案
     * @param uid 檔案uid
     * @param response
     * @throws Exception
     */
    @GetMapping("/download/{uid}")
    public void download(@PathVariable("uid") String uid,HttpServletResponse response) throws Exception
    {
        //根據檔案UUID,查詢檔案表,得到檔案路徑目錄
        String fileName = fileInfoService.selectFilePathById(uid);
        System.out.println(fileName);
        //呼叫業務層下載方法
        sysFileService.download(fileName,response.getOutputStream());
    } 

相關文章