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

该文章详细介绍了如何在SpringBoot应用中集成Minio进行文件存储操作,包括创建Bucket、用户及权限设置、引入依赖、配置文件、配置类、工具类以及测试控制器。提供了上传、下载、列出文件对象和删除文件等基本功能。
摘要由CSDN通过智能技术生成

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文件引入

<dependency>
	<groupId>io.minio</groupId>
	<artifactId>minio</artifactId>
	<version>8.4.3</version>
</dependency>
<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>okhttp</artifactId>
	<version>4.10.0</version>
</dependency>
<dependency>
	<groupId>org.jetbrains.kotlin</groupId>
	<artifactId>kotlin-stdlib</artifactId>
	<version>1.8.10</version>
</dependency>

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<String> upload(MultipartFile[] multipartFile, String bucketName) {
		List<String> 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<byte []>
	 */
	public ResponseEntity<byte[]> download(String fileName, String bucketName) {
		ResponseEntity<byte[]> 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<byte[]>(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<ObjectItem> listObjects(String bucketName) {
		Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
		List<ObjectItem> objectItems = new ArrayList<>();
		try {

			for (Result<Item> 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<Result<DeleteError>> removeObjects(String bucketName, 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;
	}
	
	/**
     * 文件下载(适用于浏览器下载,方式二)
     * @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<String> upload(@ApiParam(name="attach", value="attach", required=true) @RequestPart("attach") MultipartFile file, String bucketName) {

		//在swagger测试,只能传单个文件
		List<String> names = minioUtil.upload(new MultipartFile[] {file}, bucketName);
		//List<String> names = minioUtil.upload(file, bucketName);
		
		return names;
	}
	
	@ApiOperation("下载文件(适用于浏览器下载)")
	@PostMapping(value="/download")
	public ResponseEntity<byte[]> 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<ObjectItem> listObjects(String bucketName) {
		return minioUtil.listObjects(bucketName);
	}
	
	@ApiOperation("批量删除文件对象")
	@PostMapping(value="/removeObjects")
	public Iterable<Result<DeleteError>> removeObjects(String bucketName, @RequestParam("fileNames") List<String> fileNames) {
		return minioUtil.removeObjects(bucketName, fileNames);
	}

}

8、测试
上传:

下载:

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

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

当将MinIO与Spring Boot集成时,您可以使用MinIO Java客户端库来与MinIO对象存储系统进行交互。以下是一些步骤可以帮助您开始整合: 1. 首先,您需要在Spring Boot项目的依赖项中添加MinIO Java客户端库。在您的`pom.xml`文件中添加以下依赖项: ```xml <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.0.6</version> </dependency> ``` 2. 创建一个配置类来配置MinIO连接和操作。在您的Spring Boot项目中创建一个名为`MinioConfig`的类,并添加以下代码: ```java @Configuration public class MinioConfig { @Value("${minio.accessKey}") private String accessKey; @Value("${minio.secretKey}") private String secretKey; @Value("${minio.endpoint}") private String endpoint; @Bean public MinioClient minioClient() { return MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); } } ``` 在上面的代码中,我们使用`@Value`注解从配置文件中获取MinIO的访问密钥、秘钥和端点信息,并创建一个`MinioClient` bean。 3. 在需要使用MinIO的地方注入`MinioClient`并进行操作。例如,如果您想上传文件到MinIO,可以创建一个服务类并注入`MinioClient`,然后编写上传文件的方法: ```java @Service public class MinioService { private final MinioClient minioClient; public MinioService(MinioClient minioClient) { this.minioClient = minioClient; } public void uploadFile(String bucketName, String objectName, String filePath) { try { minioClient.uploadObject(UploadObjectArgs.builder() .bucket(bucketName) .object(objectName) .filename(filePath) .build()); System.out.println("File uploaded successfully"); } catch (Exception e) { e.printStackTrace(); } } } ``` 在上面的代码中,我们通过注入的`MinioClient`对象调用`uploadObject`方法来上传文件。 这只是一个简单的示例,您可以根据您的需求进一步扩展和使用MinIO的其他功能。 请确保在`application.properties`或`application.yml`配置文件中提供正确的MinIO连接信息,例如: ``` minio.accessKey=your_access_key minio.secretKey=your_secret_key minio.endpoint=http://localhost:9000 ``` 这是一个基本的MinIO与Spring Boot集成示例。您可以根据您的具体需求和业务逻辑进行进一步的开发和调整。希望对您有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值