minio安装部署可以看这篇教程:https://blog.csdn.net/qq_43108153/article/details/134016896
创建桶
将私有设置成公开
导入依赖
<!-- minio -->
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.0.3</version>
</dependency>
yml中配置minio地址、账号密码、桶名称
minio:
# endpoint: http://192.168.1.100:9000 #线上地址endpoint: http://127.0.0.1:9000 #本地地址accessKey: minioadminsecretKey: minioadminbucketName: mybucket
我们需要这三个类来处理
MinioClientConfig
package com.ckm.ball.config;import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;/*** @author ckm* @version 1.0* @className MinIoClientConfig* @description* @create 2022/9/28 15:27*/
@Component
@Data
public class MinioClientConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.secretKey}")private String secretKey;@Value("${minio.accessKey}")private String accessKey;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}
}
MinioObjectItem
package com.ckm.ball.config;import lombok.Data;/*** @author ckm* @version 1.0* @className ObjectItem* @description* @create 2022/9/28 15:30*/
@Data
public class MinioObjectItem {private String objectName;private Long size;
}
MinioUtils
package com.ckm.ball.config;import com.alipay.service.schema.util.StringUtil;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;/*** @author ckm* @version 1.0* @className MinioUtils* @description* @create 2022/9/28 15:30*/
@Component
public class MinioUtils {@Autowiredprivate MinioClient minioClient;@Value("${minio.bucketName}")private String bucketName;/*** description: 判断bucket是否存在,不存在则创建** @return: void*/public boolean existBucket(String name) {boolean exists;try {exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());exists = true;}} catch (Exception e) {e.printStackTrace();exists = false;}return exists;}/*** 创建存储bucket** @param bucketName 存储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** @param bucketName 存储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;}/*** description: 上传文件** @param file* @return: java.lang.String*/public String upload(MultipartFile file, String bucketNameStr) {String imageId = UUID.randomUUID().toString();String fileName = file.getOriginalFilename();String[] split = fileName.split("\\.");if (split.length > 1) {fileName = split[0] + "-" + imageId + "." + split[1];} else {fileName = fileName + System.currentTimeMillis();}InputStream in = null;try {if (StringUtil.isEmpty(bucketNameStr)) {bucketNameStr = bucketName;}in = file.getInputStream();minioClient.putObject(PutObjectArgs.builder().bucket(bucketNameStr).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();}}}
// return bucketNameStr + "/" + fileName;return fileName;}/*** description: 下载文件** @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(bucketName).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;}/*** 查看文件对象** @param bucketName 存储bucket名称* @return 存储bucket内文件对象信息*/public List<MinioObjectItem> listObjects(String bucketName) {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());List<MinioObjectItem> minioObjectItems = new ArrayList<>();try {for (Result<Item> result : results) {Item item = result.get();MinioObjectItem minioObjectItem = new MinioObjectItem();minioObjectItem.setObjectName(item.objectName());minioObjectItem.setSize(item.size());minioObjectItems.add(minioObjectItem);}} catch (Exception e) {e.printStackTrace();return null;}return minioObjectItems;}/*** 批量删除文件对象** @param bucketName 存储bucket名称* @param objects 对象名称集合*/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;}/*** 根据文件名和桶获取文件路径** @param bucketName 存储bucket名称*/public String getFileUrl(String bucketName, String objectFile) {try {if(StringUtil.isEmpty(bucketName)){bucketName = this.bucketName;}return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(objectFile).build());} catch (Exception e) {e.printStackTrace();}return null;}}
业务中测试上传图片
Base64ToMultipartFile转换工具类
package com.ckm.ball.utils;import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartFile;import java.util.Base64;@Configuration
public class Base64ToMultipartFile {public MultipartFile base64ToMultipartFile (String s) {MultipartFile image = null;StringBuilder base64 = new StringBuilder("");if (s != null && !"".equals(s)) {base64.append(s);String[] baseStrs = base64.toString().split(",");byte[] b = new byte[0];b = Base64.getDecoder().decode(baseStrs[1]);for (int j = 0; j < b.length; ++j) {if (b[j] < 0) {b[j] += 256;}}image = new BASE64DecodedMultipartFile(b, baseStrs[0]);}return image;}
}
上传成功