Springboot整合minio实现文件服务的教程详解
首先pom文件引入相关依赖
io.minio minio3.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: 10485760fileSize: 1048576000
创建MinioItem字段项目类
import io.minio.messages.Item; import io.minio.messages.Owner; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Date; @Datapublic 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@RequiredArgsConstructorpublic 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; @Overridepublic void afterPropertiesSet() throws Exception {minioClient = new MinioClient(endpoint, accessKey, secretKey); } @SneakyThrowspublic boolean bucketExists(String bucketName) {return minioClient.bucketExists(bucketName); } /*** 创建bucket** @param bucketName bucket名称*/@SneakyThrowspublic void createBucket(String bucketName) {if (!bucketExists(bucketName)) {minioClient.makeBucket(bucketName); }} /*** 获取全部bucket* * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets*/@SneakyThrowspublic ListgetAllBuckets() {return minioClient.listBuckets(); } /*** 根据bucketName获取信息** @param bucketName bucket名称*/@SneakyThrowspublic Optional getBucket(String bucketName) {return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst(); } /*** 根据bucketName删除信息** @param bucketName bucket名称*/@SneakyThrowspublic void removeBucket(String bucketName) {minioClient.removeBucket(bucketName); } /*** 根据文件前缀查询文件** @param bucketName bucket名称* @param prefix前缀* @param recursive是否递归查询* @return MinioItem 列表*/@SneakyThrowspublic 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*/@SneakyThrowspublic String getObjectURL(String bucketName, String objectName, Integer expires) {return minioClient.presignedGetObject(bucketName, objectName, expires); } /*** 获取文件外链** @param bucketName bucket名称* @param objectName 文件名称* @return url*/@SneakyThrowspublic String getObjectURL(String bucketName, String objectName) {return minioClient.presignedGetObject(bucketName, objectName); } /*** 获取文件url地址** @param bucketName bucket名称* @param objectName 文件名称* @return url*/@SneakyThrowspublic String getObjectUrl(String bucketName, String objectName) {return minioClient.getObjectUrl(bucketName, objectName); } /*** 获取文件** @param bucketName bucket名称* @param objectName 文件名称* @return 二进制流*/@SneakyThrowspublic 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 bucketNamebucket名称* @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) throwsNoSuchAlgorithmException, 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@Slf4jpublic class FilesMinioService extends ServiceImpl{ @Autowiredprivate MinioTemplate minioTemplate; @Resourceprivate 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; //获取文件md5FileEntity 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("文件信息不存在"); }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文件服务"})@RestControllerpublic class FilesMinioController { @Autowiredprivate FilesMinioService filesMinioService; @ApiOperation(value = "https://www.it610.com/article/文件上传(md5去重上传) by sunboqiang")@PostMapping("/minio/uploadFile/md5")@NoNeedLoginpublic ResponseDTOuploadFile(MultipartFile file) throws IOException {return filesMinioService.fileUpload(file); } @ApiOperation(value = "https://www.it610.com/article/文件上传(不做重复校验) by sunboqiang")@PostMapping("/minio/uploadFile/noRepeatCheck")public ResponseDTO fileUploadRep(MultipartFile file) throws IOException {return filesMinioService.fileUploadRep(file); } @ApiOperation(value = "https://www.it610.com/article/文件流上传 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 = "https://www.it610.com/article/文件查询(永久链接) by sunboqiang")@GetMapping("/minio/getFileUrl/{id}")public ResponseDTO findFileById(@PathVariable("id") Long id) {return filesMinioService.findFileById(id); } @ApiOperation(value = "https://www.it610.com/article/文件流式下载 by sunboqiang")@GetMapping("/minio/downloadFile/stream")public ResponseEntity downLoadFile(@RequestParam Long id, HttpServletRequest request) {return filesMinioService.downLoadFile(id, request); } @ApiOperation(value = "https://www.it610.com/article/文件删除(通过文件名) by sunboqiang")@PostMapping("/minio/deleteFiles")public ResponseDTO deleteFiles(@RequestBody List fileNames) {return filesMinioService.deleteFiles(fileNames); }}
【Springboot整合minio实现文件服务的教程详解】以上就是Springboot整合minio实现文件服务的教程详解的详细内容,更多关于Springboot minio文件服务的资料请关注脚本之家其它相关文章!
推荐阅读
- springboot默认日志框架选择源码解析(推荐)
- SpringBoot|SpringBoot 集成缓存性能之王 Caffeine
- 【SpringBoot】YAML|【SpringBoot】YAML 配置文件
- SpringBoot加密配置文件的SQL账号密码方式
- 数字资产知识库管理系统实现过程(springboot+es+vue+neo4j)
- 物联网微消息队列MQTT介绍-EMQX集群搭建以及与SpringBoot整合
- Spring源码|Spring源码之整合Mybatis底层实现
- springboot|SpringBoot集成JWT实现token验证
- 全文检索|springboot整合
- springboot导出MYSQL数据库文档 screw集成