【SpringBoot】SpringBoot 集成 Minio、OSS 港控/mmm° 2023-09-28 22:31 1阅读 0赞 ### 1、Minio ### MinIO 是一款基于 Go 语言发开的高性能、分布式的对象存储系统。简单来说:就是可以存视频、图片 等。 通过 github 下载 Minio 服务端: * `https://github.com/minio/minio` 启动 Minio 服务端: * 在 minio.exe 目录下打开命令行,执行 `minio.exe server 保存路径`。如:`minio.exe server D:\profession\behindEnd\minio\data`。那么,上传的文件将会保存在:`D:\profession\behindEnd\minio\data` 下 启动后,通过 `http://127.0.0.1:9000` 访问,账号/密码:`minioadmin` ![在这里插入图片描述][0d7ee0708d014ed0a43e18ea205bcb9a.png] 可以创建一个 bucket。 SpringBoot 集成 Minio: 1、添加依赖: <!--minio--> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.0.3</version> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>1.3.50</version> </dependency> 2、添加配置: spring: servlet: multipart: enabled: true max-file-size: 10MB # 单个文件上传的最大上限 max-request-size: 10MB # 一次请求总大小上限 minio: endpoint: http://127.0.0.1:9000 accessKey: minioadmin secretKey: minioadmin bucketName: test 3、代码: 配置类: @Data @Component @ConfigurationProperties(prefix = "minio") public class MinioClientConfig { private String endPoint; private String accessKey; private String secretKey; private String bucketName; @Bean public MinioClient minioClient() { return MinioClient.builder().endpoint(endPoint).credentials(accessKey, secretKey).build(); } } 工具类: @Component public class MinioUtil { @Autowired private MinioClientConfig minioClientConfig; @Autowired private MinioClient minioClient; /** * @Description:判断bucket是否存在,不存在则创建 * @Author: zzc * @Date: 2022-08-31 15:33 * @param name: * @return: void **/ public void existBucket(String name) { try { boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build()); if (!exists) { minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build()); } } catch (Exception e) { e.printStackTrace(); } } /** * @Description:创建存储bucket * @Author: zzc * @Date: 2022-08-31 15:33 * @param name: * @return: java.lang.Boolean **/ public Boolean makeBucket(String name) { try { minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 删除存储bucket * @param name 存储bucket名称 * @return Boolean */ public Boolean removeBucket(String name) { try { minioClient.removeBucket(RemoveBucketArgs.builder() .bucket(name) .build()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } public String upload(MultipartFile file) { return upload(Arrays.asList(file)).get(0); } /** * @Description:批量上传文件 * @Author: zzc * @Date: 2022-08-31 15:43 * @param multipartFile: * @return: java.util.List<java.lang.String> **/ public List<String> upload(List<MultipartFile> multipartFile) { List<String> urls = new ArrayList<>(multipartFile.size()); for (MultipartFile file : multipartFile) { String fileName = file.getOriginalFilename(); String[] split = fileName.split("\\."); if (split.length > 1) { fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; } else { fileName = fileName + System.currentTimeMillis(); } InputStream in = null; try { in = file.getInputStream(); minioClient.putObject(PutObjectArgs.builder() .bucket(minioClientConfig.getBucketName()) .object(fileName) .stream(in, in.available(), -1) .contentType(file.getContentType()) .build() ); } catch (Exception e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } urls.add(minioClientConfig.getEndPoint() + "/" + minioClientConfig.getBucketName() + "/" + fileName); } return urls; } /** * @Description:下载文件 * @Author: zzc * @Date: 2022-08-31 15:46 * @param fileName: * @return: org.springframework.http.ResponseEntity<byte[]> **/ public ResponseEntity<byte[]> download(String fileName) { ResponseEntity<byte[]> responseEntity = null; InputStream in = null; ByteArrayOutputStream out = null; try { in = minioClient.getObject(GetObjectArgs.builder().bucket(minioClientConfig.getBucketName()).object(fileName).build()); out = new ByteArrayOutputStream(); IOUtils.copy(in, out); //封装返回值 byte[] bytes = out.toByteArray(); HttpHeaders headers = new HttpHeaders(); try { headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } headers.setContentLength(bytes.length); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setAccessControlExposeHeaders(Arrays.asList("*")); responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK); } catch (Exception e) { e.printStackTrace(); } finally { try { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { out.close(); } } catch (IOException e) { e.printStackTrace(); } } return responseEntity; } /** * @Description:查看bucketName里面的文件对象 * @Author: zzc * @Date: 2022-08-31 15:48 * @param bucketName: * @return: java.util.List<com.zzc.hardcore.vo.ObjectItemVo> 存储bucket内文件对象信息 **/ public List<ObjectItemVo> listObjects(String bucketName) { Iterable<Result<Item>> results = minioClient.listObjects( ListObjectsArgs.builder().bucket(bucketName).build()); List<ObjectItemVo> objectItems = new ArrayList<>(); try { for (Result<Item> result : results) { Item item = result.get(); ObjectItemVo objectItem = new ObjectItemVo(); objectItem.setObjectName(item.objectName()); objectItem.setSize(item.size()); objectItems.add(objectItem); } } catch (Exception e) { e.printStackTrace(); return null; } return objectItems; } /** * @Description:批量删除文件对象 * @Author: zzc * @Date: 2022-08-31 15:49 * @param bucketName: * @param objects: 对象名称集合 * @return: java.lang.Iterable<io.minio.Result<io.minio.messages.DeleteError>> **/ public Iterable<Result<DeleteError>> removeObjects(String bucketName, 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; } } @Data public class ObjectItemVo { private String objectName; private Long size; } 4、接口测试 @RestController @RequestMapping("/minio") public class MinioController { @Autowired private MinioUtil minioUtil; @PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile file) { return minioUtil.upload(file); } @PostMapping("/download") public ResponseEntity<byte[]> download() { return minioUtil.download("微信图片_20211002143943_1661932958068.jpg"); } } ### 2、OSS ### 引入依赖: <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.11.2</version> </dependency> 配置文件 oss: aliyun: # 在控制台 创建完 bucket 后,会自动生成的 endPoint: '' # 注册后会有 accessKeyId: '' # 注册后会有 accessKeySecret: '' # 自己在控制台创建 bucketName: '' 配置类: @Data @Component @ConfigurationProperties(prefix = "oss.aliyun") public class OssConfig implements InitializingBean { // 创建了bucket之后,oss会根据选择的区域自动分配endpoint private String endPoint; // accessKeyId private String accessKeyId; // accessKeySecret private String accessKeySecret; // bucket名称 private String bucketName; public static String END_POINT; public static String ACCESS_KEY_ID; public static String ACCESS_KEY_SECRET; public static String BUCKET_NAME; @Override public void afterPropertiesSet() { END_POINT = endPoint; ACCESS_KEY_ID = accessKeyId; ACCESS_KEY_SECRET = accessKeySecret; BUCKET_NAME = bucketName; } } 工具类: public class OssUtil { /** * 操作OSS对象 */ private static OSSClient ossClient = null; static { initOssClient(OssConfig.END_POINT, OssConfig.ACCESS_KEY_ID, OssConfig.ACCESS_KEY_SECRET); } /** * 初始化 * * @author zzc * @date 2023/2/1 14:40 * @param: endPoint * @param: accessKeyId * @param: accessKeySecret **/ private static void initOssClient(String endPoint, String accessKeyId, String accessKeySecret) { if (Objects.isNull(ossClient)) { ossClient = new OSSClient(endPoint, new DefaultCredentialProvider(accessKeyId, accessKeySecret), new ClientConfiguration()); } } /** * 上产文件 * * @author zzc * @date 2023/2/1 15:12 * @param: file * @param: fileDir * @return: java.lang.String **/ public static String upload(MultipartFile file, String fileDir) { // 1,判断bucketName是否存在 if (!ossClient.doesBucketExist(OssConfig.BUCKET_NAME)) { ossClient.createBucket(OssConfig.BUCKET_NAME); } // 2.获取文件名称 String fileName = getFileName(file); StringBuilder fileUrl = new StringBuilder(); if (StringUtils.isNotBlank(fileDir)) { fileDir = fileDir.endsWith("/") ? fileDir : fileDir.concat("/"); fileUrl.append(fileDir); } fileUrl.append(fileName); // 3.获取文件访问路径 String filePath = getFilePath(fileUrl.toString()); // 4.上传到OSS服务器 try { PutObjectResult result = ossClient.putObject(OssConfig.BUCKET_NAME, fileUrl.toString(), file.getInputStream()); } catch (IOException e) { e.printStackTrace(); } return filePath; } /** * 删除文件 * * @author zzc * @date 2023/2/1 15:14 * @param: fileName * @return: boolean **/ public static boolean delete(String fileName) { try { if (!ossClient.doesBucketExist(OssConfig.BUCKET_NAME)) { return false; } ossClient.deleteObject(OssConfig.BUCKET_NAME, fileName); return true; } catch (Exception e) { e.printStackTrace(); return false; } } private static String getFilePath(String fileUrl) { return "https://" + OssConfig.BUCKET_NAME + "." + OssConfig.END_POINT + "/" + fileUrl; } private static String getFileName(MultipartFile file) { String orgName = file.getOriginalFilename(); if (StringUtils.isBlank(orgName)) { orgName = file.getName(); } // 对文件类型检查 /*try { FileTypeFilter.fileTypeFilter(file); } catch (Exception e) { e.printStackTrace(); }*/ orgName = getFileName(orgName); return !orgName.contains(".") ? System.currentTimeMillis() + "" : System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")); } public static String getFileName(String fileName){ //判断是否带有盘符信息 // Check for Unix-style path int unixSep = fileName.lastIndexOf('/'); // Check for Windows-style path int winSep = fileName.lastIndexOf('\\'); // Cut off at latest possible point int pos = (winSep > unixSep ? winSep : unixSep); if (pos != -1) { // Any sort of path separator found... fileName = fileName.substring(pos + 1); } //替换上传文件名字的特殊字符 fileName = fileName.replace("=","").replace(",","").replace("&","") .replace("#", "").replace("“", "").replace("”", ""); //替换上传文件名字中的空格 fileName=fileName.replaceAll("\\s",""); return fileName; } } 测试: @RestController @RequestMapping("/oss") public class OssController { @PostMapping("/upload") public String uploadOssFile(@RequestParam("file") MultipartFile file, @RequestParam("filePath") String filePath) { return OssUtil.upload(file, filePath); } } [0d7ee0708d014ed0a43e18ea205bcb9a.png]: https://img-blog.csdnimg.cn/0d7ee0708d014ed0a43e18ea205bcb9a.png
还没有评论,来说两句吧...