1.引入maven包(注意jar包冲突)
<!--minio依赖开始--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version><exclusions><exclusion><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId></exclusion><exclusion><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></exclusion><exclusion><groupId>com.google.guava</groupId><artifactId>guava</artifactId></exclusion></exclusions></dependency><!--minio依赖结束--><!--需要依赖的其他包-->
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.0</version>
</dependency>
2.测试类(建新桶一定赋权)
package com.example.demo;import io.minio.*;
import io.minio.errors.MinioException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;public class JavaMinIOUtil {public static void main(String[] args)throws IOException, NoSuchAlgorithmException, InvalidKeyException {try {// Create a minioClient with the MinIO server playground, its access key and secret key.MinioClient minioClient =MinioClient.builder().endpoint("地址").credentials("用户名", "密码").build();// Make 'asiatrip' bucket if not exist.boolean found =minioClient.bucketExists(BucketExistsArgs.builder().bucket("group1").build());if (!found) {// Make a new bucket called 'asiatrip'.minioClient.makeBucket(MakeBucketArgs.builder().bucket("group1").build());minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket("group1").config("这里是赋权").build());} else {System.out.println("Bucket 'asiatrip' already exists.");}// Upload '/home/user/Photos/asiaphotos.zip' as object name 'asiaphotos-2015.zip' to bucket// 'asiatrip'.minioClient.uploadObject(UploadObjectArgs.builder().bucket("group1").object("test/bm.jpg").filename("C:\\img\\苞米.jpg").build());} catch (MinioException e) {System.out.println("Error occurred: " + e);System.out.println("HTTP trace: " + e.httpTrace());}}}
3.工具类
package com.neixunbao.platform.minio;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.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;import static com.neixunbao.platform.image.util.FileUtil.readInputStream;/*** 功能描述 文件服务器工具类** @author:* @date:*/
@Component
public class MinIOUtil {//MinIO的API请求地址private final static String ENDPOINT = "http://127.0.0.1:9090";//用户名private final static String USERNAME = "admin";//密码private final static String PASSWORD = "1111";//桶名称private final static String BUCKETNAME = "group1";//回显路径public final static String BASEURL = "http://127.0.0.1:9090/group1/";//单例加载private final static MinioClient minioClient = MinioClient.builder().endpoint(ENDPOINT).credentials(USERNAME, PASSWORD).build();/*** 查看存储bucket是否存在* @return boolean*/public Boolean bucketExists() {Boolean found;try {found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKETNAME).build());minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(BUCKETNAME).config("{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListBucketMultipartUploads\",\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Resource\":[\"arn:aws:s3:::group1\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::group1/*\"]}]}").build());} catch (Exception e) {//e.printStackTrace();return false;}return found;}/*** 创建存储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* @return Boolean*/public Boolean removeBucket(String bucketName) {try {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 获取全部bucket*/public List<Bucket> getAllBuckets() {try {return minioClient.listBuckets();} catch (Exception e) {e.printStackTrace();}return null;}/*** 文件上传* @param file 文件* @return Boolean*/public static String upload(MultipartFile file) {try {//MultipartFile转InputStreambyte [] byteArr=file.getBytes();InputStream inputStream = new ByteArrayInputStream(byteArr);//获取文件名称String filename = file.getOriginalFilename();String prefix = filename.substring(filename.lastIndexOf(".") + 1);//后缀//根据当前时间生成文件夹Calendar calendar = Calendar.getInstance();Date time = calendar.getTime();// 2. 格式化系统时间--- 这里的时间格式可以根据自己的需要进行改变SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");String buckfilename = format.format(time);String uuid= UUID.randomUUID().toString().replace("-","");//customer_YYYYMMDDHHMMString fileName = buckfilename+"/"+uuid+"."+prefix; //文件全路径PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(BUCKETNAME).object(fileName).stream(inputStream,file.getSize(),-1).contentType(file.getContentType()).build();//文件名称相同会覆盖minioClient.putObject(objectArgs);return fileName;} catch (Exception e) {e.printStackTrace();}return "";}/*** 上传文件---直接传file** @return*/public static String upload(byte data[],String fileName) {
// File file = byte2File(data,"D:\\lsfile",fileName);try {
// MultipartFile multipartFile = getMultipartFile(file);
// byte [] byteArr=multipartFile.getBytes();InputStream inputStream = new ByteArrayInputStream(data);//获取文件名称String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);//后缀//根据当前时间生成文件夹Calendar calendar = Calendar.getInstance();Date time = calendar.getTime();// 2. 格式化系统时间--- 这里的时间格式可以根据自己的需要进行改变SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");String buckfilename = format.format(time);String uuid= UUID.randomUUID().toString().replace("-","");//customer_YYYYMMDDHHMMfileName = buckfilename+"/"+uuid+"."+prefix; //文件全路径PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(BUCKETNAME).object(fileName).stream(inputStream,data.length,-1).contentType("image/"+prefix).build();//文件名称相同会覆盖minioClient.putObject(objectArgs);return fileName;} catch (Exception e) {e.printStackTrace();} finally {}return "";}/*** 上传文件---直接传file** @return*/public static String upload(File file) {try {MultipartFile multipartFile = getMultipartFile(file);byte [] byteArr=multipartFile.getBytes();InputStream inputStream = new ByteArrayInputStream(byteArr);//获取文件名称String filename = multipartFile.getOriginalFilename();String prefix = filename.substring(filename.lastIndexOf(".") + 1);//后缀//根据当前时间生成文件夹Calendar calendar = Calendar.getInstance();Date time = calendar.getTime();// 2. 格式化系统时间--- 这里的时间格式可以根据自己的需要进行改变SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");String buckfilename = format.format(time);String uuid= UUID.randomUUID().toString().replace("-","");//customer_YYYYMMDDHHMMfilename = buckfilename+"/"+uuid+"."+prefix; //文件全路径PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(BUCKETNAME).object(filename).stream(inputStream,multipartFile.getSize(),-1).contentType(multipartFile.getContentType()).build();//文件名称相同会覆盖minioClient.putObject(objectArgs);return filename;} catch (Exception e) {e.printStackTrace();}return "";}/*** 预览图片* @param fileName* @return*/public String preview(String fileName){// 查看文件地址GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(BUCKETNAME).object(fileName).method(Method.GET).build();try {String url = minioClient.getPresignedObjectUrl(build);return url;} catch (Exception e) {e.printStackTrace();}return null;}/*** 文件下载* @param fileName 文件名称* @param res response* @return Boolean*/public void download(String fileName, HttpServletResponse res) {GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(BUCKETNAME).object(fileName).build();try (GetObjectResponse response = minioClient.getObject(objectArgs)){byte[] buf = new byte[1024];int len;try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){while ((len=response.read(buf))!=-1){os.write(buf,0,len);}os.flush();byte[] bytes = os.toByteArray();res.setCharacterEncoding("utf-8");//设置强制下载不打开//res.setContentType("application/force-download");res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);try (ServletOutputStream stream = res.getOutputStream()){stream.write(bytes);stream.flush();}}} catch (Exception e) {e.printStackTrace();}}/*** 查看文件对象* @return 存储bucket内文件对象信息*/public List<Item> listObjects() {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(BUCKETNAME).build());List<Item> items = new ArrayList<>();try {for (Result<Item> result : results) {items.add(result.get());}} catch (Exception e) {e.printStackTrace();return null;}return items;}/*** 删除* @param fileName* @return* @throws Exception*/public static boolean remove(String fileName){try {minioClient.removeObject( RemoveObjectArgs.builder().bucket(BUCKETNAME).object(fileName).build());}catch (Exception e){return false;}return true;}/*** 批量删除文件对象(没测试)* @param objects 对象名称集合*/public Iterable<Result<DeleteError>> removeObjects(List<String> objects) {List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(BUCKETNAME).objects(dos).build());return results;}public static void dfsdelete(String path) {File file=new File(path);if(file.isFile()) {//如果此file对象是文件的话,直接删除file.delete();return;}//当 file是文件夹的话,先得到文件夹下对应文件的string数组 ,递归调用本身,实现深度优先删除String [] list=file.list();for (int i = 0; i < list.length; i++) {dfsdelete(path+File.separator+list[i]);}//当把文件夹内所有文件删完后,此文件夹已然是一个空文件夹,可以使用delete()直接删除file.delete();return;}/*** 得到文件流* @param url 网络图片URL地址* @return*/public static byte[] getFileStream(String url){try {URL httpUrl = new URL(url);HttpURLConnection conn = (HttpURLConnection)httpUrl.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5 * 1000);InputStream inStream = conn.getInputStream();//通过输入流获取图片数据byte[] btImg = readInputStream(inStream);//得到图片的二进制数据return btImg;} catch (Exception e) {e.printStackTrace();}return null;}/*** 从输入流中获取数据* @param inStream 输入流* @return* @throws Exception*/public static byte[] readInputStream(InputStream inStream) throws Exception{ByteArrayOutputStream outStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;while( (len=inStream.read(buffer)) != -1 ){outStream.write(buffer, 0, len);}inStream.close();return outStream.toByteArray();}/*** file转byte*/public static byte[] file2byte(File file){byte[] buffer = null;try{FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream bos = new ByteArrayOutputStream();byte[] b = new byte[1024];int n;while ((n = fis.read(b)) != -1){bos.write(b, 0, n);}fis.close();bos.close();buffer = bos.toByteArray();}catch (FileNotFoundException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}return buffer;}/*** byte 转file*/public static File byte2File(byte[] buf, String filePath, String fileName){BufferedOutputStream bos = null;FileOutputStream fos = null;File file = null;try{File dir = new File(filePath);if (!dir.exists() && dir.isDirectory()){dir.mkdirs();}file = new File(filePath + File.separator + fileName);fos = new FileOutputStream(file);bos = new BufferedOutputStream(fos);bos.write(buf);}catch (Exception e){e.printStackTrace();}finally{if (bos != null){try{bos.close();}catch (IOException e){e.printStackTrace();}}if (fos != null){try{fos.close();}catch (IOException e){e.printStackTrace();}}}return file;}/*** multipartFile转File**/public static File multipartFile2File(MultipartFile multipartFile){File file = null;if (multipartFile != null){try {file=File.createTempFile("tmp", null);multipartFile.transferTo(file);System.gc();file.deleteOnExit();}catch (Exception e){e.printStackTrace();}}return file;}/*** File转multipartFile**/public static MultipartFile getMultipartFile(File file) {DiskFileItem item = new DiskFileItem("file", MediaType.MULTIPART_FORM_DATA_VALUE, true, file.getName(), (int)file.length(), file.getParentFile());try {OutputStream os = item.getOutputStream();os.write(FileUtils.readFileToByteArray(file));} catch (IOException e) {e.printStackTrace();}return new CommonsMultipartFile(item);}// //上传文件,返回路径
// public Object upload(HashMap<String, Object> paramMap) {
// MultipartFile file=(MultipartFile)paramMap.get("file");
// if (file.isEmpty() || file.getSize() == 0) {
// return "文件为空";
// }
// try {
// if (!this.bucketExists()) {
// this.makeBucket("group1");
// }
// InputStream inputStream = file.getInputStream();
// String fileName = file.getOriginalFilename();
//
// String newName = UUID.randomUUID().toString().replaceAll("-", "")
// + fileName.substring(fileName.lastIndexOf("."));
//
// this.upload( newName,file, inputStream);
// inputStream.close();
// String fileUrl = this.preview(newName);
// String fileUrlNew=fileUrl.substring(0, fileUrl.indexOf("?"));
// JSONObject jsonObject=new JSONObject();
// jsonObject.put("url",fileUrlNew);
// return jsonObject.toJSONString();
// } catch (Exception e) {
// e.printStackTrace();
// return "上传失败";
// }
// }
}