阅读量:0
前面已经在docker中部署了minio服务,那么该如何在Java代码中使用?
这篇说下minio在Java中的配置跟使用。
文章目录
一、导入minio依赖
这里还要导入lombok是因为在MinIOConfig类中使用了@Data注解,正常来说导入minio依赖就够了
<dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>7.1.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency>
二、添加配置
application.yml
这些配置都是在创建minio的docker容器的时候就已经定好的,按照自己的配置去改一改就可以了。需要自定义的就一个桶名称bucket
minio: # MinIO服务器地址 endpoint: http://192.168.200.128:9000 # MinIO服务器访问凭据 accessKey: minio secretKey: minio123 # MinIO桶名称 bucket: test # MinIO读取路径前缀 readPath: http://192.168.200.128:9000
MinIOConfig
通过读取配置创建minioClient对象
package com.ruoyi.minio.config; import com.ruoyi.minio.service.FileStorageService; import io.minio.MinioClient; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Data @Configuration @EnableConfigurationProperties({MinIOConfigProperties.class}) //当引入FileStorageService接口时 @ConditionalOnClass(FileStorageService.class) public class MinIOConfig { @Autowired private MinIOConfigProperties minIOConfigProperties; @Bean public MinioClient buildMinioClient() { return MinioClient .builder() .credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey()) .endpoint(minIOConfigProperties.getEndpoint()) .build(); } }
MinIOConfigProperties
package com.ruoyi.minio.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import java.io.Serializable; @Data @ConfigurationProperties(prefix = "minio") // 文件上传 配置前缀file.oss public class MinIOConfigProperties implements Serializable { private String accessKey; private String secretKey; private String bucket; private String endpoint; private String readPath; }
三、导入工具类
Service
package com.ruoyi.minio.service; import java.io.InputStream; public interface FileStorageService { /** * 上传图片文件 * @param prefix 文件前缀 * @param filename 文件名 * @param inputStream 文件流 * @return 文件全路径 */ public String uploadImgFile(String prefix, String filename,InputStream inputStream); /** * 上传html文件 * @param prefix 文件前缀 * @param filename 文件名 * @param inputStream 文件流 * @return 文件全路径 */ public String uploadHtmlFile(String prefix, String filename,InputStream inputStream); /** * 删除文件 * @param pathUrl 文件全路径 */ public void delete(String pathUrl); /** * 下载文件 * @param pathUrl 文件全路径 * @return * */ public byte[] downLoadFile(String pathUrl); }
ServiceImpl
package com.heima.file.service.impl; import com.heima.file.config.MinIOConfig; import com.heima.file.config.MinIOConfigProperties; import com.heima.file.service.FileStorageService; import io.minio.GetObjectArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveObjectArgs; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Import; import org.springframework.util.StringUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; @Slf4j @EnableConfigurationProperties(MinIOConfigProperties.class) @Import(MinIOConfig.class) public class MinIOFileStorageService implements FileStorageService { @Autowired private MinioClient minioClient; @Autowired private MinIOConfigProperties minIOConfigProperties; private final static String separator = "/"; /** * @param dirPath * @param filename yyyy/mm/dd/file.jpg * @return */ public String builderFilePath(String dirPath,String filename) { StringBuilder stringBuilder = new StringBuilder(50); if(!StringUtils.isEmpty(dirPath)){ stringBuilder.append(dirPath).append(separator); } SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); String todayStr = sdf.format(new Date()); stringBuilder.append(todayStr).append(separator); stringBuilder.append(filename); return stringBuilder.toString(); } /** * 上传图片文件 * @param prefix 文件前缀 * @param filename 文件名 * @param inputStream 文件流 * @return 文件全路径 */ @Override public String uploadImgFile(String prefix, String filename,InputStream inputStream) { String filePath = builderFilePath(prefix, filename); try { PutObjectArgs putObjectArgs = PutObjectArgs.builder() .object(filePath) .contentType("image/jpg") .bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1) .build(); minioClient.putObject(putObjectArgs); StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath()); urlPath.append(separator+minIOConfigProperties.getBucket()); urlPath.append(separator); urlPath.append(filePath); return urlPath.toString(); }catch (Exception ex){ log.error("minio put file error.",ex); throw new RuntimeException("上传文件失败"); } } /** * 上传html文件 * @param prefix 文件前缀 * @param filename 文件名 * @param inputStream 文件流 * @return 文件全路径 */ @Override public String uploadHtmlFile(String prefix, String filename,InputStream inputStream) { String filePath = builderFilePath(prefix, filename); try { PutObjectArgs putObjectArgs = PutObjectArgs.builder() .object(filePath) .contentType("text/html") .bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1) .build(); minioClient.putObject(putObjectArgs); StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath()); urlPath.append(separator+minIOConfigProperties.getBucket()); urlPath.append(separator); urlPath.append(filePath); return urlPath.toString(); }catch (Exception ex){ log.error("minio put file error.",ex); ex.printStackTrace(); throw new RuntimeException("上传文件失败"); } } /** * 删除文件 * @param pathUrl 文件全路径 */ @Override public void delete(String pathUrl) { String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/",""); int index = key.indexOf(separator); String bucket = key.substring(0,index); String filePath = key.substring(index+1); // 删除Objects RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build(); try { minioClient.removeObject(removeObjectArgs); } catch (Exception e) { log.error("minio remove file error. pathUrl:{}",pathUrl); e.printStackTrace(); } } /** * 下载文件 * @param pathUrl 文件全路径 * @return 文件流 * */ @Override public byte[] downLoadFile(String pathUrl) { String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/",""); int index = key.indexOf(separator); String bucket = key.substring(0,index); String filePath = key.substring(index+1); InputStream inputStream = null; try { inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build()); } catch (Exception e) { log.error("minio down file error. pathUrl:{}",pathUrl); e.printStackTrace(); } ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buff = new byte[100]; int rc = 0; while (true) { try { if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break; } catch (IOException e) { e.printStackTrace(); } byteArrayOutputStream.write(buff, 0, rc); } return byteArrayOutputStream.toByteArray(); } }
四、使用工具类上传文件并返回url
package com.ruoyi.web.controller.utils; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.minio.service.impl.MinIOFileStorageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @RestController @RequestMapping("/minio") public class MinioController { @Autowired MinIOFileStorageService minIOFileStorageService; @PostMapping("/fileupload") public AjaxResult minIo(MultipartFile multipartFile){ // 检查multipartFile是否为空 if (multipartFile == null || multipartFile.isEmpty()) { return AjaxResult.error("文件为空,无法处理。"); } try(InputStream inputStream = multipartFile.getInputStream()) { // 将MultipartFile转换为InputStream // 上传到MinIO服务器 // 这里的文件名可以生成随机的名称,防止重复 String url = minIOFileStorageService.uploadImgFile("testjpg", "test1.jpg", inputStream); return AjaxResult.success(url); } catch (IOException e) { // 处理异常,可能是getInputStream()失败 return AjaxResult.error("获取InputStream失败:" + e.getMessage()); } } }
上传成功后在浏览器中访问图片的url就可以看到图片了。
注意事项(问题解决):
如果出现下面这个问题,检查两个地方
1、桶的权限问题
这里必须是public
2、url路径问题
如果桶配置没问题那就一定是url路径不对,去代码中排查这个问题就可以了。
我这里出现这个问题是因为在配置文件的前缀中多配置了一级test,导致url路径不正确
# MinIO读取路径前缀 readPath: http://192.168.200.128:9000/test