Springboot整合minio实现文件服务的教程详解

网友投稿 550 2022-07-26


首先pom文件引入相关依赖

io.minio

minio

3.0.10

springboot配置文件application.yml 里配置minio信息

#minio配置

minio:

endpoint: http://${minio_host:172.16.10.21}:9000/

accessKey: ${minio_user:minioadmin}

secretKey: ${minio_pwd:minioadmin}

bucket: ${minio_space:spacedata}

http-url: http://${minio_url:172.16.10.21}:9000/

imgSize: 10485760

fileSize: 1048576000

创建MinioItem字段项目类

import io.minio.messages.Item;

import io.minio.messages.Owner;

import io.swagger.annotations.ApiModelProperty;

import lombok.Data;

import java.util.Date;

@Data

public class MinioItem {

/**对象名称**/

@ApiModelProperty("对象名称")

private String objectName;

/**最后操作时间**/

@ApiModelProperty("最后操作时间")

private Date lastModified;

private String etag;

/**对象大小**/

@ApiModelProperty("对象大小")

private String size;

private String storageClass;

private Owner owner;

/**对象类型:directory(目录)或file(文件)**/

@ApiModelProperty("对象类型:directory(目录)或file(文件)")

private String type;

public MinioItem(String objectName, Date lastModified, String etag, String size, String storageClass, Owner owner, String type) {

this.objectName = objectName;

this.lastModified = lastModified;

this.etag = etag;

this.size = size;

this.storageClass = storageClass;

this.owner = owner;

this.type = type;

}

public MinioItem(Item item) {

this.objectName = item.objectName();

this.type = item.isDir() ? "directory" : "file";

this.etag = item.etag();

long sizeNum = item.objectSize();

this.size = sizeNum > 0 ? convertFileSize(sizeNum):"0";

this.storageClass = item.storageClass();

this.owner = item.owner();

try {

this.lastModified = item.lastModified();

}catch(NullPointerException e){}

}

public String convertFileSize(long size) {

long kb = 1024;

long mb = kb * 1024;

long gb = mb * 1024;

if (size >= gb) {

return String.format("%.1f GB", (float) size / gb);

} else if (size >= mb) {

float f = (float) size / mb;

return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);

} else if (size >= kb) {

float f = (float) size / kb;

return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);

} else{

return String.format("%d B", size);

}

}

}

创建MinioTemplate模板类

import com.gis.spacedata.domain.dto.minio.MinioItem;

import com.google.common.collect.Lists;

import io.minio.MinioClient;

import io.minio.ObjectStat;

import io.minio.Result;

import io.minio.errors.*;

import io.minio.messages.Bucket;

import io.minio.messages.Item;

import lombok.RequiredArgsConstructor;

import lombok.SneakyThrows;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.stereotype.Component;

import org.springframework.util.FileCopyUtils;

import org.xmlpull.v1.XmlPullParserException;

import javax.servlet.http.HttpServletRequest;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.net.URL;

import java.net.URLEncoder;

import java.nio.charset.StandardCharsets;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.util.ArrayList;

import java.util.List;

import java.util.Optional;

@Slf4j

@Component

@RequiredArgsConstructor

public class MinioTemplate implements InitializingBean {

/**

* minio的路径

**/

@Value("${minio.endpoint}")

private String endpoint;

/**

* minio的accessKey

**/

@Value("${minio.accessKey}")

private String accessKey;

/**

* minio的secretKey

**/

@Value("${minio.secretKey}")

private String secretKey;

/**

* 下载地址

**/

@Value("${minio.http-url}")

private String httpUrl;

@Value("${minio.bucket}")

private String bucket;

private static MinioClient minioClient;

@Override

public void afterPropertiesSet() throws Exception {

minioClient = new MinioClient(endpoint, accessKey, secretKey);

}

@SneakyThrows

public boolean bucketExists(String bucketName) {

return minioClient.bucketExists(bucketName);

}

/**

* 创建bucket

*

* @param bucketName bucket名称

*/

@SneakyThrows

public void createBucket(String bucketName) {

if (!bucketExists(bucketName)) {

minioClient.makeBucket(bucketName);

}

}

/**

* 获取全部bucket

*

* https://docs.minio.io/cn/java-client-api-reference.html#listBuckets

*/

@SneakyThrows

public List getAllBuckets() {

return minioClient.listBuckets();

}

/**

* 根据bucketName获取信息

*

* @param bucketName bucket名称

*/

@SneakyThrows

public Optional getBucket(String bucketName) {

return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();

}

/**

* 根据bucketName删除信息

*

* @param bucketName bucket名称

*/

@SneakyThrows

public void removeBucket(String bucketName) {

minioClient.removeBucket(bucketName);

}

/**

* 根据文件前缀查询文件

*

* @param bucketName bucket名称

* @param prefix 前缀

* @param recursive 是否递归查询

* @return MinioItem 列表

*/

@SneakyThrows

public List getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {

List objectList = new ArrayList<>();

Iterable> objectsIterator = minioClient.listObjects(bucketName, prefix, recursive);

for (Result result : objectsIterator) {

objectList.add(new MinioItem(result.get()));

}

return objectList;

}

/**

* 获取文件外链

*

* @param bucketName bucket名称

* @param objectName 文件名称

* @param expires 过期时间 <=7

* @return url

*/

@SneakyThrows

public String getObjectURL(String bucketName, String objectName, Integer expires) {

return minioClient.presignedGetObject(bucketName, objectName, expires);

}

/**

* 获取文件外链

*

* @param bucketName bucket名称

* @param objectName 文件名称

* @return url

*/

@SneakyThrows

public String getObjectURL(String bucketName, String objectName) {

return minioClient.presignedGetObject(bucketName, objectName);

}

/**

* 获取文件url地址

*

* @param bucketName bucket名称

* @param objectName 文件名称

* @return url

*/

@SneakyThrows

public String getObjectUrl(String bucketName, String objectName) {

return minioClient.getObjectUrl(bucketName, objectName);

}

/**

* 获取文件

*

* @param bucketName bucket名称

* @param objectName 文件名称

* @return 二进制流

*/

@SneakyThrows

public InputStream getObject(String bucketName, String objectName) {

return minioClient.getObject(bucketName, objectName);

}

/**

* 上传文件(流下载)

*

* @param bucketName bucket名称

* @param objectName 文件名称

* @param stream 文件流

* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject

*/

public void putObject(String bucketName, String objectName, InputStream stream) throws Exception {

String contentType = "application/octet-stream";

if ("json".equals(objectName.split("\\.")[1])) {

//json格式,C++编译生成文件,需要直接读取

contentType = "application/json";

}

minioClient.putObject(bucketName, objectName, stream, stream.available(), contentType);

}

/**

* 上传文件

*

* @param bucketName bucket名称

* @param objectName 文件名称

* @param stream 文件流

* @param size 大小

* @param contextType 类型

* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject

*/

public void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception {

minioClient.putObject(bucketName, objectName, stream, size, contextType);

}

/**

* 获取文件信息

*

* @param bucketName bucket名称

* @param objectName 文件名称

* @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject

*/

public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception {

return minioClient.statObject(bucketName, objectName);

}

/**

* 删除文件夹及文件

*

* @param bucketName bucket名称

* @param objectName 文件或文件夹名称

* @since tarzan LIU

*/

public void removeObject(String bucketName, String objectName) {

try {

if (StringUtils.isNotBlank(objectName)) {

if (objectName.endsWith(".") || objectName.endsWith("/")) {

Iterable> list = minioClient.listObjects(bucketName, objectName);

list.forEach(e -> {

try {

minioClient.removeObject(bucketName, e.get().objectName());

} catch (InvalidBucketNameException invalidBucketNameException) {

invalidBucketNameException.printStackTrace();

} catch (NoSuchAlgorithmException noSuchAlgorithmException) {

noSuchAlgorithmException.printStackTrace();

} catch (InsufficientDataException insufficientDataException) {

insufficientDataException.printStackTrace();

} catch (IOException ioException) {

ioException.printStackTrace();

} catch (InvalidKeyException invalidKeyException) {

invalidKeyException.printStackTrace();

} catch (NoResponseException noResponseException) {

noResponseException.printStackTrace();

} catch (XmlPullParserException xmlPullParserException) {

xmlPullParserException.printStackTrace();

} catch (ErrorResponseException errorResponseException) {

errorResponseException.printStackTrace();

} catch (InternalException internalException) {

internalException.printStackTrace();

}

});

}

}

} catch (XmlPullParserException e) {

e.printStackTrace();

}

}

/**

* 下载文件夹内容到指定目录

*

* @param bucketName bucket名称

* @param objectName 文件或文件夹名称

* @param dirPath 指定文件夹路径

* @since tarzan LIU

*/

public void downloadTargetDir(String bucketName, String objectName, String dirPath) {

try {

if (StringUtils.isNotBlank(objectName)) {

if (objectName.endsWith(".") || objectName.endsWith("/")) {

Iterable> list = minioClient.listObjects(bucketName, objectName);

list.forEach(e -> {

try {

String url = minioClient.getObjectUrl(bucketName, e.get().objectName());

getFile(url, dirPath);

} catch (InvalidBucketNameException invalidBucketNameException) {

invalidBucketNameException.printStackTrace();

} catch (NoSuchAlgorithmException noSuchAlgorithmException) {

noSuchAlgorithmException.printStackTrace();

} catch (InsufficientDataException insufficientDataException) {

insufficientDataException.printStackTrace();

} catch (IOException ioException) {

ioException.printStackTrace();

} catch (InvalidKeyException invalidKeyException) {

invalidKeyException.printStackTrace();

} catch (NoResponseException noResponseException) {

noResponseException.printStackTrace();

} catch (XmlPullParserException xmlPullParserException) {

xmlPullParserException.printStackTrace();

} catch (ErrorResponseException errorResponseException) {

errorResponseException.printStackTrace();

} catch (InternalException internalException) {

internalException.printStackTrace();

}

});

}

}

} catch (XmlPullParserException e) {

e.printStackTrace();

}

}

public static void main(String[] args) throws

NoSuchAlgorithmException, IOException, InvalidKeyException, XmlPullParserException {

try {

// 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象

MinioClient minioClient = new MinioClient("http://172.16.10.201:9000/", "minioadmin", "minioadmin");

// 检查存储桶是否已经存在

boolean isExist = minioClient.bucketExists("spacedata");

if (isExist) {

System.out.println("Bucket already exists.");

} else {

// 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。

minioClient.makeBucket("spacedata");

}

// 使用putObject上传一个文件到存储桶中。

// minioClient.putObject("spacedata", "测试.jpg", "C:\\Users\\sundasheng44\\Desktop\\1.png");

// minioClient.removeObject("spacedata", "20200916/8ca27855ba884d7da1496fb96907a759.dwg");

Iterable> list = minioClient.listObjects("spacedata", "CompileResult/");

List list1 = Lists.newArrayList();

list.forEach(e -> {

try {

list1.add("1");

String url = minioClient.getObjectUrl("spacedata", e.get().objectName());

System.out.println(url);

//getFile(url, "C:\\Users\\liuya\\Desktop\\" + e.get().objectName());

System.out.println(e.get().objectName());

// minioClient.removeObject("spacedata", e.get().objectName());

} catch (InvalidBucketNameException invalidBucketNameException) {

invalidBucketNameException.printStackTrace();

} catch (NoSuchAlgorithmException noSuchAlgorithmException) {

noSuchAlgorithmException.printStackTrace();

} catch (InsufficientDataException insufficientDataException) {

insufficientDataException.printStackTrace();

} catch (IOException ioException) {

ioException.printStackTrace();

} catch (InvalidKeyException invalidKeyException) {

invalidKeyException.printStackTrace();

} catch (NoResponseException noResponseException) {

noResponseException.printStackTrace();

} catch (XmlPullParserException xmlPullParserException) {

xmlPullParserException.printStackTrace();

} catch (ErrorResponseException errorResponseException) {

errorResponseException.printStackTrace();

} catch (InternalException internalException) {

internalException.printStackTrace();

}

});

System.out.println(list1.size());

} catch (MinioException e) {

System.out.println("Error occurred: " + e);

}

}

/**

* 文件流下载(原始文件名)

*

* @author sunboqiang

* @date 2020/10/22

*/

public ResponseEntity fileDownload(String url, String fileName, HttpServletRequest request) {

return this.downloadMethod(url, fileName, request);

}

private File getFile(String url, String fileName) {

InputStream in = null;

// 创建文件

String dirPath = fileName.substring(0, fileName.lastIndexOf("/"));

File dir = new File(dirPath);

if (!dir.exists()) {

dir.mkdirs();

}

File file = new File(fileName);

try {

URL url1 = new URL(url);

in = url1.openStream();

// 输入流转换为字节流

byte[] buffer = FileCopyUtils.copyToByteArray(in);

// 字节流写入文件

FileCopyUtils.copy(buffer, file);

// 关闭输入流

in.close();

} catch (IOException e) {

log.error("文件获取失败:" + e);

return null;

} finally {

try {

in.close();

} catch (IOException e) {

log.error("", e);

}

}

return file;

}

public ResponseEntity downloadMethod(String url, String fileName, HttpServletRequest request) {

HttpHeaders heads = new HttpHeaders();

heads.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream; charset=utf-8");

try {

if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {

// firefox浏览器

fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");

} else if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {

// IE浏览器

fileName = URLEncoder.encode(fileName, "UTF-8");

} else if (request.getHeader("User-Agent").toUpperCase().indexOf("EDGE") > 0) {

// WIN10浏览器

fileName = URLEncoder.encode(fileName, "UTF-8");

} else if (request.getHeader("User-Agent").toUpperCase().indexOf("CHROME") > 0) {

// 谷歌

fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");

} else {

//万能乱码问题解决

fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);

}

} catch (UnsupportedEncodingException e) {

// log.error("", e);

}

heads.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName);

try {

//InputStream in = new FileInputStream(file);

URL url1 = new URL(url);

InputStream in = url1.openStream();

// 输入流转换为字节流

byte[] buffer = FileCopyUtils.copyToByteArray(in);

ResponseEntity responseEntity = new ResponseEntity<>(buffer, heads, HttpStatus.OK);

//file.delete();

return responseEntity;

} catch (Exception e) {

log.error("", e);

}

return null;

}

创建 FilesMinioService 服务类

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.gis.spacedata.common.constant.response.ResponseCodeConst;

import com.gis.spacedata.common.domain.ResponseDTO;

import com.gis.spacedata.domain.dto.file.vo.UploadVO;

import com.gis.spacedata.domain.dto.minio.MinioItem;

import com.gis.spacedata.domain.entity.file.FileEntity;

import com.gis.spacedata.enums.file.FileServiceTypeEnum;

import com.gis.spacedata.handler.SmartBusinessException;

import com.gis.spacedata.mapper.file.FileDao;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.codec.digest.DigestUtils;

import org.apache.commons.lang3.StringUtils;

import org.springblade.core.tool.utils.FileUtil;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.http.ResponseEntity;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import org.springframework.stereotype.Service;

import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

import javax.servlet.http.HttpServletRequest;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;

import java.util.List;

import java.util.UUID;

@Service

@Slf4j

public class FilesMinioService extends ServiceImpl {

@Autowired

private MinioTemplate minioTemplate;

@Resource

private ThreadPoolTaskExecutor taskExecutor;

/**

* 图片大小限制

**/

@Value("#{${minio.imgSize}}")

private Long imgSize;

/**

* 文件大小限制

**/

@Value("#{${minio.fileSize}}")

private Long fileSize;

@Value("${minio.bucket}")

private String bucket;

/**

* 下载地址

**/

@Value("${minio.http-url}")

private String httpUrl;

/**

* 判断是否图片

*/

private boolean isImage(String fileName) {

//设置允许上传文件类型

String suffixList = "jpg,gif,png,ico,bmp,jpeg";

// 获取文件后缀

String suffix = fileName.substring(fileName.lastIndexOf(".")

+ 1);

return suffixList.contains(suffix.trim().toLowerCase());

}

/**

* 验证文件大小

*

* @param upfile

* @param fileName 文件名称

* @throws Exception

*/

private void fileCheck(MultipartFile upfile, String fileName) throws Exception {

Long size = upfile.getSize();

if (isImage(fileName)) {

if (size > imgSize) {

throw new Exception("上传对图片大于:" + (imgSize / 1024 / 1024) + "M限制");

}

} else {

if (size > fileSize) {

throw new Exception("上传对文件大于:" + (fileSize / 1024 / 1024) + "M限制");

}

}

}

/**

* 文件上传

*

* @author sunboqiang

* @date 2020/9/9

*/

public ResponseDTO fileUpload(MultipartFile upfile) throws IOException {

String originalFileName = upfile.getOriginalFilename();

try {

fileCheck(upfile, originalFileName);

} catch (Exception e) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR, e.getMessage());

}

if (StringUtils.isBlank(originalFileName)) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "文件名称不能为空");

}

UploadVO vo = new UploadVO();

String url;

//获取文件md5,查找数据库,如果有,则不需要上传了

String md5 = DigestUtils.md5Hex(upfile.getInputStream());

QueryWrapper query = new QueryWrapper<>();

query.lambda().eq(FileEntity::getMd5, md5);

query.lambda().eq(FileEntity::getStorageType, FileServiceTypeEnum.MINIO_OSS.getLocationType());

FileEntity fileEntity = baseMapper.selectOne(query);

if (null != fileEntity) {

//url = minioTemplate.getObjectURL(bucket,fileEntity.getFileName());

vo.setId(fileEntity.getId());

vo.setFileName(originalFileName);

vo.setUrl(httpUrl + fileEntity.getFileUrl());

vo.setNewFileName(fileEntity.getFileName());

vo.setFileSize(upfile.getSize());

vo.setFileLocationType(FileServiceTypeEnum.MINIO_OSS.getLocationType());

log.info("文件已上传,直接获取");

return ResponseDTO.succData(vo);

}

//拼接文件名

String fileName = generateFileName(originalFileName);

try {

// 检查存储桶是否已经存在

boolean isExist = minioTemplate.bucketExists(bucket);

if (isExist) {

log.info("Bucket already exists.");

} else {

// 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。

minioTemplate.createBucket(bucket);

}

// 使用putObject上传一个文件到存储桶中。

minioTemplate.putObject(bucket, fileName, upfile.getInputStream());

log.info("上传成功.");

//生成一个外部链接

//url = minioTemplate.getObjectURL(bucket,fileName);

//已经设置永久链接,直接获取

url = httpUrl + bucket + "/" + fileName;

fileEntity = new FileEntity();

fileEntity.setStorageType(FileServiceTypeEnum.MINIO_OSS.getLocationType());

fileEntity.setFileName(fileName);

fileEntity.setOriginalFileName(originalFileName);

fileEntity.setFileUrl(bucket + "/" + fileName);

fileEntity.setFileSize(upfile.getSize());

fileEntity.setMd5(md5);

baseMapper.insert(fileEntity);

} catch (Exception e) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR, "上传失败!");

}

vo.setFileName(originalFileName);

vo.setId(fileEntity.getId());

vo.setUrl(url);

vo.setNewFileName(fileName);

vo.setFileSize(upfile.getSize());

vo.setFileLocationType(FileServiceTypeEnum.MINIO_OSS.getLocationType());

return ResponseDTO.succData(vo);

}

/**

* 生成文件名字

* 当前年月日时分秒 +32位 uuid + 文件格式后缀

*

* @param originalFileName

* @return String

*/

private String generateFileName(String originalFileName) {

String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

String uuid = UUID.randomUUID().toString().replaceAll("-", "");

String fileType = originalFileName.substring(originalFileName.lastIndexOf("."));

return time + "/" + uuid + fileType;

}

/**

* 文件上传(不做重复校验)

*

* @author sunboqiang

* @date 2020/9/25

*/

public ResponseDTO fileUploadRep(MultipartFile upfile) throws IOException {

String originalFileName = upfile.getOriginalFilename();

try {

fileCheck(upfile, originalFileName);

} catch (Exception e) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR, e.getMessage());

}

if (StringUtils.isBlank(originalFileName)) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "文件名称不能为空");

}

UploadVO vo = new UploadVO();

String url;

//获取文件md5

FileEntity fileEntity = new FileEntity();

//拼接文件名

String fileName = generateFileName(originalFileName);

try {

// 检查存储桶是否已经存在

boolean isExist = minioTemplate.bucketExists(bucket);

if (isExist) {

log.info("Bucket already exists.");

} else {

// 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。

minioTemplate.createBucket(bucket);

}

// 使用putObject上传一个文件到存储桶中。

minioTemplate.putObject(bucket, fileName, upfile.getInputStream());

log.info("上传成功.");

//生成一个外部链接

//url = minioTemplate.getObjectURL(bucket,fileName);

//已经设置永久链接,直接获取

url = httpUrl + bucket + "/" + fileName;

fileEntity.setStorageType(FileServiceTypeEnum.MINIO_OSS.getLocationType());

fileEntity.setFileName(fileName);

fileEntity.setOriginalFileName(originalFileName);

fileEntity.setFileUrl(bucket + "/" + fileName);

fileEntity.setFileSize(upfile.getSize());

baseMapper.insert(fileEntity);

} catch (Exception e) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR, "上传失败!");

}

vo.setFileName(originalFileName);

vo.setId(fileEntity.getId());

vo.setUrl(url);

vo.setNewFileName(fileName);

vo.setFileSize(upfile.getSize());

vo.setFileLocationType(FileServiceTypeEnum.MINIO_OSS.getLocationType());

return ResponseDTO.succData(vo);

}

/**

* 文件流上传(不存数据库)

*

* @author sunboqiang

* @date 2020/9/25

*/

public ResponseDTO uploadStream(InputStream inputStream, String originalFileName) {

UploadVO vo = new UploadVO();

String url;

//文件名

String fileName = originalFileName;

try {

// 检查存储桶是否已经存在

boolean isExist = minioTemplate.bucketExists(bucket);

if (isExist) {

log.info("Bucket already exists.");

} else {

// 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。

minioTemplate.createBucket(bucket);

}

// 使用putObject上传一个文件到存储桶中。

minioTemplate.putObject(bucket, fileName, inputStream);

log.info("上传成功.");

//生成一个外部链接

//url = minioTemplate.getObjectURL(bucket,fileName);

//已经设置永久链接,直接获取

url = httpUrl + bucket + "/" + fileName;

} catch (Exception e) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR, "上传失败!");

}

vo.setFileName(originalFileName);

vo.setUrl(url);

vo.setNewFileName(fileName);

vo.setFileLocationType(FileServiceTypeEnum.MINIO_OSS.getLocationType());

return ResponseDTO.succData(vo);

}

private String generateFileNameTwo(String originalFileName) {

String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

return time + "/" + originalFileName;

}

/**

* 文件查询

*

* @author sunboqiang

* @date 2020/9/25

*/

public ResponseDTO findFileById(Long id) {

FileEntity fileEntity = baseMapper.selectById(id);

if (null == fileEntity) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, "文件不存在");

}

UploadVO vo = new UploadVO();

/*String url = minioTemplate.getObjectURL(bucket,fileEntity.getFileName());

if(StringUtils.isEmpty(url)){

return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM,"获取minio 文件url失败!");

}*/

vo.setFileName(fileEntity.getOriginalFileName());

vo.setUrl(httpUrl + fileEntity.getFileUrl());

vo.setNewFileName(fileEntity.getFileName());

vo.setFileSize(fileEntity.getFileSize());

vo.setFileLocationType(FileServiceTypeEnum.MINIO_OSS.getLocationType());

return ResponseDTO.succData(vo);

}

/**

* 文件流式下载

*

* @author sunboqiang

* @date 2020/10/22

*/

public ResponseEntity downLoadFile(Long id, HttpServletRequest request) {

FileEntity fileEntity = baseMapper.selectById(id);

if (null == fileEntity) {

throw new SmartBusinessException("文件信息不存在");

zEosT}

if (StringUtils.isEmpty(fileEntity.getFileUrl())) {

throw new SmartBusinessException("文件url为空");

}

ResponseEntity stream = minioTemplate.fileDownload(httpUrl + fileEntity.getFileUrl(), fileEntity.getOriginalFileName(), request);

return stream;

}

/**

* 文件删除(通过文件名)

*

* @author tarzan Liu

* @date 2020/11/11

*/

public ResponseDTO deleteFiles(List fileNames) {

try {

for (String fileName : fileNames) {

minioTemplate.removeObject(bucket, fileName);

}

} catch (Exception e) {

return ResponseDTO.wrap(ResponseCodeConst.ERROR, e.getMessage());

}

return ResponseDTO.succ();

}

/**

* tarzan LIU

*

* @author tarzan Liu

* @date 2020/11/11

*/

public ResponseDTO downloadTargetDir(String objectName, String dirPath) {

minioTemplate.downloadTargetDir(bucket, objectName, dirPath);

return ResponseDTO.succ();

}

/**

* 下载备份编译结果

*

* @param dirPath

* @return {@link Boolean}

* @author zhangpeng

* @date 2021年10月15日

*/

public Boolean downloadCompile(String dirPath) {

if (!minioTemplate.bucketExists(bucket)) {

log.info("Bucket not exists.");

return true;

}

List list = minioTemplate.getAllObjectsByPrefix(bucket, "CompileResult/", true);

list.forEach(e -> {

String url = minioTemplate.getObjectUrl(bucket, e.getObjectName());

InputStream minioStream = minioTemplate.getObject(bucket, e.getObjectName());

File file = new File(dirPath + url.substring(url.indexOf("CompileResult")-1));

if (!file.getParentFile().exists()) {

file.getParentFile().mkdirs();

}

FileUtil.toFile(minioStream, file);

});

log.info("downloadCompile complete.");

return true;

}

部分操作数据库的相关代码省略,不再展示

创建FilesMinioController 服务接口

import com.alibaba.fastjson.JSONObject;

import com.alibaba.fastjson.serializer.SerializerFeature;

import com.gis.spacedata.common.anno.NoNeedLogin;

import com.gis.spacedata.common.domain.ResponseDTO;

import com.gis.spacedata.domain.dto.file.vo.UploadVO;

import com.gis.spacedata.service.file.FilesMinioService;

import io.swagger.annotations.Api;

import io.swagger.annotations.ApiOperation;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.Arrays;

import java.util.List;

@Api(tags = {"minio文件服务"})

@RestController

public class FilesMinioController {

@Autowired

private FilesMinioService filesMinioService;

@ApiOperation(value = "文件上传(md5去重上传) by sunboqiang")

@PostMapping("/minio/uploadFile/md5")

@NoNeedLogin

public ResponseDTO uploadFile(MultipartFile file) throws IOException {

return filesMinioService.fileUpload(file);

}

@ApiOperation(value = "文件上传(不做重复校验) by sunboqiang")

@PostMapping("/minio/uploadFile/noRepeatCheck")

public ResponseDTO fileUploadRep(MultipartFile file) throws IOException {

return filesMinioService.fileUploadRep(file);

}

@ApiOperation(value = "文件流上传 by sunboqiang")

@PostMapping("/minio/uploadFile/stream/{fileName}")

public ResponseDTO uploadStream(InputStream inputStream, @PathVariable("fileName") String fileName) throws IOException {

return filesMinioService.uploadStream(inputStream, fileName);

}

@ApiOperation(value = "文件查询(永久链接) by sunboqiang")

@GetMapping("/minio/getFileUrl/{id}")

public ResponseDTO findFileById(@PathVariable("id") Long id) {

return filesMinioService.findFileById(id);

}

@ApiOperation(value = "文件流式下载 by sunboqiang")

@GetMapping("/minio/downloadFile/stream")

public ResponseEntity downLoadFile(@RequestParam Long id, HttpServletRequest request) {

return filesMinioService.downLoadFile(id, request);

}

@ApiOperation(value = "文件删除(通过文件名) by sunboqiang")

@PostMapping("/minio/deleteFiles")

public ResponseDTO deleteFiles(@RequestBody List fileNames) {

return filesMinioService.deleteFiles(fileNames);

}

}

以上就是Springboot整合minio实现文件服务的教程详解的详细内容,更多关于Springboot minio文件服务的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java 开启多线程常见的4种方法
下一篇:关于RedisTemplate之opsForValue的使用说明
相关文章

 发表评论

暂时没有评论,来抢沙发吧~