依赖
<!-- 分布式存储 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.4.3</version>
</dependency>
配置:
控制层:
@Autowired
private MinioClient minioClient;
@Value("${minio.bucketName}")
private String bucketName;
@Autowired
private MinioUtilS minioUtilS;
/**
* 上传文件
* @param files
* @return
*/
@PostMapping("/uploadOtherFile")
public ResponseResult uploadOtherFile(@RequestParam(name = "file", required = false) MultipartFile[] files) {
if (files == null || files.length == 0) {
throw new BusinessException(ResponseCode.UPLOAD_MINIO_NULL);
}
List<UploadVo> upload = minioUtilS.uploadOtherFile(files);
return ResponseResult.success(ResponseCode.UPLOAD_SUCCESS, upload);
}
工具类:
package com.youming.shuiku.system.business.utils;
import cn.hutool.core.lang.UUID;
import com.youming.shuiku.commons.exception.BusinessException;
import com.youming.shuiku.system.business.minio.ObjectItem;
import com.youming.shuiku.system.vo.UploadPdfVo;
import com.youming.shuiku.system.vo.UploadVo;
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.ListObjectsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveBucketArgs;
import io.minio.RemoveObjectsArgs;
import io.minio.Result;
import io.minio.StatObjectArgs;
import io.minio.StatObjectResponse;
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.apache.dubbo.common.utils.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
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 javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @version : [v1.0]
* @className : MinioUtilS
* @description : [ 工具类]
* @createTime : [2022/7/15 20:09]
*/
@Component
public class MinioUtilS {
@Autowired
private MinioClient minioClient;
@Value("${minio.bucketName}")
private String bucketName;
@Value("${minio.endpoint}")
private String endPoint;
@Value("${minio.isPro}")
private Boolean isPro;
/**
* description: 判断bucket是否存在,不存在则创建
* @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();
}
}
/**
* 创建存储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;
}
public UploadPdfVo uploadPdfOneUrl(MultipartFile multipartFile){
// 将pdf装图片 并且自定义图片得格式大小
if(!"application/pdf".equals(multipartFile.getContentType())){
throw new BusinessException("只能解析pdf文件!");
}
try {
UploadPdfVo uploadPdfVo=new UploadPdfVo();
String pdfUrl = uploadIntranet(multipartFile.getOriginalFilename(), multipartFile.getBytes(), multipartFile.getContentType());
PDDocument doc = PDDocument.load(multipartFile.getInputStream());
PDFRenderer renderer = new PDFRenderer(doc);
// int pageCount = doc.getNumberOfPages();
for (int i = 0; i < 1; i++) {
BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
// BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", outputStream);
byte[] buffer = outputStream.toByteArray();
outputStream.flush();
outputStream.close();
String pdfOneUrl = uploadIntranet(UUID.randomUUID().toString() + ".jpg", buffer, "image/jpeg");
uploadPdfVo.setPdfUrl(pdfUrl);
uploadPdfVo.setPdfOneUel(pdfOneUrl);
return uploadPdfVo;
}
} catch (IOException e) {
e.printStackTrace();
}
throw new BusinessException("解析失败");
}
public String uploadIntranet(String fileName, byte[] bytes, String contentType) {
//创建一个MinIO的Java客户端
InputStream inputStream = new ByteArrayInputStream(bytes);
try {
String newFileName=fileName.substring(fileName.lastIndexOf(".")+1);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
// 设置存储对象名称
String objectName = sdf.format(new Date()) + "/" + UUID.randomUUID(false)+"/"+ UUID.randomUUID(true)+"."+newFileName;
try {
minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName)
.stream(inputStream, inputStream.available(), -1).contentType(contentType).build());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (inputStream != null) {
try {
inputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
// String preview = this.preview(fileName);
UploadVo uploadVo = new UploadVo();
if(isPro){
return "https://XXX.XX.XX.XX" + "/" + bucketName + "/" + objectName;
}else{
return endPoint + "/" + bucketName + "/" + objectName;
}
} catch (Exception e) {
}
return null;
}
/**
* description: 上传文件
* @param multipartFile
* @return: java.lang.String
*
*/
public List<UploadVo> upload(MultipartFile[] multipartFile) {
List<UploadVo> names = new ArrayList<>(multipartFile.length);
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();
// }
String newFileName=fileName.substring(fileName.lastIndexOf(".")+1);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
// 设置存储对象名称
String objectName = sdf.format(new Date()) + "/" + UUID.randomUUID(false)+"/"+ UUID.randomUUID(true)+"."+newFileName;
InputStream in = null;
try {
in = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName)
.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();
}
}
}
// String preview = this.preview(fileName);
UploadVo uploadVo = new UploadVo();
if(isPro){
uploadVo.setFileRoute("https://XXX.XX.XX.XX" + "/" + bucketName + "/" + objectName);
}else{
uploadVo.setFileRoute(endPoint + "/" + bucketName + "/" + objectName);
}
uploadVo.setFileName(objectName);
names.add(uploadVo);
}
return names;
}
/*
* @description: 上传其他文件
* @author: wangxihao
* @date:2023/6/6 13:36
* @param: multipartFile
* @return: java.util.List<com.youming.shuiku.system.vo.UploadVo>
**/
public List<UploadVo> uploadOtherFile(MultipartFile[] multipartFile) {
List<UploadVo> names = new ArrayList<>(multipartFile.length);
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();
// }
String newFileName=fileName.substring(fileName.lastIndexOf(".")+1);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
// 设置存储对象名称
String objectName = "otherFile/"+sdf.format(new Date()) + "/" + UUID.randomUUID(false)+"/"+ UUID.randomUUID(true)+"."+newFileName;
InputStream in = null;
try {
in = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName)
.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();
}
}
}
// String preview = this.preview(fileName);
UploadVo uploadVo = new UploadVo();
if(isPro){
uploadVo.setFileRoute("https://XXX.XX.XX.XX" + "/" + bucketName + "/" + objectName);
}else{
uploadVo.setFileRoute(endPoint + "/" + bucketName + "/" + objectName);
}
uploadVo.setFileName(objectName);
names.add(uploadVo);
}
return names;
}
// TODO: 2022/7/15 其他方案
/**
* 文件上传
* @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; }
*/
/**
* description: 下载文件
* @param fileName
* @return: org.springframework.http.ResponseEntity<byte [ ]>
*/
public ResponseEntity<byte[]> download(HttpServletResponse response, String fileName) {
ResponseEntity<byte[]> responseEntity = null;
InputStream in = null;
ByteArrayOutputStream out = null;
try {
StatObjectResponse statObjectResponse = minioClient
.statObject(StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
response.setContentType(statObjectResponse.contentType());
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
out = new ByteArrayOutputStream();
IOUtils.copy(in, response.getOutputStream());
// 封装返回值
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<ObjectItem> listObjects(String bucketName) {
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
List<ObjectItem> objectItems = new ArrayList<>();
try {
for (Result<Item> result : results) {
Item item = result.get();
ObjectItem objectItem = new ObjectItem();
objectItem.setObjectName(item.objectName());
objectItem.setSize(item.size());
objectItems.add(objectItem);
}
}
catch (Exception e) {
e.printStackTrace();
return null;
}
return objectItems;
}
/**
* 预览图片
* @param fileName
* @return
*/
public String preview(String fileName) {
// TODO: 2022/7/15 待验证
// 查看文件地址
GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName)
.method(Method.GET).build();
try {
String url = minioClient.getPresignedObjectUrl(build);
if (!StringUtils.isBlank(url)) {
String[] split = url.split("\\?");
return split[0];
}
return url;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 批量删除文件对象
* @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;
}
}
注:XXX.XX.XX.XX换成服务器地址