在Docker中运行Minio
minio需要一个稳定的运行环境,测试的时候我们可以再docker中运行一个简单的实例,📢注意这个例子并没有映射任何volume,所以停止container的时候数据也会销毁
1 2 3 4 5 6
| docker run \ -p 9000:9000 \ -p 9001:9001 \ -e "MINIO_ROOT_USER=<USERNAME>" \ -e "MINIO_ROOT_PASSWORD=<PASSWORD>" \ quay.io/minio/minio server /data --console-address ":9001"
|
集成到Spring boot中
在Spring boot中的pom.xml增加依赖
这里用的maven
1 2 3 4 5
| <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.3.0</version> </dependency>
|
在application.properties中增加相关配置项,相关配置修改为自己的
1 2 3 4 5 6 7 8
| server.port=8080 spring.servlet.multipart.max-file-size=2MB
minio.bucket.name=minio-example-demo minio.access.key=minioadmin minio.access.secret=minioadmin minio.url=https://play.min.io
|
配置Bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Configuration public class MinioConfiguration {
@Value("${minio.access.key}") private String accessKey;
@Value("${minio.access.secret}") private String secretKey;
@Value("${minio.url}") private String minioUrl;
@Bean @Primary public MinioClient minioClient() { return new MinioClient.Builder() .credentials(accessKey, secretKey) .endpoint(minioUrl) .build(); }
}
|
DTO,用来传输数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Data @Builder @NoArgsConstructor @AllArgsConstructor @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) @JsonInclude(JsonInclude.Include.NON_NULL) public class FileDto implements Serializable {
private static final long serialVersionUID = 232836038145089522L;
private String title;
private String description;
@SuppressWarnings("java:S1948") private MultipartFile file;
private String url;
private Long size;
private String filename;
}
|
获取文件列表
创建MinioService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @Slf4j @Service public class MinioService {
@Autowired private MinioClient minioClient;
@Value("${minio.bucket.name}") private String bucketName;
public List<FileDto> getListObjects() { List<FileDto> objects = new ArrayList<>(); try { Iterable<Result<Item>> result = minioClient.listObjects(ListObjectsArgs.builder() .bucket(bucketName) .recursive(true) .build()); for (Result<Item> item : result) { objects.add(FileDto.builder() .filename(item.get().objectName()) .size(item.get().size()) .url(getPreSignedUrl(item.get().objectName())) .build()); } return objects; } catch (Exception e) { log.error("Happened error when get list objects from minio: ", e); }
return objects; }
private String getPreSignedUrl(String filename) { return "http://localhost:8080/file/".concat(filename); }
}
|
创建Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Slf4j @RestController @RequestMapping(value = "/file") public class FileController {
@Autowired private MinioService minioService;
@GetMapping public ResponseEntity<Object> getFiles() { return ResponseEntity.ok(minioService.getListObjects()); }
}
|
上传文件到minio
下面代码是添加到MinioService中的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public FileDto uploadFile(FileDto request) { try { minioClient.putObject(PutObjectArgs.builder() .bucket(bucketName) .object(request.getFile().getOriginalFilename()) .stream(request.getFile().getInputStream(), request.getFile().getSize(), -1) .build()); } catch (Exception e) { log.error("Happened error when upload file: ", e); } return FileDto.builder() .title(request.getTitle()) .description(request.getDescription()) .size(request.getFile().getSize()) .url(getPreSignedUrl(request.getFile().getOriginalFilename())) .filename(request.getFile().getOriginalFilename()) .build(); }
|
对应的Controller
1 2 3 4
| @PostMapping(value = "/upload") public ResponseEntity<Object> upload(@ModelAttribute FileDto request) { return ResponseEntity.ok().body(minioService.uploadFile(request)); }
|
下载文件
添加到MinioService
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public InputStream getObject(String filename) { InputStream stream; try { stream = minioClient.getObject(GetObjectArgs.builder() .bucket(bucketName) .object(filename) .build()); } catch (Exception e) { log.error("Happened error when get list objects from minio: ", e); return null; }
return stream; }
|
Controller
1 2 3 4 5 6 7 8
| @GetMapping(value = "/**") public ResponseEntity<Object> getFile(HttpServletRequest request) throws IOException { String pattern = (String) request.getAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE); String filename = new AntPathMatcher().extractPathWithinPattern(pattern, request.getServletPath()); return ResponseEntity.ok() .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(IOUtils.toByteArray(minioService.getObject(filename))); }
|
访问:http://localhost:8080/file/{filename},页面中会展示或者下载对应的文件
参考