MinIO는 고성능 오픈소스 객체 저장소 시스템으로, Amazon S3 API와 호환됩니다. Java 애플리케이션에서 MinIO 공식 SDK인 MinIO Java SDK를 사용하여 MinIO 서비스를 조작할 수 있으며, 파일 업로드, 다운로드, 삭제, 객체 목록 조회 등 일반적인 기능을 수행할 수 있습니다.
- 의존성 추가 (Maven)
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.12</version> <!-- 최신 버전 사용 권장 -->
</dependency>
주의: MinIO Java SDK 8.x 버전부터 API는 OkHttp + Retrofit을 사용하며, 모든 메서드는 비동기 비블록 방식(
CompletableFuture반환)입니다. 단,.get()메서드나 동기 메서드를 통해 동기 호출도 가능합니다.
- MinIO 클라이언트 초기화
import io.minio.MinioClient;
MinioClient client = MinioClient.builder()
.endpoint("http://localhost:9000") // MinIO 서버 주소
.credentials("ACCESS_KEY", "SECRET_KEY") // 인증 키
.build();
HTTPS 사용 시, 인증서가 유효해야 하며 테스트 환경에서는 모든 인증서를 신뢰하도록 설정할 수 있습니다.
- 주요 작업 예제
1. 버킷 생성
boolean exists = client.bucketExists(BucketExistsArgs.builder().bucket("sample-bucket").build());
if (!exists) {
client.makeBucket(MakeBucketArgs.builder().bucket("sample-bucket").build());
}
2. 로컬 파일 업로드
client.uploadObject(
UploadObjectArgs.builder()
.bucket("sample-bucket")
.object("test.txt")
.filename("/path/to/file.txt")
.build()
);
3. InputStream으로 업로드 (웹 업로드용)
InputStream stream = new FileInputStream("/path/to/image.png");
client.putObject(
PutObjectArgs.builder()
.bucket("sample-bucket")
.object("image.png")
.stream(stream, stream.available(), -1)
.contentType("image/png")
.build()
);
stream.close();
주의:
-1은 크기 모름을 의미하며, MinIO는 자동으로 분할 업로드합니다. 크기가 알려진 경우 실제 바이트 수를 전달하여 성능 향상 가능.
4. 파일 다운로드
client.downloadObject(
DownloadObjectArgs.builder()
.bucket("sample-bucket")
.object("test.txt")
.filename("/tmp/downloaded.txt")
.build()
);
5. 객체를 InputStream으로 가져오기
InputStream stream = client.getObject(
GetObjectArgs.builder()
.bucket("sample-bucket")
.object("test.txt")
.build()
);
String content = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
stream.close();
6. 버킷 내 객체 목록 조회
ListObjectsArgs args = ListObjectsArgs.builder()
.bucket("sample-bucket")
.prefix("") // 선택적 접두사 필터
.recursive(true) // 하위 디렉토리 포함 여부
.build();
Iterable<Result<Item>> results = client.listObjects(args);
for (Result<Item> result : results) {
Item item = result.get();
System.out.println(item.objectName() + " (" + item.size() + " bytes)");
}
7. 객체 삭제
client.removeObject(
RemoveObjectArgs.builder()
.bucket("sample-bucket")
.object("test.txt")
.build()
);
8. 여러 객체 삭제 (배치 처리)
List<DeleteObject> items = Arrays.asList(
new DeleteObject("data1.txt"),
new DeleteObject("data2.txt")
);
Iterable<Result<DeleteError>> errors = client.removeObjects(
RemoveObjectsArgs.builder()
.bucket("sample-bucket")
.objects(items)
.build()
);
for (Result<DeleteError> error : errors) {
DeleteError err = error.get();
System.err.println("삭제 실패: " + err.objectName() + " - " + err.message());
}
9. 사전 서명 URL 생성
String url = client.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket("sample-bucket")
.object("secure-file.doc")
.expiry(60 * 60) // 1시간 유효
.build()
);
System.out.println("다운로드 링크: " + url);
- 예외 처리
MinIO SDK는 ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, IOException 등을 발생시킵니다.
일관된 처리를 위해 다음과 같이 예외를 잡는 것이 좋습니다:
try {
// MinIO 작업
} catch (ErrorResponseException e) {
System.err.println("서버 오류: " + e.errorResponse().message());
} catch (Exception e) {
e.printStackTrace();
}
- 전체 예제: 업로드 및 다운로드 링크 생성
import io.minio.*;
import io.minio.http.Method;
import java.nio.file.Paths;
public class MinioSample {
public static void main(String[] args) throws Exception {
MinioClient client = MinioClient.builder()
.endpoint("http://localhost:9000")
.credentials("minioadmin", "minioadmin")
.build();
String bucket = "storage-bucket";
String fileName = "sample.txt";
String filePath = "/tmp/sample.txt";
// 버킷 생성
if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build())) {
client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
}
// 파일 업로드
client.uploadObject(
UploadObjectArgs.builder()
.bucket(bucket)
.object(fileName)
.filename(filePath)
.build()
);
// 사전 서명 URL 생성
String url = client.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucket)
.object(fileName)
.expiry(3600)
.build()
);
System.out.println("파일 업로드 완료. 다운로드 링크: " + url);
}
}
- 주의사항
- 스레드 안전성:
MinioClient는 스레드 안전하며, 전역 싱글톤으로 사용 가능합니다. - 대용량 파일 업로드: SDK가 자동으로 멀티파트 업로드를 처리합니다.
- HTTPS 설정: 실제 환경에서는 HTTPS를 활성화하고 유효한 인증서를 사용해야 합니다.
- 권한 관리: 애플리케이션용 별도의 Access Key를 생성하고, MinIO의 IAM 정책을 통해 권한을 제한하는 것이 좋습니다.
- 버전 호환성: MinIO 서버와 Java SDK 버전을 최신으로 유지하여 호환성을 확보하세요.
추가 고급 기능(객체 메타데이터 설정, 라이프사이클 관리, 이벤트 알림 등)에 대해서는 공식 문서를 참고하세요: 👉 https://min.io/docs/minio/linux/developers/java/MinIO-Java-SDK.html