https://fullmooney.tistory.com/74
minio multipart test
springboot 앱에서 minio bucket에 multipart file 업로드와 다운로드를 해보자먼저 minio연결을 위한 디펜던시를 추가한다 io.minio minio 8.5.13 minio에 버킷과 access key를 생성해보자.먼저 버킷 생성이다.용량
fullmooney.tistory.com
지난번 컨피그가 windows에서 경로 권한문제로 잘 처리되지 않아
mac에서 다시 환경 구성하고 springboot 통해서 file up/download를 해보자.
컨트롤러 개발에 참고한 블로그이다.
https://terianp.tistory.com/201
Spring Boot Web Chatting : 스프링 부트로 실시간 화상 채팅 만들기(13) minIO 배포 & 파일업로드/다운로드
1. 시작하면서 1) 서버 정리 이번에는 좀 오래만에 프로젝트 일지를 쓰게되었습니다. 2023 회고록에서 언급했듯이 사실 최근에 제 프로젝트에 나름? 많은 일이 있었습니다. 특히 기존에 있던 opensta
terianp.tistory.com
컨트롤러를 작성해보자.
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidResponseException;
import io.minio.errors.ServerException;
import io.minio.errors.XmlParserException;
@RestController
@RequestMapping("/api/obj")
public class ObjectRestController {
private final MinioClient minioClient;
public ObjectRestController(MinioClient minioClient){
this.minioClient= minioClient;
}
@PostMapping(value="/file-upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Void> fileUpload(@RequestPart("file") MultipartFile file) {
try {
// 헤더 설정
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getOriginalFilename() + "\"");
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
PutObjectArgs args = PutObjectArgs.builder()
.bucket("multipart")
.object(Path.of(file.getOriginalFilename()).toString())
.stream(file.getInputStream(), file.getInputStream().available(), -1)
.contentType(file.getContentType())
.headers(header.toSingleValueMap())
.build();
minioClient.putObject(args);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error while fetching files in Minio", e.getCause());
}
return ResponseEntity.ok().build();
}
@PostMapping(value="/file-download")
public ResponseEntity<byte[]> fileDownload(@RequestBody String fileName) {
InputStream fileData = null;
byte[] bytes = null;
GetObjectArgs args = GetObjectArgs.builder()
.bucket("multipart")
.object(fileName)
.build();
try {
fileData = minioClient.getObject(args);
bytes = IOUtils.toByteArray(fileData);
} catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
| InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
| IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
httpHeaders.setContentDispositionFormData("attachment", fileName);
return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);
}
}
swagger를 추가하고 테스트해보자.
springboot 3.3.5 openapi 설정이다.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.6.0</version>
</dependency>
<!-- 생략 -->
</dependencies>
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.models.OpenAPI;
@OpenAPIDefinition(
info = @Info(title = "OpenAPI Swagger",
description = "API 명세서",
version = "v3"))
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI openAPI(){
return new OpenAPI();
}
}
이제 테스트해보자.
txt, 이미지파일, 200MB이상의 파일을 업로드 테스트해보았다.
1) 텍스트파일


정상 업로드되고 버켓에서도 조회가 된다.

이 파일을 버킷에서 삭제처리하고 다시 업로드하고 파일변경후 재업로드 하는등 몇번 처리해보니,
일단 파일명이 같아도 바로 올라가진다. 그리고 버킷설정대로 버저닝이 된다.
우측 메뉴바의 Display Object Versions를 눌러보면 다음과 같이 조회된다.

2) 이미지
이제 이미지를 올려본다.
우측의 Preview를 통해 미리보기가 가능하다.

3) 대용량
200MB이상의 비교적 큰 파일을 우선 첨부를 해보자.
Resolved [org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded] 를 볼수 있다.
application.yml에 spring.servlet.multipart.max-file-size와 max-request-size 설정을 추가한다.
spring:
application:
name: fullmooney-tistory-com
profiles:
active: local
devtools:
livereload:
port: 18090
enabled: true
servlet:
multipart:
max-file-size: 500MB
max-request-size: 500MB
다시 업로드하니 성공했다.

이제 다운로드를 받아본다.
swagger에서 파일명을 입력후 excute 하여 응답에 추가된 Download file 링크를 클릭한다.

파일을 열어보니 잘 받아졌다.
이제 백업에 사용해보자.
'CloudNative > Runtime' 카테고리의 다른 글
| minio multipart test (1) | 2024.11.17 |
|---|---|
| minio (0) | 2024.11.16 |