회원 정보 수정에서 썸네일 업로드가 필요했습니다.
파일을 Gloud에 저장하여 업로드 및 다운이 필요했기에 현재 사용하고 있는 Google Cloud Platform을 선택하였습니다.
적용하는데 발생한 이슈위주로 적는 글이라, 자세한 설정은 아래 블로그를 참조해주세요.
설정
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 요청은 다음과 같습니다.
- 실행 중간에 이 에러가 왜 뜨는지 잘 모르겠습니다.. 실행이 아예 멈추진 않았지만 찝찝하네요...
파일 다운로드 & 화면단 뷰어
공개액세스로 변경했다면
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
stackoverflow.com/questions/39820128/google-cloud-storage-image-public-link-to-img-src
'Tech > Spring' 카테고리의 다른 글
Spring Filter에서 request Body 가공하기 (0) | 2021.07.19 |
---|---|
단위 테스트를위한 ReflectionTestUtils (1) | 2021.03.23 |
Spring Boot에서 Actuator 및 Spring Actuator Admin 설정 방법 (0) | 2021.03.21 |
Google 소셜 로그인 Google API 클라이언트 라이브러리 + GoogleIdTokenVerifier 사용하는 방법 (4) | 2021.03.15 |
Spring Boot Validation 순서 정하기 & 테스트 코드 (4) | 2021.03.15 |