Java基础之《minio(2)—springboot整合minio》

1、创建一个桶Bucket,名字叫test
Buckets - Create Bucket

2、创建一个访问用户
Identity - Users - Create User
(1)创建一个用户user001,12345678
(2)设置权限
consoleAdmin:控制台管理
diagnostics:诊断
readwrite:读写
(3)为用户设置Access Keys
Access Key:VsKN1asPH1l4iNiL
Secret Key:6tO8VuGDxZsSBXBiakrsm4rRCRTrvHBE

3、pom文件引入


	io.minio
	minio
	8.4.3


	com.squareup.okhttp3
	okhttp
	4.10.0


	org.jetbrains.kotlin
	kotlin-stdlib
	1.8.10

minio依赖okhttp和kotlin,springboot自带依赖版本可能比较老。
引用jar包的工具类网上找一个参考参考。

4、application.yml文件添加

#minio配置
minio:
  url: http://192.168.3.203:9998
  access-key: VsKN1asPH1l4iNiL
  secret-key: 6tO8VuGDxZsSBXBiakrsm4rRCRTrvHBE
  bucket-name: test

#设置文件上传大小
spring:
    servlet:
      multipart:
        max-file-size: 50MB
        max-request-size: 50MB

5、minio配置类
MinioClientConfig.java

package com.example.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.minio.MinioClient;

@Configuration
public class MinioClientConfig {
	
	@Value("${minio.url}")
	private String url;
	
	@Value("${minio.access-key}")
	private String accessKey;
	
	@Value("${minio.secret-key}")
	private String secretKey;

	/**
	 * 注入minio客户端
	 */
	@Bean
	public MinioClient minioClient() {

		return MinioClient.builder()
				.endpoint(url)
				.credentials(accessKey, secretKey)
				.build();
	}
}

ObjectItem.java

package com.example.domain;

import lombok.Data;

/**
 * minio文件对象的实体类
 */
@Data
public class ObjectItem {

	private String objectName;
	
    private Long size;
}

6、minio工具类
MinioUtil.java

package com.example.utils;

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;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
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.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;

import com.example.domain.ObjectItem;

import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.GetObjectResponse;
import io.minio.ListObjectsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveBucketArgs;
import io.minio.RemoveObjectsArgs;
import io.minio.Result;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;

@Component
public class MinioUtil {

	@Autowired
	private MinioClient minioClient;

	/**
	 * 判断bucket是否存在
	 */
	public boolean existBucket(String bucketName) {
		try {
			boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());

			return exists;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return false;
	}

	/**
	 * 创建存储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 List upload(MultipartFile[] multipartFile, String bucketName) {
		List 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;
	}

	/**
	 * 下载文件(适用于浏览器下载)
	 *
	 * @param fileName
	 * @return : org.springframework.http.ResponseEntity
	 */
	public ResponseEntity download(String fileName, String bucketName) {
		ResponseEntity 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();
			}
			headers.setContentLength(bytes.length);
			headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			headers.setAccessControlExposeHeaders(Arrays.asList("*"));
			responseEntity = new ResponseEntity(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 List listObjects(String bucketName) {
		Iterable> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
		List objectItems = new ArrayList<>();
		try {

			for (Result 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 Iterable> removeObjects(String bucketName, List objects) {
		List dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
		Iterable> results = minioClient
				.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());

		return results;
	}
	
	/**
     * 文件下载(适用于浏览器下载,方式二)
     * @param fileName 文件名称
     * @param bucketName 桶名称
     * @param res response
     * @return 
     */
    public void download(String fileName, String bucketName, 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.setContentLength(bytes.length);
                res.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
                //告示浏览器文件的打开方式是下载
                res.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "utf-8"));
                try (ServletOutputStream stream = res.getOutputStream()) {
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

7、minio测试类
MinioController.java

package com.example.web;

import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.example.domain.ObjectItem;
import com.example.utils.MinioUtil;

import io.minio.Result;
import io.minio.messages.DeleteError;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Api(description = "minio测试接口")
@RestController
@RequestMapping("/minio")
public class MinioController {

	@Autowired
	private MinioUtil minioUtil;

	@Value("${minio.url}")
	private String address;

//	@Value("${minio.bucket-name}")
//	private String bucketName;
	
	@ApiOperation("判断bucket是否存在")
	@PostMapping(value="/existBucket")
	public boolean existBucket(String bucketName) {
		return minioUtil.existBucket(bucketName);
	}
	
	@ApiOperation("创建存储bucket")
	@PostMapping(value="/makeBucket")
	public boolean makeBucket(String bucketName) {
		return minioUtil.makeBucket(bucketName);
	}
	
	@ApiOperation("删除存储bucket")
	@PostMapping(value="/removeBucket")
	public boolean removeBucket(String bucketName) {
		return minioUtil.removeBucket(bucketName);
	}

	@ApiOperation("上传文件(浏览器上传)")
	@PostMapping(value="/upload", headers="content-type=multipart/form-data")
	public List upload(@ApiParam(name="attach", value="attach", required=true) @RequestPart("attach") MultipartFile file, String bucketName) {

		//在swagger测试,只能传单个文件
		List names = minioUtil.upload(new MultipartFile[] {file}, bucketName);
		//List names = minioUtil.upload(file, bucketName);
		
		return names;
	}
	
	@ApiOperation("下载文件(适用于浏览器下载)")
	@PostMapping(value="/download")
	public ResponseEntity download(String fileName, String bucketName) {
		return minioUtil.download(fileName, bucketName);
	}
	
	@ApiOperation("下载文件(适用于浏览器下载,方式二)")
	@PostMapping(value="/download2")
	public void download2(String fileName, String bucketName, HttpServletResponse res) {
		minioUtil.download(fileName, bucketName, res);
	}
	
	@ApiOperation("查看bucket文件对象")
	@PostMapping(value="/listObjects")
	public List listObjects(String bucketName) {
		return minioUtil.listObjects(bucketName);
	}
	
	@ApiOperation("批量删除文件对象")
	@PostMapping(value="/removeObjects")
	public Iterable> removeObjects(String bucketName, @RequestParam("fileNames") List fileNames) {
		return minioUtil.removeObjects(bucketName, fileNames);
	}

}

8、测试
上传:
Java基础之《minio(2)—springboot整合minio》_第1张图片

下载:
Java基础之《minio(2)—springboot整合minio》_第2张图片

目前工具类只有浏览器上传、下载功能,没有接口上传下载功能,还要根据使用场景完善。

参考资料:
springboot整合minio_qianQueen的博客-CSDN博客
springboot整合minio分布式存储_kill-java的博客-CSDN博客

你可能感兴趣的:(JAVA基础,java,minio)