网站建设公司做ppt吗,广州白云区网站开发,服装营销方式和手段,上门做网站哪家好SpringBoot整合Minio
在企业开发中#xff0c;我们经常会使用到文件存储的业务#xff0c;Minio就是一个不错的文件存储工具#xff0c;下面我们来看看如何在SpringBoot中整合Minio
POM
pom文件指定SpringBoot项目所依赖的软件工具包
?xml version1.0 …SpringBoot整合Minio
在企业开发中我们经常会使用到文件存储的业务Minio就是一个不错的文件存储工具下面我们来看看如何在SpringBoot中整合Minio
POM
pom文件指定SpringBoot项目所依赖的软件工具包
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.zsxq/groupIdartifactIdcsg_idc_zsxq/artifactIdversion0.0.1-SNAPSHOT/versionnamecsg_idc_zsxq/namedescriptioncsg_idc_zsxq/descriptionpropertiesjava.version17/java.versionproject.build.sourceEncodingUTF-8/project.build.sourceEncodingproject.reporting.outputEncodingUTF-8/project.reporting.outputEncodingspring-boot.version2.7.3/spring-boot.version/propertiesdependenciesdependencygroupIdorg.apache.httpcomponents/groupIdartifactIdhttpclient/artifactId/dependencydependencygroupIdorg.apache.cxf/groupIdartifactIdcxf-rt-transports-http/artifactIdversion3.5.1/version/dependencydependencygroupIdorg.apache.cxf/groupIdartifactIdcxf-rt-frontend-jaxws/artifactIdversion3.5.1/version/dependencydependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.12/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactIdversion2.7.7/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion2.0.16/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis-reactive/artifactId/dependencydependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.12/version/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.12.0/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.26/version/dependency!--minio--dependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion8.0.3/version/dependency/dependenciesdependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion${spring-boot.version}/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.8.1/versionconfigurationsource17/sourcetarget17/targetencodingUTF-8/encoding/configuration/pluginplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdversion${spring-boot.version}/versionconfigurationmainClasscom.idc.zsxq.CsgIdcZsxqApplication/mainClassskiptrue/skip/configurationexecutionsexecutionidrepackage/idgoalsgoalrepackage/goal/goals/execution/executions/plugin/plugins/build/project
YML
SpringBoot配置文件
server:port: 11112
# springdoc-openapi项目配置
knife4j:enable: truesetting:language: zh_cn
spring:redis:password:host: 127.0.0.1port: 6379username:
# minio
minio:endpoint: http://127.0.0.1:9000accessKey: minioadminsecretKey: minioadminbucketName: bucketMinioClientConfig
Minio的配置类
package com.idc.zsxq.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;Data
Component
public class MinIoClientConfig {Value(${minio.endpoint})private String endpoint;Value(${minio.accessKey})private String accessKey;Value(${minio.secretKey})private String secretKey;/*** 注入minio 客户端** return*/Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}}
MinioUtil
操作Minio的工具类实现了判断Bucket是否存在创建Bucket上传文件下载文件等功能
package com.idc.zsxq.util;import com.idc.zsxq.model.ObjectItem;
import io.minio.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.apache.tomcat.util.http.fileupload.IOUtils;
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.annotation.Resource;
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.stream.Collectors;/*** description minio工具类* version3.0*/
Component
public class MinioUtil {Resourceprivate MinioClient minioClient;Value(${minio.bucketName})private String bucketName;/*** 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;}/*** description: 上传文件** param multipartFile* return: java.lang.String*/public ListString upload(MultipartFile[] multipartFile) {ListString 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();}InputStream in null;try {in file.getInputStream();minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).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();}}}names.add(fileName);}return names;}/*** description: 上传文件流** param in* return: InputStream*/public void upload(InputStream in, String bucketName, String fileName) {try {minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(in, in.available(), -1).contentType(application/octet-stream;charsetUTF-8).build());} catch (Exception e) {e.printStackTrace();} finally {try {in.close();} catch (IOException e) {e.printStackTrace();}}}/*** description: 下载文件** param fileName* return: org.springframework.http.ResponseEntitybyte [ ]*/public ResponseEntitybyte[] download(String fileName, String bucketName) {ResponseEntitybyte[] 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();}//需要设置此属性否则浏览器默认不会读取到响应头中的Accept-Ranges属性因此会认为服务器端不支持分片所以会直接全文下载headers.add(Access-Control-Expose-Headers, Accept-Ranges,Content-Range);headers.setContentLength(bytes.length);headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);headers.setAccessControlExposeHeaders(Arrays.asList(*));responseEntity new ResponseEntitybyte[](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 ListObjectItem listObjects(String bucketName) {IterableResultItem results minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());ListObjectItem objectItems new ArrayList();try {for (ResultItem 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 bucketName 存储bucket名称* param objects 对象名称集合*/public IterableResultDeleteError removeObjects(String bucketName, ListString objects) {ListDeleteObject dos objects.stream().map(e - new DeleteObject(e)).collect(Collectors.toList());IterableResultDeleteError results minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());return results;}}
案例
在SpringBoot中如何使用MinioUtil操作Minio一般我们会使用Minio当做文件缓存
下面这个案例实现了下载文件的功能逻辑先从Minio查找是否存在文件如果存在则从Minio下载文件如果不存在则从远程文件服务器下载文件
//获取文件
public byte[] downloadFile(String bucketName, String fileId, String newFileId) {log.info(下载文件 开始);// 测试bucketName library;fileId 6cc750db08c943b48a259020ce4e6794;newFileId 0fe8cb9eb5954cc2876c3ac8496692a7;String fileName bucketName _ fileId _ (newFileId null ? : newFileId);log.info(文件名 {}, fileName);try {//如果没有bucket则创建minioUtil.existBucket(bucketName);//判断Minio中是否有该文件ListObjectItem objectItems minioUtil.listObjects(bucketName);boolean flag false;if (CollectionUtil.isNotEmpty(objectItems)) {for (ObjectItem o : objectItems) {if (StringUtils.equals(o.getObjectName(), fileName)) {flag true;break;}}}byte[] bytes null;//如果有则从Minio中获取文件if (flag) {log.info(从Minio获取文件);ResponseEntitybyte[] download minioUtil.download(fileName, bucketName);bytes download.getBody();} else {log.info(从文件服务器获取文件);//如果Minio没有则从文件服务器获取文件如果报错则抛出异常//封装基本查询参数urlString withParamsUrl CnkiUrlEnum.DOWNLOAD_FILE.getUrl() ?fileId fileId (StringUtils.isEmpty(newFileId) ? : newFileId newFileId) bucketName bucketName;HttpResponse httpResponse HttpRequest.post(withParamsUrl).header(accessToken, ConstantEnum.TOKEN.getValue()).body().execute();String status httpResponse.getStatus() ;//判断是否请求成功if (!200.equals(status) !204.equals(status)) {log.error(数据库查询异常, CNKI接口返回状态码为: status);throw new BusinessException(ResultEnum.ERROR);}//空文件抛出异常if (StringUtils.equals(httpResponse.header(Content-Type), application/json)) {String jsonBody httpResponse.body();JSONObject dataJson JSONObject.parseObject(jsonBody);String dataCode dataJson.getString(code);log.error(文件内容为空 dataCode);throw new BusinessException(ResultEnum.ERROR);}//获取文件字节流bytes httpResponse.bodyBytes();//写入MiniominioUtil.upload(new ByteArrayInputStream(bytes), bucketName, fileName);}log.info(下载文件 结束);//写到响应流中return bytes;} catch (Exception e) {log.error(下载文件报错 : {}, e);}return new byte[]{};}效果
通过postman调用接口返回文件流