一、pom.xml依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.1.0</version>
</dependency>
二、配置文件
config.properties
#---------------MinIO接入配置----------#
#MinIO服务所在地址
#注意:这里的端口指的是minio的服务端口,不是console的端口
minio.endpoint=http://127.0.0.1:9002
#存储桶名称
minio.bucketName=xxx
#访问的key
minio.accessKey=xxx
#访问的秘钥
minio.secretKey=xxx
三、配置类
package com.xxx.config;
import com.xxx.util.Constant;
import com.xxx.util.MinIOUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@Slf4j
@PropertySource(value = {
"classpath:config.properties"})
public class MinIOConfig {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.bucketName}")
private String bucketName;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Bean
public MinIOUtils minIOUtils() {
return new MinIOUtils(endpoint, bucketName, accessKey, secretKey);
}
}
四、ContentType管理Map
package com.xxx.mgr;
import java.util.HashMap;
import java.util.Map;
/**
* 上下文类型管理
*
* @date 2023/6/6 10:44
*/
public class ContentTypeMapMrg {
/**
* 上下文类型map
*/
public static final Map<String, String> CONTENT_TYPE_MAP = new HashMap<>();
static {
CONTENT_TYPE_MAP.put(".001","application/x-001");
CONTENT_TYPE_MAP.put(".301","application/x-301");
CONTENT_TYPE_MAP.put(".323","text/h323");
CONTENT_TYPE_MAP.put(".906","application/x-906");
CONTENT_TYPE_MAP.put(".907","drawing/907");
CONTENT_TYPE_MAP.put(".a11","application/x-a11");
CONTENT_TYPE_MAP.put(".acp","audio/x-mei-aac");
CONTENT_TYPE_MAP.put(".ai","application/postscript");
CONTENT_TYPE_MAP.put(".aif","audio/aiff");
CONTENT_TYPE_MAP.put(".aifc","audio/aiff");
CONTENT_TYPE_MAP.put(".aiff","audio/aiff");
CONTENT_TYPE_MAP.put(".anv","application/x-anv");
CONTENT_TYPE_MAP.put(".asa","text/asa");
CONTENT_TYPE_MAP.put(".asf","video/x-ms-asf");
CONTENT_TYPE_MAP.put(".asp","text/asp");
CONTENT_TYPE_MAP.put(".asx","video/x-ms-asf");
CONTENT_TYPE_MAP.put(".au","audio/basic");
CONTENT_TYPE_MAP.put(".avi","video/avi");
CONTENT_TYPE_MAP.put(".awf","application/vnd.adobe.workflow");
CONTENT_TYPE_MAP.put(".biz","text/xml");
CONTENT_TYPE_MAP.put(".bmp","application/x-bmp");
CONTENT_TYPE_MAP.put(".bot","application/x-bot");
CONTENT_TYPE_MAP.put(".c4t","application/x-c4t");
CONTENT_TYPE_MAP.put(".c90","application/x-c90");
CONTENT_TYPE_MAP.put(".cal","application/x-cals");
CONTENT_TYPE_MAP.put(".cat","application/vnd.ms-pki.seccat");
CONTENT_TYPE_MAP.put(".cdf","application/x-netcdf");
CONTENT_TYPE_MAP.put(".cdr","application/x-cdr");
CONTENT_TYPE_MAP.put(".cel","application/x-cel");
CONTENT_TYPE_MAP.put(".cer","application/x-x509-ca-cert");
CONTENT_TYPE_MAP.put(".cg4","application/x-g4");
CONTENT_TYPE_MAP.put(".cgm","application/x-cgm");
CONTENT_TYPE_MAP.put(".cit","application/x-cit");
CONTENT_TYPE_MAP.put(".class","java/");
CONTENT_TYPE_MAP.put(".cml","text/xml");
CONTENT_TYPE_MAP.put(".cmp","application/x-cmp");
CONTENT_TYPE_MAP.put(".cmx","application/x-cmx");
CONTENT_TYPE_MAP.put(".cot","application/x-cot");
CONTENT_TYPE_MAP.put(".crl","application/pkix-crl");
CONTENT_TYPE_MAP.put(".crt","application/x-x509-ca-cert");
CONTENT_TYPE_MAP.put(".csi","application/x-csi");
CONTENT_TYPE_MAP.put(".css","text/css");
CONTENT_TYPE_MAP.put(".cut","application/x-cut");
CONTENT_TYPE_MAP.put(".dbf","application/x-dbf");
CONTENT_TYPE_MAP.put(".dbm","application/x-dbm");
CONTENT_TYPE_MAP.put(".dbx","application/x-dbx");
CONTENT_TYPE_MAP.put(".dcd","text/xml");
CONTENT_TYPE_MAP.put(".dcx","application/x-dcx");
CONTENT_TYPE_MAP.put(".der","application/x-x509-ca-cert");
CONTENT_TYPE_MAP.put(".dgn","application/x-dgn");
CONTENT_TYPE_MAP.put(".dib","application/x-dib");
CONTENT_TYPE_MAP.put(".dll","application/x-msdownload");
CONTENT_TYPE_MAP.put(".doc","application/msword");
CONTENT_TYPE_MAP.put(".dot","application/msword");
CONTENT_TYPE_MAP.put(".drw","application/x-drw");
CONTENT_TYPE_MAP.put(".dtd","text/xml");
CONTENT_TYPE_MAP.put(".dwf","Model/vnd.dwf");
//CONTENT_TYPE_MAP.put(".dwf","application/x-dwf");
CONTENT_TYPE_MAP.put(".dwg","application/x-dwg");
CONTENT_TYPE_MAP.put(".dxb","application/x-dxb");
CONTENT_TYPE_MAP.put(".dxf","application/x-dxf");
CONTENT_TYPE_MAP.put(".edn","application/vnd.adobe.edn");
CONTENT_TYPE_MAP.put(".emf","application/x-emf");
CONTENT_TYPE_MAP.put(".eml","message/rfc822");
CONTENT_TYPE_MAP.put(".ent","text/xml");
CONTENT_TYPE_MAP.put(".epi","application/x-epi");
CONTENT_TYPE_MAP.put(".eps","application/x-ps");
//CONTENT_TYPE_MAP.put(".eps","application/postscript");
CONTENT_TYPE_MAP.put(".etd","application/x-ebx");
CONTENT_TYPE_MAP.put(".exe","application/x-msdownload");
CONTENT_TYPE_MAP.put(".fax","image/fax");
CONTENT_TYPE_MAP.put(".fdf","application/vnd.fdf");
CONTENT_TYPE_MAP.put(".fif","application/fractals");
CONTENT_TYPE_MAP.put(".fo","text/xml");
CONTENT_TYPE_MAP.put(".frm","application/x-frm");
CONTENT_TYPE_MAP.put(".g4","application/x-g4");
CONTENT_TYPE_MAP.put(".gbr","application/x-gbr");
CONTENT_TYPE_MAP.put(".gcd","application/x-gcd");
CONTENT_TYPE_MAP.put(".gif","image/gif");
CONTENT_TYPE_MAP.put(".gl2","application/x-gl2");
CONTENT_TYPE_MAP.put(".gp4","application/x-gp4");
CONTENT_TYPE_MAP.put(".hgl","application/x-hgl");
CONTENT_TYPE_MAP.put(".hmr","application/x-hmr");
CONTENT_TYPE_MAP.put(".hpg","application/x-hpgl");
CONTENT_TYPE_MAP.put(".hpl","application/x-hpl");
CONTENT_TYPE_MAP.put(".hqx","application/mac-binhex40");
CONTENT_TYPE_MAP.put(".hrf","application/x-hrf");
CONTENT_TYPE_MAP.put(".hta","application/hta");
CONTENT_TYPE_MAP.put(".htc","text/x-component");
CONTENT_TYPE_MAP.put(".htm","text/html");
CONTENT_TYPE_MAP.put(".html","text/html");
CONTENT_TYPE_MAP.put(".htt","text/webviewhtml");
CONTENT_TYPE_MAP.put(".htx","text/html");
CONTENT_TYPE_MAP.put(".icb","application/x-icb");
CONTENT_TYPE_MAP.put(".ico","image/x-icon");
//CONTENT_TYPE_MAP.put(".ico","application/x-ico");
CONTENT_TYPE_MAP.put(".iff","application/x-iff");
CONTENT_TYPE_MAP.put(".ig4","application/x-g4");
CONTENT_TYPE_MAP.put(".igs","application/x-igs");
CONTENT_TYPE_MAP.put(".iii","application/x-iphone");
CONTENT_TYPE_MAP.put(".img","application/x-img");
CONTENT_TYPE_MAP.put(".ins","application/x-internet-signup");
CONTENT_TYPE_MAP.put(".isp","application/x-internet-signup");
CONTENT_TYPE_MAP.put(".IVF","video/x-ivf");
CONTENT_TYPE_MAP.put(".java","java/*");
CONTENT_TYPE_MAP.put(".jfif","image/jpeg");
CONTENT_TYPE_MAP.put(".jpe","image/jpeg");
//CONTENT_TYPE_MAP.put(".jpe","application/x-jpe");
CONTENT_TYPE_MAP.put(".jpeg","image/jpeg");
CONTENT_TYPE_MAP.put(".jpg","image/jpeg");
//CONTENT_TYPE_MAP.put(".jpg","application/x-jpg");
CONTENT_TYPE_MAP.put(".js","application/x-javascript");
CONTENT_TYPE_MAP.put(".jsp","text/html");
CONTENT_TYPE_MAP.put(".la1","audio/x-liquid-file");
CONTENT_TYPE_MAP.put(".lar","application/x-laplayer-reg");
CONTENT_TYPE_MAP.put(".latex","application/x-latex");
CONTENT_TYPE_MAP.put(".lavs","audio/x-liquid-secure");
CONTENT_TYPE_MAP.put(".lbm","application/x-lbm");
CONTENT_TYPE_MAP.put(".lmsff","audio/x-la-lms");
CONTENT_TYPE_MAP.put(".ls","application/x-javascript");
CONTENT_TYPE_MAP.put(".ltr","application/x-ltr");
CONTENT_TYPE_MAP.put(".m1v","video/x-mpeg");
CONTENT_TYPE_MAP.put(".m2v","video/x-mpeg");
CONTENT_TYPE_MAP.put(".m3u","audio/mpegurl");
CONTENT_TYPE_MAP.put(".m4e","video/mpeg4");
CONTENT_TYPE_MAP.put(".mac","application/x-mac");
CONTENT_TYPE_MAP.put(".man","application/x-troff-man");
CONTENT_TYPE_MAP.put(".math","text/xml");
CONTENT_TYPE_MAP.put(".mdb","application/msaccess");
//CONTENT_TYPE_MAP.put(".mdb","application/x-mdb");
CONTENT_TYPE_MAP.put(".mfp","application/x-shockwave-flash");
CONTENT_TYPE_MAP.put(".mht","message/rfc822");
CONTENT_TYPE_MAP.put(".mhtml","message/rfc822");
CONTENT_TYPE_MAP.put(".mi","application/x-mi");
CONTENT_TYPE_MAP.put(".mid","audio/mid");
CONTENT_TYPE_MAP.put(".midi","audio/mid");
CONTENT_TYPE_MAP.put(".mil","application/x-mil");
CONTENT_TYPE_MAP.put(".mml","text/xml");
CONTENT_TYPE_MAP.put(".mnd","audio/x-musicnet-download");
CONTENT_TYPE_MAP.put(".mns","audio/x-musicnet-stream");
CONTENT_TYPE_MAP.put(".mocha","application/x-javascript");
CONTENT_TYPE_MAP.put(".movie","video/x-sgi-movie");
CONTENT_TYPE_MAP.put(".mp1","audio/mp1");
CONTENT_TYPE_MAP.put(".mp2","audio/mp2");
CONTENT_TYPE_MAP.put(".mp2v","video/mpeg");
CONTENT_TYPE_MAP.put(".mp3","audio/mp3");
CONTENT_TYPE_MAP.put(".mp4","video/mpeg4");
CONTENT_TYPE_MAP.put(".mpa","video/x-mpg");
CONTENT_TYPE_MAP.put(".mpd","application/vnd.ms-project");
CONTENT_TYPE_MAP.put(".mpe","video/x-mpeg");
CONTENT_TYPE_MAP.put(".mpeg","video/mpg");
CONTENT_TYPE_MAP.put(".mpg","video/mpg");
CONTENT_TYPE_MAP.put(".mpga","audio/rn-mpeg");
CONTENT_TYPE_MAP.put(".mpp","application/vnd.ms-project");
CONTENT_TYPE_MAP.put(".mps","video/x-mpeg");
CONTENT_TYPE_MAP.put(".mpt","application/vnd.ms-project");
CONTENT_TYPE_MAP.put(".mpv","video/mpg");
CONTENT_TYPE_MAP.put(".mpv2","video/mpeg");
CONTENT_TYPE_MAP.put(".mpw","application/vnd.ms-project");
CONTENT_TYPE_MAP.put(".mpx","application/vnd.ms-project");
CONTENT_TYPE_MAP.put(".mtx","text/xml");
CONTENT_TYPE_MAP.put(".mxp","application/x-mmxp");
CONTENT_TYPE_MAP.put(".net","image/pnetvue");
CONTENT_TYPE_MAP.put(".nrf","application/x-nrf");
CONTENT_TYPE_MAP.put(".nws","message/rfc822");
CONTENT_TYPE_MAP.put(".odc","text/x-ms-odc");
CONTENT_TYPE_MAP.put(".out","application/x-out");
CONTENT_TYPE_MAP.put(".p10","application/pkcs10");
CONTENT_TYPE_MAP.put(".p12","application/x-pkcs12");
CONTENT_TYPE_MAP.put(".p7b","application/x-pkcs7-certificates");
CONTENT_TYPE_MAP.put(".p7c","application/pkcs7-mime");
CONTENT_TYPE_MAP.put(".p7m","application/pkcs7-mime");
CONTENT_TYPE_MAP.put(".p7r","application/x-pkcs7-certreqresp");
CONTENT_TYPE_MAP.put(".p7s","application/pkcs7-signature");
CONTENT_TYPE_MAP.put(".pc5","application/x-pc5");
CONTENT_TYPE_MAP.put(".pci","application/x-pci");
CONTENT_TYPE_MAP.put(".pcl","application/x-pcl");
CONTENT_TYPE_MAP.put(".pcx","application/x-pcx");
CONTENT_TYPE_MAP.put(".pdf","application/pdf");
CONTENT_TYPE_MAP.put(".pdx","application/vnd.adobe.pdx");
CONTENT_TYPE_MAP.put(".pfx","application/x-pkcs12");
CONTENT_TYPE_MAP.put(".pgl","application/x-pgl");
CONTENT_TYPE_MAP.put(".pic","application/x-pic");
CONTENT_TYPE_MAP.put(".pko","application/vnd.ms-pki.pko");
CONTENT_TYPE_MAP.put(".pl","application/x-perl");
CONTENT_TYPE_MAP.put(".plg","text/html");
CONTENT_TYPE_MAP.put(".pls","audio/scpls");
CONTENT_TYPE_MAP.put(".plt","application/x-plt");
CONTENT_TYPE_MAP.put(".png","image/png");
//CONTENT_TYPE_MAP.put(".png","application/x-png");
CONTENT_TYPE_MAP.put(".pot","application/vnd.ms-powerpoint");
CONTENT_TYPE_MAP.put(".ppa","application/vnd.ms-powerpoint");
CONTENT_TYPE_MAP.put(".ppm","application/x-ppm");
CONTENT_TYPE_MAP.put(".pps","application/vnd.ms-powerpoint");
CONTENT_TYPE_MAP.put(".ppt","application/vnd.ms-powerpoint");
//CONTENT_TYPE_MAP.put(".ppt","application/x-ppt");
CONTENT_TYPE_MAP.put(".pr","application/x-pr");
CONTENT_TYPE_MAP.put(".prf","application/pics-rules");
CONTENT_TYPE_MAP.put(".prn","application/x-prn");
CONTENT_TYPE_MAP.put(".prt","application/x-prt");
CONTENT_TYPE_MAP.put(".ps","application/x-ps");
//CONTENT_TYPE_MAP.put(".ps","application/postscript");
CONTENT_TYPE_MAP.put(".ptn","application/x-ptn");
CONTENT_TYPE_MAP.put(".pwz","application/vnd.ms-powerpoint");
CONTENT_TYPE_MAP.put(".r3t","text/vnd.rn-realtext3d");
CONTENT_TYPE_MAP.put(".ra","audio/vnd.rn-realaudio");
CONTENT_TYPE_MAP.put(".ram","audio/x-pn-realaudio");
CONTENT_TYPE_MAP.put(".ras","application/x-ras");
CONTENT_TYPE_MAP.put(".rat","application/rat-file");
CONTENT_TYPE_MAP.put(".rdf","text/xml");
CONTENT_TYPE_MAP.put(".rec","application/vnd.rn-recording");
CONTENT_TYPE_MAP.put(".red","application/x-red");
CONTENT_TYPE_MAP.put(".rgb","application/x-rgb");
CONTENT_TYPE_MAP.put(".rjs","application/vnd.rn-realsystem-rjs");
CONTENT_TYPE_MAP.put(".rjt","application/vnd.rn-realsystem-rjt");
CONTENT_TYPE_MAP.put(".rlc","application/x-rlc");
CONTENT_TYPE_MAP.put(".rle","application/x-rle");
CONTENT_TYPE_MAP.put(".rm","application/vnd.rn-realmedia");
CONTENT_TYPE_MAP.put(".rmf","application/vnd.adobe.rmf");
CONTENT_TYPE_MAP.put(".rmi","audio/mid");
CONTENT_TYPE_MAP.put(".rmj","application/vnd.rn-realsystem-rmj");
CONTENT_TYPE_MAP.put(".rmm","audio/x-pn-realaudio");
CONTENT_TYPE_MAP.put(".rmp","application/vnd.rn-rn_music_package");
CONTENT_TYPE_MAP.put(".rms","application/vnd.rn-realmedia-secure");
CONTENT_TYPE_MAP.put(".rmvb","application/vnd.rn-realmedia-vbr");
CONTENT_TYPE_MAP.put(".rmx","application/vnd.rn-realsystem-rmx");
CONTENT_TYPE_MAP.put(".rnx","application/vnd.rn-realplayer");
CONTENT_TYPE_MAP.put(".rp","image/vnd.rn-realpix");
CONTENT_TYPE_MAP.put(".rpm","audio/x-pn-realaudio-plugin");
CONTENT_TYPE_MAP.put(".rsml","application/vnd.rn-rsml");
CONTENT_TYPE_MAP.put(".rt","text/vnd.rn-realtext");
CONTENT_TYPE_MAP.put(".rtf","application/msword");
//CONTENT_TYPE_MAP.put(".rtf","application/x-rtf");
CONTENT_TYPE_MAP.put(".rv","video/vnd.rn-realvideo");
CONTENT_TYPE_MAP.put(".sam","application/x-sam");
CONTENT_TYPE_MAP.put(".sat","application/x-sat");
CONTENT_TYPE_MAP.put(".sdp","application/sdp");
CONTENT_TYPE_MAP.put(".sdw","application/x-sdw");
CONTENT_TYPE_MAP.put(".sit","application/x-stuffit");
CONTENT_TYPE_MAP.put(".slb","application/x-slb");
CONTENT_TYPE_MAP.put(".sld","application/x-sld");
CONTENT_TYPE_MAP.put(".slk","drawing/x-slk");
CONTENT_TYPE_MAP.put(".smi","application/smil");
CONTENT_TYPE_MAP.put(".smil","application/smil");
CONTENT_TYPE_MAP.put(".smk","application/x-smk");
CONTENT_TYPE_MAP.put(".snd","audio/basic");
CONTENT_TYPE_MAP.put(".sol","text/plain");
CONTENT_TYPE_MAP.put(".sor","text/plain");
CONTENT_TYPE_MAP.put(".spc","application/x-pkcs7-certificates");
CONTENT_TYPE_MAP.put(".spl","application/futuresplash");
CONTENT_TYPE_MAP.put(".spp","text/xml");
CONTENT_TYPE_MAP.put(".ssm","application/streamingmedia");
CONTENT_TYPE_MAP.put(".sst","application/vnd.ms-pki.certstore");
CONTENT_TYPE_MAP.put(".stl","application/vnd.ms-pki.stl");
CONTENT_TYPE_MAP.put(".stm","text/html");
CONTENT_TYPE_MAP.put(".sty","application/x-sty");
CONTENT_TYPE_MAP.put(".svg","text/xml");
CONTENT_TYPE_MAP.put(".swf","application/x-shockwave-flash");
CONTENT_TYPE_MAP.put(".tdf","application/x-tdf");
CONTENT_TYPE_MAP.put(".tg4","application/x-tg4");
CONTENT_TYPE_MAP.put(".tga","application/x-tga");
CONTENT_TYPE_MAP.put(".tif","image/tiff");
//CONTENT_TYPE_MAP.put(".tif","application/x-tif");
CONTENT_TYPE_MAP.put(".tiff","image/tiff");
CONTENT_TYPE_MAP.put(".tld","text/xml");
CONTENT_TYPE_MAP.put(".top","drawing/x-top");
CONTENT_TYPE_MAP.put(".torrent","application/x-bittorrent");
CONTENT_TYPE_MAP.put(".tsd","text/xml");
CONTENT_TYPE_MAP.put(".txt","text/plain");
CONTENT_TYPE_MAP.put(".uin","application/x-icq");
CONTENT_TYPE_MAP.put(".uls","text/iuls");
CONTENT_TYPE_MAP.put(".vcf","text/x-vcard");
CONTENT_TYPE_MAP.put(".vda","application/x-vda");
CONTENT_TYPE_MAP.put(".vdx","application/vnd.visio");
CONTENT_TYPE_MAP.put(".vml","text/xml");
CONTENT_TYPE_MAP.put(".vpg","application/x-vpeg005");
CONTENT_TYPE_MAP.put(".vsd","application/vnd.visio");
//CONTENT_TYPE_MAP.put(".vsd","application/x-vsd");
CONTENT_TYPE_MAP.put(".vss","application/vnd.visio");
CONTENT_TYPE_MAP.put(".vst","application/vnd.visio");
//CONTENT_TYPE_MAP.put(".vst","application/x-vst");
CONTENT_TYPE_MAP.put(".vsw","application/vnd.visio");
CONTENT_TYPE_MAP.put(".vsx","application/vnd.visio");
CONTENT_TYPE_MAP.put(".vtx","application/vnd.visio");
CONTENT_TYPE_MAP.put(".vxml","text/xml");
CONTENT_TYPE_MAP.put(".wav","audio/wav");
CONTENT_TYPE_MAP.put(".wax","audio/x-ms-wax");
CONTENT_TYPE_MAP.put(".wb1","application/x-wb1");
CONTENT_TYPE_MAP.put(".wb2","application/x-wb2");
CONTENT_TYPE_MAP.put(".wb3","application/x-wb3");
CONTENT_TYPE_MAP.put(".wbmp","image/vnd.wap.wbmp");
CONTENT_TYPE_MAP.put(".wiz","application/msword");
CONTENT_TYPE_MAP.put(".wk3","application/x-wk3");
CONTENT_TYPE_MAP.put(".wk4","application/x-wk4");
CONTENT_TYPE_MAP.put(".wkq","application/x-wkq");
CONTENT_TYPE_MAP.put(".wks","application/x-wks");
CONTENT_TYPE_MAP.put(".wm","video/x-ms-wm");
CONTENT_TYPE_MAP.put(".wma","audio/x-ms-wma");
CONTENT_TYPE_MAP.put(".wmd","application/x-ms-wmd");
CONTENT_TYPE_MAP.put(".wmf","application/x-wmf");
CONTENT_TYPE_MAP.put(".wml","text/vnd.wap.wml");
CONTENT_TYPE_MAP.put(".wmv","video/x-ms-wmv");
CONTENT_TYPE_MAP.put(".wmx","video/x-ms-wmx");
CONTENT_TYPE_MAP.put(".wmz","application/x-ms-wmz");
CONTENT_TYPE_MAP.put(".wp6","application/x-wp6");
CONTENT_TYPE_MAP.put(".wpd","application/x-wpd");
CONTENT_TYPE_MAP.put(".wpg","application/x-wpg");
CONTENT_TYPE_MAP.put(".wpl","application/vnd.ms-wpl");
CONTENT_TYPE_MAP.put(".wq1","application/x-wq1");
CONTENT_TYPE_MAP.put(".wr1","application/x-wr1");
CONTENT_TYPE_MAP.put(".wri","application/x-wri");
CONTENT_TYPE_MAP.put(".wrk","application/x-wrk");
CONTENT_TYPE_MAP.put(".ws","application/x-ws");
CONTENT_TYPE_MAP.put(".ws2","application/x-ws");
CONTENT_TYPE_MAP.put(".wsc","text/scriptlet");
CONTENT_TYPE_MAP.put(".wsdl","text/xml");
CONTENT_TYPE_MAP.put(".wvx","video/x-ms-wvx");
CONTENT_TYPE_MAP.put(".xdp","application/vnd.adobe.xdp");
CONTENT_TYPE_MAP.put(".xdr","text/xml");
CONTENT_TYPE_MAP.put(".xfd","application/vnd.adobe.xfd");
CONTENT_TYPE_MAP.put(".xfdf","application/vnd.adobe.xfdf");
CONTENT_TYPE_MAP.put(".xhtml","text/html");
CONTENT_TYPE_MAP.put(".xls","application/vnd.ms-excel");
//CONTENT_TYPE_MAP.put(".xls","application/x-xls");
CONTENT_TYPE_MAP.put(".xlw","application/x-xlw");
CONTENT_TYPE_MAP.put(".xml","text/xml");
CONTENT_TYPE_MAP.put(".xpl","audio/scpls");
CONTENT_TYPE_MAP.put(".xq","text/xml");
CONTENT_TYPE_MAP.put(".xql","text/xml");
CONTENT_TYPE_MAP.put(".xquery","text/xml");
CONTENT_TYPE_MAP.put(".xsd","text/xml");
CONTENT_TYPE_MAP.put(".xsl","text/xml");
CONTENT_TYPE_MAP.put(".xslt","text/xml");
CONTENT_TYPE_MAP.put(".xwd","application/x-xwd");
CONTENT_TYPE_MAP.put(".x_b","application/x-x_b");
CONTENT_TYPE_MAP.put(".x_t","application/x-x_t");
}
}
五、工具类
package com.xxx.util;
import com.alibaba.fastjson.JSONObject;
import com.xxx.mgr.ContentTypeMapMrg;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* MinIO操作工具类
*
* @author hcs
* @date 2023/6/1 9:40
*/
public class MinIOUtils {
private static Logger log = LoggerFactory.getLogger(MinIOUtils.class);
private static MinioClient minioClient;
private static String endpoint;
private static String bucketName;
private static String accessKey;
private static String secretKey;
private static final String SEPARATOR = "/";
public MinIOUtils(String endpoint, String bucketName, String accessKey, String secretKey) {
MinIOUtils.endpoint = endpoint;
MinIOUtils.bucketName = bucketName;
MinIOUtils.accessKey = accessKey;
MinIOUtils.secretKey = secretKey;
createMinioClient();
}
public static String getEndpoint() {
return endpoint;
}
public static String getBucketName() {
return bucketName;
}
public static String getAccessKey() {
return accessKey;
}
public static String getSecretKey() {
return secretKey;
}
/**
* 创建minioClient
*/
private void createMinioClient() {
try {
if (null == minioClient) {
log.info("minioClient create start");
minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey)
.build();
createBucket();
log.info("minioClient create end");
}
} catch (Exception e) {
log.error("连接MinIO服务器异常:{}", e.getMessage(), e);
}
}
/**
* 获取上传文件的基础路径
*
* @return url
*/
public static String getBasisUrl() {
return endpoint + SEPARATOR + bucketName + SEPARATOR;
}
/**
* 获取上传文件的基础路径
*
* @param bucketName
* @return url
*/
public static String getBasisUrl(String bucketName) {
return endpoint + SEPARATOR + bucketName + SEPARATOR;
}
/*操作存储桶*/
/**
* 初始化Bucket
*
* @throws Exception 异常
*/
private static void createBucket() throws Exception {
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
}
/**
* 创建bucket
*
* @param bucketName bucket名称
*/
public static void createBucket(String bucketName) throws Exception {
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
}
/**
* 验证bucketName是否存在
*
* @return boolean true:存在
*/
public static boolean bucketExists() throws Exception {
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
}
/**
* 验证bucketName是否存在
*
* @return boolean true:存在
*/
public static boolean bucketExists(String bucketName) throws Exception {
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
}
/**
* 获取存储桶策略
*
* @param bucketName 存储桶名称
* @return json
*/
private JSONObject getBucketPolicy(String bucketName) throws Exception {
String bucketPolicy = minioClient
.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());
return JSONObject.parseObject(bucketPolicy);
}
/**
* 获取全部bucket
* <p>
* https://docs.minio.io/cn/java-client-api-reference.html#listBuckets
*/
public static List<Bucket> getAllBuckets() throws Exception {
return minioClient.listBuckets();
}
/**
* 根据bucketName获取信息
*
* @param bucketName bucket名称
*/
public static Optional<Bucket> getBucket(String bucketName) throws Exception {
return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
}
/**
* 根据bucketName删除信息
*
* @param bucketName bucket名称
*/
public static void removeBucket(String bucketName) throws Exception {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
}
/*操作文件对象*/
/**
* 判断文件是否存在
*
* @param bucketName 存储桶
* @param objectName 对象
* @return true:存在
*/
public static boolean doesObjectExist(String bucketName, String objectName) {
boolean exist = true;
try {
//重新构建objectName
objectName = buildObjectName(objectName);
minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
} catch (Exception e) {
exist = false;
}
return exist;
}
/**
* 判断文件夹是否存在
*
* @param bucketName 存储桶
* @param objectName 文件夹名称(保存/)
* @return true:存在
*/
/*public static boolean doesFolderExist(String bucketName, String objectName) {
//重新构建objectName
objectName = buildObjectName(objectName);
boolean exist = false;
try {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());
for (Result<Item> result : results) {
Item item = result.get();
//明明是文件夹,isDir却是false
if (item.isDir() && objectName.equals(item.objectName())) {
exist = true;
}
}
} catch (Exception e) {
exist = false;
}
return exist;
}*/
/**
* 根据文件前置查询文件
*
* @param bucketName bucket名称
* @param prefix 前缀
* @param recursive 是否递归查询
* @return MinioItem 列表
*/
public static List<Item> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) throws Exception {
List<Item> list = new ArrayList<>();
Iterable<Result<Item>> objectsIterator = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
if (objectsIterator != null) {
for (Result<Item> o : objectsIterator) {
Item item = o.get();
list.add(item);
}
}
return list;
}
/**
* 获取文件流
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @return 二进制流
*/
public static InputStream getObject(String bucketName, String objectName) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
}
/**
* 断点下载
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param offset 起始字节的位置
* @param length 要读取的长度
* @return 流
*/
public InputStream getObject(String bucketName, String objectName, long offset, long length) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
return minioClient.getObject(
GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length)
.build());
}
/**
* 获取路径下文件列表
*
* @param bucketName bucket名称
* @param prefix 文件名称
* @param recursive 是否递归查找,如果是false,就模拟文件夹结构查找
* @return 二进制流
*/
public static Iterable<Result<Item>> listObjects(String bucketName, String prefix, boolean recursive) {
return minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
}
/**
* 通过MultipartFile,上传文件
*
* @param bucketName 存储桶
* @param file 文件
* @param objectName 对象名
* @param fileSuffix 文件后缀
*/
public static ObjectWriteResponse putObjectByFileSuffix(String bucketName, MultipartFile file,
String objectName, String fileSuffix) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
InputStream inputStream = file.getInputStream();
return putObjectByFileSuffix(bucketName, inputStream, objectName, fileSuffix);
}
/**
* 通过MultipartFile,上传文件
*
* @param bucketName 存储桶
* @param file 文件
* @param objectName 对象名
* @param contentType 上下文类型,如:video/mp4,(如果不传递则默认为“application/octet-stream”,在获取文件外链时,获取到的会是二进制流)
*/
public static ObjectWriteResponse putObjectByContentType(String bucketName, MultipartFile file,
String objectName, String contentType) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
InputStream inputStream = file.getInputStream();
return putObjectByContentType(bucketName, inputStream, objectName, contentType);
}
/**
* 上传已知大小的输入流
*
* @param bucketName 存储桶
* @param inputStream 文件输入流
* @param objectName 对象名
* @param fileSuffix 文件后缀
* @param fileSize 文件大小
* @return
* @throws Exception
*/
public static ObjectWriteResponse putObjectByFileSuffix(String bucketName, InputStream inputStream,
String objectName, String fileSuffix, long fileSize) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
//上下文类型,如:video/mp4,(如果不传递则默认为“application/octet-stream”,在获取文件外链时,获取到的会是二进制流)
String contentType = StringUtils.isBlank(fileSuffix) ? null : ContentTypeMapMrg.CONTENT_TYPE_MAP.get(fileSuffix);
PutObjectArgs.Builder object = PutObjectArgs.builder().bucket(bucketName).object(objectName);
if (StringUtils.isNotBlank(contentType)) {
object.contentType(contentType);
}
return minioClient.putObject(object.stream(inputStream, fileSize, -1).build());
}
/**
* 上传已知大小的输入流
*
* @param bucketName 存储桶
* @param inputStream 文件输入流
* @param objectName 对象名
* @param contentType 上下文类型,如:video/mp4,(如果不传递则默认为“application/octet-stream”,在获取文件外链时,获取到的会是二进制流)
* @param fileSize 文件大小
* @return
* @throws Exception
*/
public static ObjectWriteResponse putObjectByContentType(String bucketName, InputStream inputStream,
String objectName, String contentType, long fileSize) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
PutObjectArgs.Builder object = PutObjectArgs.builder().bucket(bucketName).object(objectName);
if (StringUtils.isNotBlank(contentType)) {
object.contentType(contentType);
}
return minioClient.putObject(object.stream(inputStream, fileSize, -1).build());
}
/**
* 上传未知大小的输入流
*
* @param bucketName 存储桶
* @param inputStream 文件输入流
* @param objectName 对象名
* @param fileSuffix 文件后缀
* @return
* @throws Exception
*/
public static ObjectWriteResponse putObjectByFileSuffix(String bucketName, InputStream inputStream,
String objectName, String fileSuffix) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
//上下文类型,如:video/mp4,(如果不传递则默认为“application/octet-stream”,在获取文件外链时,获取到的会是二进制流)
String contentType = StringUtils.isBlank(fileSuffix) ? null : ContentTypeMapMrg.CONTENT_TYPE_MAP.get(fileSuffix);
PutObjectArgs.Builder object = PutObjectArgs.builder().bucket(bucketName).object(objectName);
if (StringUtils.isNotBlank(contentType)) {
object.contentType(contentType);
}
return minioClient.putObject(object.stream(inputStream, -1, 10485760).build());
}
/**
* 上传未知大小的输入流
*
* @param bucketName 存储桶
* @param inputStream 文件输入流
* @param objectName 对象名
* @param contentType 上下文类型,如:video/mp4,(如果不传递则默认为“application/octet-stream”,在获取文件外链时,获取到的会是二进制流)
* @return
* @throws Exception
*/
public static ObjectWriteResponse putObjectByContentType(String bucketName, InputStream inputStream,
String objectName, String contentType) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
PutObjectArgs.Builder object = PutObjectArgs.builder().bucket(bucketName).object(objectName);
if (StringUtils.isNotBlank(contentType)) {
object.contentType(contentType);
}
return minioClient.putObject(object.stream(inputStream, -1, 10485760).build());
}
/**
* 上传本地文件,上传时,同名的会覆盖
*
* @param bucketName 存储桶
* @param objectName 对象名称
* @param filePath 本地文件路径
* @param fileSuffix 文件后缀
*/
public static ObjectWriteResponse uploadObjectByFileSuffix(String bucketName, String objectName, String filePath, String fileSuffix) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
//上下文类型,如:video/mp4,(如果不传递则默认为“application/octet-stream”,在获取文件外链时,获取到的会是二进制流)
String contentType = StringUtils.isBlank(fileSuffix) ? null : ContentTypeMapMrg.CONTENT_TYPE_MAP.get(fileSuffix);
UploadObjectArgs.Builder builder = UploadObjectArgs.builder()
.bucket(bucketName).object(objectName).filename(filePath).contentType(contentType);
if (StringUtils.isNotBlank(contentType)) {
builder.contentType(contentType);
}
return minioClient.uploadObject(builder.build());
}
/**
* 上传本地文件,上传时,同名的会覆盖
*
* @param bucketName 存储桶
* @param objectName 对象名称
* @param filePath 本地文件路径
* @param contentType 上下文类型,如:video/mp4,(如果不传递则默认为“application/octet-stream”,在获取文件外链时,获取到的会是二进制流)
*/
public static ObjectWriteResponse uploadObjectByContentType(String bucketName, String objectName, String filePath, String contentType) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
UploadObjectArgs.Builder builder = UploadObjectArgs.builder()
.bucket(bucketName).object(objectName).filename(filePath).contentType(contentType);
if (StringUtils.isNotBlank(contentType)) {
builder.contentType(contentType);
}
return minioClient.uploadObject(builder.build());
}
/**
* 创建文件夹或目录
*
* @param bucketName 存储桶
* @param folder 目录路径,需要以'/'结尾
*/
public static ObjectWriteResponse putDirObject(String bucketName, String folder) throws Exception {
return minioClient.putObject(
PutObjectArgs.builder().bucket(bucketName).object(folder).stream(
new ByteArrayInputStream(new byte[]{
}), 0, -1)
.build());
}
/**
* 获取文件信息, 如果抛出异常则说明文件不存在
*
* @param bucketName bucket名称
* @param objectName 文件名称
*/
public static ObjectStat statObject(String bucketName, String objectName) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
}
/**
* 拷贝文件
*
* @param sourceBucketName 资源bucket名称
* @param sourceObjectName 资源文件名称
* @param targetBucketName 目标bucket名称
* @param targetObjectName 目标文件名称
*/
public static ObjectWriteResponse copyObject(String sourceBucketName, String sourceObjectName,
String targetBucketName, String targetObjectName) throws Exception {
return minioClient.copyObject(
CopyObjectArgs.builder()
.source(CopySource.builder().bucket(sourceBucketName).object(sourceObjectName).build())
.bucket(targetBucketName)
.object(targetObjectName)
.build());
}
/**
* 将对象的数据下载到文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param fileName 文件下载目录 + 文件名称
* @throws Exception
*/
public static void downloadObject(String bucketName, String objectName, String fileName) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
//如果目录不存在则创建目录
String dir = fileName.replace("\\", "/");
dir = dir.substring(0, dir.lastIndexOf("/"));
File dirFile = new File(dir);
if (!dirFile.exists()) {
boolean mkdirs = dirFile.mkdirs();
}
minioClient.downloadObject(
DownloadObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.filename(fileName)
.build());
}
/**
* 删除文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
*/
public static void removeObject(String bucketName, String objectName) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
}
/**
* 批量删除文件
*
* @param bucketName bucket
* @param objects 需要删除的文件列表
* @return
*/
public static void removeObjects(String bucketName, List<DeleteObject> objects) {
try {
Iterable<Result<DeleteError>> results =
minioClient.removeObjects(
RemoveObjectsArgs.builder().bucket(bucketName).objects(objects).build());
for (Result<DeleteError> result : results) {
DeleteError error = result.get();
log.error("Error in deleting object " + error.objectName() + "; " + error.message());
}
} catch (Exception e) {
log.error("Exception in deleting object:" + e.getMessage(), e);
}
}
/*操作Presigned*/
/**
* 获取文件外链
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param expires 过期时间
* @param timeUnit 过期时间单位
* @param method http请求方式
* @param reqParams http请求参数
* @return
* @throws Exception
*/
public static String getPresignedObjectUrl(String bucketName, String objectName, Integer expires,
TimeUnit timeUnit, Method method, Map<String, String> reqParams) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
GetPresignedObjectUrlArgs.Builder args = GetPresignedObjectUrlArgs.builder()
.method(method)
.bucket(bucketName)
.object(objectName);
if (expires != null && expires > 0 && timeUnit != null) {
args.expiry(expires, timeUnit);
}
if (reqParams != null && reqParams.size() > 0) {
args.extraQueryParams(reqParams);
}
return minioClient.getPresignedObjectUrl(args.build());
}
/**
* 给presigned URL设置策略
*
* @param bucketName 存储桶
* @param objectName 对象名
* @param expires 过期策略
* @param contentType 上下文类型,如:video/mp4,(如果不传递则默认为“application/octet-stream”,在获取文件外链时,获取到的会是二进制流)
* @return map
*/
public static Map<String, String> presignedGetObject(String bucketName, String objectName,
Integer expires, String contentType) throws Exception {
//重新构建objectName
objectName = buildObjectName(objectName);
PostPolicy policy = new PostPolicy(bucketName, objectName,
ZonedDateTime.now().plusDays(expires));
if (StringUtils.isNotBlank(contentType)) {
policy.setContentType(contentType);
}
return minioClient.presignedPostPolicy(policy);
}
/**
* 将URLDecoder编码转成UTF8
*
* @param str
* @return
* @throws UnsupportedEncodingException
*/
public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {
String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
return URLDecoder.decode(url, "UTF-8");
}
/**
* 对文件路径进行重构
*
* @param filePath
* @return
*/
private static String buildFilePath(String filePath) {
//判断是否是以盘符开头,例如:C:/
String regex = "[a-zA-Z]+:/";
if (filePath.matches(regex)) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(filePath);
while (matcher.find()) {
//去除盘符
filePath = filePath.replace(matcher.group(), "");
}
} else if (filePath.startsWith("/")) {
//去除第一个"/"
filePath = filePath.substring(1);
}
return filePath;
}
/**
* 重新构建objectName
*
* @param objectName
*/
private static String buildObjectName(String objectName) {
if (StringUtils.isBlank(objectName)) {
return objectName;
}
//去除开头的/
objectName = objectName.startsWith("/") ? objectName.substring(1) : objectName;
//去除?后边的参数
objectName = objectName.contains("?") ? objectName.substring(0, objectName.indexOf("?")) : objectName;
return objectName;
}
/**
* 传入文件访问外链,返回objectName
*
* @param url
* @return
*/
public static String getObjectNameByUrl(String url) {
if (StringUtils.isBlank(url)) {
return url;
}
if (url.contains(getBasisUrl())) {
// 去除minio基础路径
url = url.replace(getBasisUrl(), "");
// 去除?后边的参数
url = url.contains("?") ? url.substring(0, url.indexOf("?")) : url;
}
return url;
}
}