MinIO
安装MinIo
docker安装
# 先创建minio 文件存放的位置 mkdir -p /opt/docker/minio/data # 启动并指定端口 docker run \ -p 9000:9000 \ -p 5001:5001 \ --name minio \ -v /opt/docker/minio/data:/data \ -e "MINIO_ROOT_USER=minioadmin" \ -e "MINIO_ROOT_PASSWORD=minioadmin" \ -d minio/minio server /data --console-address ":5001" # 设置为和 docker 绑定启动,docker 启动则 minio 就启动 docker update --restart=always
官方下载地址
官方下载地址提供多版本
https://www.minio.org.cn/download.shtml#/windows
导入依赖
<!-- https://mvnrepository.com/artifact/io.minio/minio --> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.4.0</version> </dependency>
application.yml 配置信息
minio: endpoint: http://192.168.218.131/:9000 #Minio服务所在地址 bucketName: tulaoda #存储桶名称 accessKey: minioadmin #访问的key secretKey: minioadmin #访问的秘钥
MinioConfig.class配置类
@Data @Configuration @ConfigurationProperties(prefix = "minio") public class MinioConfig { 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(); } }
minio工具类
@Component @Slf4j public class MinioUtil { @Autowired private MinioConfig prop; @Resource private MinioClient minioClient; @Autowired private CodeService codeService; /** * 查看存储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 { List<Bucket> buckets = minioClient.listBuckets(); return buckets; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 文件上传 * * @param file 文件 * @return Boolean */ public String upload(MultipartFile file) { String originalFilename = file.getOriginalFilename(); if (StringUtils.isBlank(originalFilename)){ throw new RuntimeException(); } String fileName = UuidUtils.generateUuid() + originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = CommUtils.getNowDateLongStr("yyyy-MM/dd") + "/" + fileName; try { PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(prop.getBucketName()).object(objectName) .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build(); //文件名称相同会覆盖 minioClient.putObject(objectArgs); } catch (Exception e) { e.printStackTrace(); return null; } return objectName; } /** * 预览图片 * @param fileName * @return */ public String preview(String fileName){ // 查看文件地址 GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(prop.getBucketName()).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(prop.getBucketName()) .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(prop.getBucketName()).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(prop.getBucketName()).object(fileName).build()); }catch (Exception e){ return false; } return true; } }
文件处理接口
@Api(tags = "文件相关接口") @Slf4j @RestController @RequestMapping(value = "/product/file") public class FileController { @Autowired private MinioUtil minioUtil; @Autowired private MinioConfig prop; @ApiOperation(value = "查看存储bucket是否存在") @GetMapping("/bucketExists") public R bucketExists(@RequestParam("bucketName") String bucketName) { return R.ok().put("bucketName",minioUtil.bucketExists(bucketName)); } @ApiOperation(value = "创建存储bucket") @GetMapping("/makeBucket") public R makeBucket(String bucketName) { return R.ok().put("bucketName",minioUtil.makeBucket(bucketName)); } @ApiOperation(value = "删除存储bucket") @GetMapping("/removeBucket") public R removeBucket(String bucketName) { return R.ok().put("bucketName",minioUtil.removeBucket(bucketName)); } @ApiOperation(value = "获取全部bucket") @GetMapping("/getAllBuckets") public R getAllBuckets() { List<Bucket> allBuckets = minioUtil.getAllBuckets(); return R.ok().put("allBuckets",allBuckets); } @ApiOperation(value = "文件上传返回url") @PostMapping("/upload") public R upload(@RequestParam("file") MultipartFile file) { String objectName = minioUtil.upload(file); if (null != objectName) { return R.ok().put("url",(prop.getEndpoint() + "/" + prop.getBucketName() + "/" + objectName)); } return R.error(); } @ApiOperation(value = "图片/视频预览") @GetMapping("/preview") public R preview(@RequestParam("fileName") String fileName) { return R.ok().put("filleName",minioUtil.preview(fileName)); } @ApiOperation(value = "文件下载") @GetMapping("/download") public R download(@RequestParam("fileName") String fileName, HttpServletResponse res) { minioUtil.download(fileName,res); return R.ok(); } @ApiOperation(value = "删除文件", notes = "根据url地址删除文件") @PostMapping("/delete") public R remove(String url) { String objName = url.substring(url.lastIndexOf(prop.getBucketName()+"/") + prop.getBucketName().length()+1); minioUtil.remove(objName); return R.ok().put("objName",objName); } }