前後端分離項目,如何優雅實現文件存儲!

  • 2020 年 2 月 10 日
  • 筆記

在上一節中我們講到了使用MinIO來自建對象存儲服務,這次我們來講下MinIO如何結合SpringBoot和Vue來實現文件存儲。

學前準備

學習本文需要一些MinIO的基礎知識,還不了解的小夥伴可以參考下:Github標星19K+Star,10分鐘自建對象存儲服務!

結合SpringBoot使用

接下來我們將結合SpringBoot來實現一個完整的圖片上傳與刪除操作。

  • 上傳流程示意圖:
  • 在pom.xml中添加MinIO的相關依賴:
<!--MinIO JAVA SDK-->  <dependency>      <groupId>io.minio</groupId>      <artifactId>minio</artifactId>      <version>3.0.10</version>  </dependency>  
  • 在SpringBoot中開啟文件上傳功能,需要在application.yml添加如下配置:
spring:    servlet:      multipart:        enabled: true #開啟文件上傳        max-file-size: 10MB #限制文件上傳大小為10M  
  • 添加一個MinioController控制器用於實現文件的上傳和刪除操作:
/**   * Created by macro on 2019/12/25.   */  @Api(tags = "MinioController", description = "MinIO對象存儲管理")  @Controller  @RequestMapping("/minio")  public class MinioController {        private static final Logger LOGGER = LoggerFactory.getLogger(MinioController.class);      @Value("${minio.endpoint}")      private String ENDPOINT;      @Value("${minio.bucketName}")      private String BUCKET_NAME;      @Value("${minio.accessKey}")      private String ACCESS_KEY;      @Value("${minio.secretKey}")      private String SECRET_KEY;        @ApiOperation("文件上傳")      @RequestMapping(value = "/upload", method = RequestMethod.POST)      @ResponseBody      public CommonResult upload(@RequestParam("file") MultipartFile file) {          try {              //創建一個MinIO的Java客戶端              MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);              boolean isExist = minioClient.bucketExists(BUCKET_NAME);              if (isExist) {                  LOGGER.info("存儲桶已經存在!");              } else {                  //創建存儲桶並設置只讀許可權                  minioClient.makeBucket(BUCKET_NAME);                  minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY);              }              String filename = file.getOriginalFilename();              SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");              // 設置存儲對象名稱              String objectName = sdf.format(new Date()) + "/" + filename;              // 使用putObject上傳一個文件到存儲桶中              minioClient.putObject(BUCKET_NAME, objectName, file.getInputStream(), file.getContentType());              LOGGER.info("文件上傳成功!");              MinioUploadDto minioUploadDto = new MinioUploadDto();              minioUploadDto.setName(filename);              minioUploadDto.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName);              return CommonResult.success(minioUploadDto);          } catch (Exception e) {              LOGGER.info("上傳發生錯誤: {}!", e.getMessage());          }          return CommonResult.failed();      }        @ApiOperation("文件刪除")      @RequestMapping(value = "/delete", method = RequestMethod.POST)      @ResponseBody      public CommonResult delete(@RequestParam("objectName") String objectName) {          try {              MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);              minioClient.removeObject(BUCKET_NAME, objectName);              return CommonResult.success(null);          } catch (Exception e) {              e.printStackTrace();          }          return CommonResult.failed();      }  }  
  • 在application.yml中對MinIO客戶端進行配置:
# MinIO對象存儲相關配置  minio:    endpoint: http://192.168.6.132:9090 #MinIO服務所在地址    bucketName: mall #存儲桶名稱    accessKey: minioadmin #訪問的key    secretKey: minioadmin #訪問的秘鑰  
  • 啟動我的SpringBoot應用,使用Postman來訪問上傳介面進行文件上傳,上傳介面地址:http://localhost:8080/minio/upload
  • 上傳完成後,我們打開MinIO的管理介面可以看到上傳後的圖片,也可以通過返回的url來訪問圖片:
  • 我們可以調用刪除介面來刪除該圖片,需要注意的是objectName值是存儲桶中的圖片相對路徑,刪除文件介面地址:http://localhost:8080/minio/delete

結合Vue使用

經過上面操作,我們的SpringBoot應用已經可以完成文件上傳與刪除操作了,接下來我們結合Vue來實現前端上傳圖片到MinIO中,以mall-admin-web中的程式碼為例。

  • 我們的SpringBoot應用需要支援跨域請求,否則Vue前端無法進行介面調用,我們先添加一個全局的跨域請求配置:
/**   * 全局跨域配置   * Created by macro on 2019/7/27.   */  @Configuration  public class GlobalCorsConfig {        /**       * 允許跨域調用的過濾器       */      @Bean      public CorsFilter corsFilter() {          CorsConfiguration config = new CorsConfiguration();          //允許所有域名進行跨域調用          config.addAllowedOrigin("*");          //允許跨越發送cookie          config.setAllowCredentials(true);          //放行全部原始頭資訊          config.addAllowedHeader("*");          //允許所有請求方法跨域調用          config.addAllowedMethod("*");          UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();          source.registerCorsConfiguration("/**", config);          return new CorsFilter(source);      }  }  
  • mall-admin-web的文件上傳操作主要是在singleUpload.vuemultiUpload.vue中,下面我們以singleUpload.vue的修改為例。
  • 我們需要把原來的OSS上傳和現在的MinIO上傳做個兼容操作,先在Vue實例的數據對象中添加三個屬性:
  • 然後根據useOss屬性設置el-upload上傳組件的提交地址和提交參數:
  • el-upload上傳文件之前的鉤子函數中添加如下程式碼,對於使用MinIO上傳的操作不進行獲取OSS上傳策略的操作;
  • 最後在el-upload文件上傳成功的鉤子函數中添加如下程式碼,對於使用MinIO上傳的操作直接從返回結果中獲取文件url;
  • 運行mall-admin-web項目,使用商品分類下的添加功能來測試下文件上傳,發現已經可以成功上傳,圖片也已經可以正常回顯:

後端項目地址

https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-oss

前端項目地址

https://github.com/macrozheng/mall-admin-web