minio springboot file up/download

2024. 11. 19. 11:25·CloudNative/Runtime

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 링크를 클릭한다.

 

파일을 열어보니 잘 받아졌다.

 

이제 백업에 사용해보자.

728x90

'CloudNative > Runtime' 카테고리의 다른 글

minio multipart test  (1) 2024.11.17
minio  (0) 2024.11.16
'CloudNative/Runtime' 카테고리의 다른 글
  • minio multipart test
  • minio
yunapapa
yunapapa
working on the cloud
    250x250
  • yunapapa
    supermoon
    yunapapa
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • 개발 (20)
        • java (17)
        • web (2)
        • MSX (1)
        • Go (0)
      • CloudNative (50)
        • App Definition & Developeme.. (17)
        • Orchestration & Management (4)
        • Runtime (3)
        • Provisioning (7)
        • Observability & Analysis (14)
        • event review (5)
      • AWS (7)
      • 환경관련 (17)
      • 취미생활 (0)
        • 맛집 (0)
        • 게임 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • CNCF Past Events
    • Kubernetes Korea Group
  • 공지사항

  • 인기 글

  • 태그

    dop-c02
    istio
    kubernetes
    APM
    Pinpoint
    gitlab
    Java
    k8s
    OpenShift
    티스토리챌린지
    AWS
    devops
    helm
    오블완
    springboot
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
yunapapa
minio springboot file up/download
상단으로

티스토리툴바