springboot2.3 + minio8 檔案上傳
阿新 • • 發佈:2021-07-13
簡介
是在 Apache License v2.0 下發布的物件儲存伺服器,學習成本低,安裝運維簡單,主流語⾔的客戶端整合都有,號稱最強的物件儲存⽂件伺服器,且可以和容器化技術docker/k8s等結合,優點:功能強、可以根據業務做二次的定製,新一代分散式檔案儲存系統。
安裝
下載
wget http://dl.minio.org.cn/server/minio/release/linux-amd64/minio
賦權
chmod +x minio
啟動 (指定的url是檔案儲存地址)
./minio server /usr/local/wulei/minio_store 2>&1 &
訪問
http:192.168.200.100:9000
初體驗
介面非常友好,登陸成功後右下角可以 create bucket 也可以直接上傳檔案。create bucket 有點類似分組的概念,建議每個專案都各自一個分組。
還可以在分組下面繼續建立資料夾,右邊還提供了各種功能(視訊、文件 等資源不支援預覽)。
codeing
1. 加入配置和依賴
<!--檔案儲存--> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.0.3</version> </dependency> minio: # 地址 endpoint: http://192.168.200.100:9000 # 賬號 accessKey: minioadmin # 密碼 secretKey: minioadmin
2. 配置客戶端
import io.minio.MinioClient; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; @Data @Configuration @ConfigurationProperties(prefix = "minio") /** * 檔案伺服器配置類 */ public class MinioConfig { private String endpoint; private String accessKey; private String secretKey; @Bean public MinioClient minioClient(){ return MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); } }
3. 工具類
import io.minio.*; import io.minio.http.Method; import io.minio.messages.Bucket; import io.minio.messages.DeleteError; import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.springframework.stereotype.Component; import org.springframework.util.FastByteArrayOutputStream; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; /** * 檔案伺服器工具類 */ @Component public class MinioUtil { private String bucketName = "wulei-service"; @Resource private MinioClient minioClient; /** * 檢視儲存bucket是否存在 * @return boolean */ public Boolean bucketExists(String bucketName) { Boolean found; try { found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); } catch (Exception e) { //e.printStackTrace(); return false; } return found; } /** * 建立儲存bucket * @return Boolean */ public Boolean makeBucket(String bucketName) { try { minioClient.makeBucket(MakeBucketArgs.builder() .bucket(bucketName) .build()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 刪除儲存bucket * @return Boolean */ public Boolean removeBucket(String bucketName) { try { minioClient.removeBucket(RemoveBucketArgs.builder() .bucket(bucketName) .build()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 獲取全部bucket */ public List<Bucket> getAllBuckets() { try { return minioClient.listBuckets(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 檔案上傳 * @param file 檔案 * @return Boolean */ public Boolean upload(MultipartFile file) { // 修飾過的檔名 非原始檔名 String fileName = "2021-07/21/"; fileName = fileName+file.getOriginalFilename(); try { PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName) .stream(file.getInputStream(),file.getSize(),-1).contentType(file.getContentType()).build(); //檔名稱相同會覆蓋 minioClient.putObject(objectArgs); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 預覽圖片 * @param fileName * @return */ public String preview(String fileName){ // 檢視檔案地址 GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(bucketName).object(fileName).method(Method.GET).build(); try { String url = minioClient.getPresignedObjectUrl(build); return url; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 檔案下載 * @param fileName 檔名稱 * @param res response * @return Boolean */ public void download(String fileName, HttpServletResponse res) { GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName) .object(fileName).build(); try (GetObjectResponse response = minioClient.getObject(objectArgs)){ byte[] buf = new byte[1024]; int len; try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){ while ((len=response.read(buf))!=-1){ os.write(buf,0,len); } os.flush(); byte[] bytes = os.toByteArray(); res.setCharacterEncoding("utf-8"); //設定強制下載不開啟 //res.setContentType("application/force-download"); res.addHeader("Content-Disposition", "attachment;fileName=" + fileName); try (ServletOutputStream stream = res.getOutputStream()){ stream.write(bytes); stream.flush(); } } } catch (Exception e) { e.printStackTrace(); } } /** * 檢視檔案物件 * @return 儲存bucket內檔案物件資訊 */ public List<Item> listObjects() { Iterable<Result<Item>> results = minioClient.listObjects( ListObjectsArgs.builder().bucket(bucketName).build()); List<Item> items = new ArrayList<>(); try { for (Result<Item> result : results) { items.add(result.get()); } } catch (Exception e) { e.printStackTrace(); return null; } return items; } /** * 刪除 * @param fileName * @return * @throws Exception */ public boolean remove(String fileName){ try { minioClient.removeObject( RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build()); }catch (Exception e){ return false; } return true; } /** * 批量刪除檔案物件(沒測試) * @param objects 物件名稱集合 */ public Iterable<Result<DeleteError>> removeObjects(List<String> objects) { List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList()); Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build()); return results; } }
4. 測試
import com.wulei.common.util.JsonData; import com.wulei.user.util.MinioUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; @Api(tags = "檔案管理模組") @RestController @RequestMapping("/api/file/v1") @Slf4j public class MinioController { @Autowired private MinioUtil minioUtil; @ApiOperation(value = "檢視儲存bucket是否存在") @GetMapping("/bucketExists") public JsonData bucketExists(String bucketName) { return JsonData.buildSuccess(minioUtil.bucketExists(bucketName)); } @ApiOperation(value = "建立儲存bucket") @GetMapping("/makeBucket") public JsonData makeBucket(String bucketName) { minioUtil.makeBucket(bucketName); return JsonData.buildSuccess(); } @ApiOperation(value = "刪除儲存bucket") @GetMapping("/removeBucket") public JsonData removeBucket(String bucketName) { minioUtil.removeBucket(bucketName); return JsonData.buildSuccess(); } @ApiOperation(value = "獲取全部bucket") @GetMapping("/getAllBuckets") public JsonData getAllBuckets() { return JsonData.buildSuccess(minioUtil.getAllBuckets()); } @ApiOperation(value = "檔案上傳") @GetMapping("/upload") public JsonData upload(MultipartFile file) { minioUtil.upload(file); return JsonData.buildSuccess(); } @ApiOperation(value = "圖片預覽") @GetMapping("/preview") public JsonData preview(String fileName) { return JsonData.buildSuccess(minioUtil.preview(fileName)); } @ApiOperation(value = "檔案下載") @GetMapping("/download") public JsonData download(String fileName, HttpServletResponse res) { minioUtil.download(fileName,res); return JsonData.buildSuccess(); } @ApiOperation(value = "檔案刪除") @GetMapping("/remove") public JsonData remove(String fileName) { minioUtil.remove(fileName); return JsonData.buildSuccess(); } }
。