Springboot + GCP Cloud Storage 연동(파일 업로드, 다운로드)

2021. 3. 22. 21:42·Tech/Spring

회원 정보 수정에서 썸네일 업로드가 필요했습니다.

파일을 Gloud에 저장하여 업로드 및 다운이 필요했기에 현재 사용하고 있는 Google Cloud Platform을 선택하였습니다.

 

적용하는데 발생한 이슈위주로 적는 글이라, 자세한 설정은 아래 블로그를 참조해주세요.

jyami.tistory.com/54

 

GCP Cloud Storage + Springboot 연동하기

이번 외주를 맡은 내용이 Google Cloud Storage를 이용해서 file을 업로드, 다운로드하는 API 기능을 구현해서 이 내용을 정리하고자 한다. Cloud Storage를 다루는 방법으로 Google Cloud Console, Cloud SDK를..

jyami.tistory.com

설정

gradle 설정을 다음과 같이 했습니다.

dependencies {
    
    ...
    
    1.
    // implementation 'org.springframework.cloud:spring-cloud-gcp-starter'
    // implementation 'org.springframework.cloud:spring-cloud-gcp-starter-storage'
    
    2.
    // compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter'
    // compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-storage'
    
    3.
    // implementation group: 'com.google.cloud', name: 'google-cloud-storage', version: '1.111.2'
    // implementation group: 'com.google.cloud', name: 'spring-cloud-gcp-core', version: '2.0.1'
    // implementation group: 'com.google.cloud', name: 'spring-cloud-gcp-starter', version: '2.0.1'
    
    4.
    implementation group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter', version: '1.2.5.RELEASE'
    implementation group: 'org.springframework.cloud', name: 'spring-cloud-gcp-storage', version: '1.2.5.RELEASE'

   	...
}
  • 구글링으로 나온 1번 or 2번처럼 라이브러리를 추가해도 적용이 되지 않았습니다.
    • " import com.google.cloud.* "를 불러오질 못했습니다.
  • 결국, 수동으로 라이브러리를 찾아야 됬었는데, 3번의 시행착오 끝에 4번 형식의 라이브러리 적용 코드를 찾았습니다.
    • spring boot 2.3.7 버전을 사용했습니다. 혹시라도 의존성 충돌이 일어날까봐 2.3.X가 출시된 이후 나온 gcp-** 버전을 적용하였습니다.
    • maven repository에서 검색 후 적용하였습니다.

전체 라이브러리

 

spring:
  cloud:
    gcp:
      storage:
        credentials:
          location: classpath:{서비스 key파일 이름}.json
  • gradle에서 적용이 잘되었다면, application.yml에 위와같이 등록을 할 수 있습니다.
    • 만약, 밑줄이 뜨거나 자동완성으로 뜨지 않았다면 라이브러기가 정상적으로 등록이 되지 않은겁니다.
  • 이렇게하면 Spring Boot에서 자동으로 {서비스 key파일 이름}.json을 읽어 Storage에 자동으로 @Autowired를 해준다고 합니다. 하지만 왜 그런지 @Autowired가 되지 않아서 .json 파일또한 수동으로 설정을 해야 했습니다.

파일 업로드

// Controller
@PostMapping(value = "/{id}/upload")
    public ResponseEntity<?> uploadToStorage(
        @RequestBody UploadReqDto uploadReqDto
    ){

        BlobInfo blobInfo = userService.uploadFileToGCS(uploadReqDto);
        log.info("blobInfo : " + blobInfo);

        return ResponseEntity.status(HttpStatus.OK)
            .body(ResponseTemplate.create(
                "Gdc"
            ));
    }
    
    
// Dto
public static class  UploadReqDto {
    private String bucketName;
    private String uploadFileName;
    private String localFileLocation;
}
  • Controller / Dto 코드 입니다.
    public BlobInfo uploadFileToGCS(UploadReqDto uploadReqDto){
        try{
            String keyFileName = ".json 파일명";
            InputStream keyFile = ResourceUtils.getURL("classpath:" + keyFileName).openStream();

            Storage storage = StorageOptions.newBuilder().setProjectId("nosell")
               // Key 파일 수동 등록
               .setCredentials(GoogleCredentials.fromStream(keyFile))
               .build().getService();

            BlobId blobId = BlobId.of(uploadReqDto.getBucketName(), uploadReqDto.getUploadFileName());
            BlobInfo blobInfo = BlobInfo.newBuilder(blobId)
                .setAcl(new ArrayList<>(Arrays.asList(Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER))))
                .build();
                
            Blob blob = storage
                .create(blobInfo, new FileInputStream(uploadReqDto.getLocalFileLocation()));
                
            return blob;
        }catch(IOException e){
            log.error(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }
  • resources 폴더 바로 밑에 있는 .json 파일의 경로를 가져온 뒤 key 파일을 수동으로 등록하였습니다.
  • 암호화 하지 않는 storage.create() 메소드는 google-cloud-storage.1.111.2 에서(1.111.2 부터인지는 모르겠습니다) deprecated() 되었습니다. 일단 작동은 잘되니 추후 수정해야겠습니다.

 

 

  • 루트 바로 밑에있는 upload폴더에 존재하는 파일을 스토리지에 올리는 방식입니다.
  • 향후, 클라이언트에서 등록한 파일을 바로 스토리지에 올리는 방식이 존재하는지 찾아봐야겠군요.

 

  • PostMan 요청은 다음과 같습니다.

 

 

  • 실행 중간에 이 에러가 왜 뜨는지 잘 모르겠습니다.. 실행이 아예 멈추진 않았지만 찝찝하네요...

 

파일 다운로드 & 화면단 뷰어

jsikim1.tistory.com/27

 

Google Cloud Storage Bucket 개체 공개 액세스 변경 (allUsers 뷰어 권한 부여)

Google Cloud Storage Bucket 개체 공개 액세스 변경 (allUsers 뷰어 권한 부여) Google Data Studio의 Community Visualizations 을 직접 만들어 사용하거나 공개하고 싶을때와 같이 Google Cloud Pl..

jsikim1.tistory.com

공개액세스로 변경했다면

https://storage.googleapis.com/{Bucket Name}/{파일경로}/{파일명}.확장자 

로 다운로드 할 수 있습니다.

 

화면단에서 보여줄라면 img 태그의 src에 링크만 넣어주면 된다.

  <img src={image_url} alt=""/>

 

참조

www.programcreek.com/java-api-examples/?class=com.google.cloud.storage.BlobInfo&method=getMediaLink

mingpd.github.io/2019/03/12/develop/java-google-api/

docs.spring.io/spring-cloud-gcp/docs/1.2.6.RELEASE/reference/html/#spring-cloud-gcp-core

cloud.google.com/storage/docs/uploading-objects?hl=ko#storage-upload-object-java

stackoverflow.com/questions/41880371/com-google-cloud-storage-storageexception-401-unauthorized

r4bb1t.tistory.com/29

stackoverflow.com/questions/39820128/google-cloud-storage-image-public-link-to-img-src

 

저작자표시 (새창열림)

'Tech > Spring' 카테고리의 다른 글

Spring Filter에서 request Body 가공하기  (1) 2021.07.19
단위 테스트를위한 ReflectionTestUtils  (1) 2021.03.23
Spring Boot에서 Actuator 및 Spring Actuator Admin 설정 방법  (0) 2021.03.21
Google 소셜 로그인 Google API 클라이언트 라이브러리 + GoogleIdTokenVerifier 사용하는 방법  (5) 2021.03.15
Spring Boot Validation 순서 정하기 & 테스트 코드  (5) 2021.03.15
'Tech/Spring' 카테고리의 다른 글
  • Spring Filter에서 request Body 가공하기
  • 단위 테스트를위한 ReflectionTestUtils
  • Spring Boot에서 Actuator 및 Spring Actuator Admin 설정 방법
  • Google 소셜 로그인 Google API 클라이언트 라이브러리 + GoogleIdTokenVerifier 사용하는 방법
소프
소프
  • 소프
    기회는 찬스
    소프
  • 전체
    오늘
    어제
    • 분류 전체보기 (138)
      • Language (20)
        • Java (19)
        • Design Pattern (1)
      • Tech (27)
        • Spring (19)
        • JPA (3)
        • QueryDSL (1)
        • Gradle (4)
      • 개발 생각 (1)
      • IT Book (0)
        • 자바_스프링 개발자를 위한 실용주의 프로그래밍 (0)
      • Database (4)
        • Mysql (4)
        • Redis (0)
      • 네트워크 (1)
      • 운영체제 (2)
      • IDE (12)
        • Intellij (9)
        • vscode (2)
        • datagrip (1)
      • 인프라 (11)
        • Docker (2)
        • Jenkins (7)
        • Github Actions (1)
        • GCP (1)
      • 형상관리 (2)
        • gitlab (2)
        • git (0)
      • 외부활동 (44)
        • CS 면접 끝장내기 - 데이터베이스 1기 (5)
        • CS 면접 끝장내기 - 컴퓨터 네트워크 2기 (5)
        • CS 면접 끝장내기 - 자바 2기 (0)
        • TDD, 클린 코드 with Java 17기 (7)
        • ATDD, 클린 코드 with Spring 8기 (6)
        • 루퍼스 2기 (21)
      • 프로젝트 (0)
      • 회고 (6)
      • 기타 (1)
        • 제미니의 개발 실무 (0)
  • 블로그 메뉴

    • 홈
    • Github
    • LinkedIn
    • 방명록
  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.6
소프
Springboot + GCP Cloud Storage 연동(파일 업로드, 다운로드)
상단으로

티스토리툴바