SpringBoot整合minio对象存储
一、导入依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
二、编写配置类
1、MinioAPI.java
import io.minio.*;
import io.minio.http.Method;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.InputStream;
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioAPI {
private String ENDPOINT;
private String ACCESS_KEY;
private String SECRET_KEY;
private static final String BUCKET_PARAM = "${bucket}";
private static final String READ_ONLY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
private static final String WRITE_ONLY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
private static final String READ_WRITE = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
public String getObjectPrefixUrl(String bucket) {
return String.format("%s/%s/", ENDPOINT, bucket);
}
public void makeBucket(String bucket) throws Exception {
MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
boolean isExist = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
if (!isExist) {
client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
}
}
public void setBucketPolicy(String bucket, String policy) throws Exception {
MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
switch (policy) {
case "read-only":
client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(READ_ONLY.replace(BUCKET_PARAM, bucket)).build());
break;
case "write-only":
client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(WRITE_ONLY.replace(BUCKET_PARAM, bucket)).build());
break;
case "read-write":
client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucket).config(READ_WRITE.replace(BUCKET_PARAM, bucket)).build());
break;
case "none":
default:
break;
}
}
public String uploadFile(String bucket, String objectKey, String filePath) throws Exception {
MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
client.uploadObject(UploadObjectArgs.builder().bucket(bucket).object(objectKey).filename(filePath).contentType("image/png").build());
return getObjectPrefixUrl(bucket) + objectKey;
}
public String uploadInputStream(String bucket, String objectKey, InputStream inputStream, String contentType) throws Exception {
MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
client.putObject(PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(inputStream, inputStream.available(), -1).contentType(contentType).build());
return getObjectPrefixUrl(bucket) + objectKey;
}
public InputStream download(String bucket, String objectKey) throws Exception {
MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
return client.getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build());
}
public String copyFile(String sourceBucket, String sourceObjectKey, String bucket, String objectKey) throws Exception {
MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
CopySource source = CopySource.builder().bucket(sourceBucket).object(sourceObjectKey).build();
client.copyObject(CopyObjectArgs.builder().bucket(bucket).object(objectKey).source(source).build());
return getObjectPrefixUrl(bucket) + objectKey;
}
public void deleteFile(String bucket, String objectKey) throws Exception {
MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectKey).build());
}
public String getSignedUrl(String bucket, String objectKey, int expires) throws Exception {
MinioClient client = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY, SECRET_KEY).build();
return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucket).object(objectKey).expiry(expires).build());
}
}
2、application.yml
minio:
ENDPOINT: http://192.168.0.198:10004
ACCESS_KEY: minio
SECRET_KEY: dyminio123
3、MinioConstants.java
public class MinioConstants {
public static final String IMAGE_JPG = "image/jpeg";
public static final String IMAGE_PNG = "image/png";
public static final String IMAGE_GIF = "image/gif";
public static final String APPLICATION_PDF = "application/pdf";
public static final String APPLICATION_MP4 = "video/mp4";
public static final String APPLICATION_WORD = "application/msword";
public static final String APPLICATION_STREAM = "application/octet-stream";
public static final Integer EXPIRES = 604800;
public static final String BUCKET_IMG = "img";
public static final String BUCKET_FILE = "file";
public static final String BUCKET_VIDEO = "video";
}
三、代码示例(多文件)
1、上传文件
if (!ObjectUtils.isEmpty(knFiles) && knFiles != null && knFiles.length > 0 && knFiles[0].getSize() > 0L) {
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateNowStr = sdf.format(d);
String datestr = dateNowStr + "/" + knowledgeId + "/" + dateNowStr + "-";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < knFiles.length; ++i) {
String img = datestr + knFiles[i].getOriginalFilename();
try {
InputStream is = knFiles[i].getInputStream();
this.minioAPI.uploadInputStream(MinioConstants.BUCKET_KNOWLEDGE_FILE, img, is, MinioConstants.APPLICATION_WORD);
} catch (Exception e) {
System.out.println("============上传文件失败=========");
e.printStackTrace();
}
if (sb.length() > 0) {
sb.append(",");
}
sb.append(img);
}
String s = sb.toString();
if (!StringUtils.isEmpty(knId) && knId!=" " && !knId.equals("null")) {
KnowledgeData byId = knowledgeDataService.getById(knId);
if (byId != null && !StringUtils.isEmpty(byId.getKnFile())) {
String knFiless = byId.getKnFile() + "," + s;
knowledgeData.setKnFile(knFiless);
} else {
knowledgeData.setKnFile(s);
}
}else {
knowledgeData.setKnFile(s);
}
}
2、查看文件
String imgName = knowledgeData.getKnFile();
if (imgName != null) {
String[] imgs = imgName.split(",");
Map<String,String> map = new HashMap<>();
for (int i = 0; i < imgs.length; ++i) {
try {
String signedFileUrl = this.minioAPI.getSignedUrl(MinioConstants.BUCKET_KNOWLEDGE_FILE, imgs[i], MinioConstants.EXPIRES);
String fileName = imgs[i].substring(imgs[i].lastIndexOf("-")+1);
map.put(fileName,signedFileUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
backListVO.setKnFiles(map);
}
3、删除文件
@PostMapping("/file/delete")
@ApiOperation(value = "文件删除接口")
@Transactional
public R upload(@ApiParam(value = "文件名称") @RequestParam String fileName,
@ApiParam(value = "主键knId") @RequestParam String knId) {
KnowledgeData knowledgeData = new KnowledgeData();
knowledgeData.setKnId(Integer.valueOf(knId));
KnowledgeData byId = knowledgeDataService.getById(knId);
if (byId!=null && !StringUtils.isEmpty(byId.getKnFile())){
String imgName = byId.getKnFile();
if (imgName != null) {
String[] imgs = imgName.split(",");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < imgs.length; ++i) {
String fileName1 = imgs[i].substring(imgs[i].lastIndexOf("-")+1);
if (fileName.equals(fileName1)){
try {
minioAPI.deleteFile(MinioConstants.BUCKET_KNOWLEDGE_FILE,imgs[i]);
} catch (Exception e) {
e.printStackTrace();
}
}else {
if (sb.length() > 0) {
sb.append(",");
}
sb.append(imgs[i]);
}
}
String s = sb.toString();
knowledgeData.setKnFile(s);
}
}
boolean b = knowledgeDataService.updateById(knowledgeData);
return R.status(b);
}
四、查看、删除、上传和保留之前文件上传 代码封装
MInioUtils.java
import com.knowledge.base.enums.MinioConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class MinioUtils {
@Autowired
private MinioAPI minioAPI;
private Map<String,String> getFileUrl(String filePath, String bucket){
if (filePath != null) {
String[] imgs = filePath.split(",");
Map<String,String> map = new HashMap<>();
for (int i = 0; i < imgs.length; ++i) {
try {
String signedFileUrl = this.minioAPI.getSignedUrl(bucket, imgs[i], MinioConstants.EXPIRES);
String fileName = imgs[i].substring(imgs[i].lastIndexOf("-")+1);
map.put(fileName,signedFileUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
return map;
}
return null;
}
private String deleteFile(String filePath, String fileName, String bucket){
if (filePath != null) {
String[] imgs = filePath.split(",");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < imgs.length; ++i) {
String fileName1 = imgs[i].substring(imgs[i].lastIndexOf("-")+1);
if (fileName.equals(fileName1)){
try {
minioAPI.deleteFile(bucket,imgs[i]);
} catch (Exception e) {
e.printStackTrace();
}
}else {
if (sb.length() > 0) {
sb.append(",");
}
sb.append(imgs[i]);
}
}
String s = sb.toString();
return s;
}
return null;
}
private String upload(MultipartFile[] files, String bucket, String contentType){
if (!ObjectUtils.isEmpty(files) && files != null && files.length > 0 && files[0].getSize() > 0L) {
Date d = new Date();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
String dateNowStr1 = sdf1.format(d);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateNowStr = sdf.format(d);
String datestr = dateNowStr1 + "/" + dateNowStr + "-";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < files.length; ++i) {
String img = datestr + files[i].getOriginalFilename();
try {
InputStream is = files[i].getInputStream();
this.minioAPI.uploadInputStream(bucket, img, is, contentType);
} catch (Exception e) {
System.out.println("============上传文件失败=========");
e.printStackTrace();
}
if (sb.length() > 0) {
sb.append(",");
}
sb.append(img);
}
String s = sb.toString();
return s;
}
return null;
}
private String uploadEdit(MultipartFile[] files, String bucket, String contentType, String filePath){
if (!ObjectUtils.isEmpty(files) && files != null && files.length > 0 && files[0].getSize() > 0L) {
Date d = new Date();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
String dateNowStr1 = sdf1.format(d);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateNowStr = sdf.format(d);
String datestr = dateNowStr1 + "/" + dateNowStr + "-";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < files.length; ++i) {
String img = datestr + files[i].getOriginalFilename();
try {
InputStream is = files[i].getInputStream();
this.minioAPI.uploadInputStream(bucket, img, is, contentType);
} catch (Exception e) {
System.out.println("============上传文件失败=========");
e.printStackTrace();
}
if (sb.length() > 0) {
sb.append(",");
}
sb.append(img);
}
String s = sb.toString();
if (!StringUtils.isEmpty(s)) {
String filesStr = filePath + "," + s;
return filesStr;
} else {
return s;
}
}
return null;
}
}
|