📌 Goole Cloud
https://cloud.google.com/?hl=ko
만들기 버튼 클릭합니다.
버킷 이름 지정을 입력하고 위치는 Region asia-northeast3(서울) 로 변경 후, 이 버킷에 공개 액세스 방지 적용 체크 해제합니다.
버킷이 잘 생성된걸 확인할 수 있습니다.
생성한 버킷을 선택 후, 권한으로 이동합니다.
Bucket의 모든 객체들을 모든 사용자들에게 공개된 상태로 변경하기 위해 다음과 같이 설정합니다.
5번 과정은 JSON key를 만들어, Spring Boot에서 JSON key를 이용해 storage에 접근하기 위한 설정입니다.
IAM 및 관리자 - 서비스 계정으로 이동합니다.
서비스 계정에 프로젝트에 대한 액세스 권한 부여에서 다음과 같이 역할을 추가해 줍니다.
추후에 Spring Boot 파일로 옮기기 위해 JSON 키 파일은 컴퓨터에 저장해둡니다.
// Google Cloud Platform Storage(GCP Storage)
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'
위에서 만든 JSON key file을 resources 폴더에 넣고, application.yml에 아래 코드를 추가해 줍니다.
spring:
cloud:
gcp:
storage:
credentials:
location: ${LOCATION}
project-id: ${PROJECT_ID}
bucket: ${BUCKET}
application.yml에 JSON key 파일의 경로를 적어주면 스프링 부트는 키 파일의 내용을 바탕으로 stroage 변수에 자동으로 의존성을 부여합니다.
location은 JSON 키의 경로, project-id는 JSON key 파일에 있는 project-id, bucket은 Cloud Storage 콘솔 들어가시면 나오는 버킷 이름입니다.
Storage 내에서 이름이 동일한 파일은 덮어쓰기가 되거나 저장되지 않기 때문에 파일명을 중복되지 않게 만들어줘야 하기 때문에 UUID를 사용하여 URL을 저장해 보겠습니다.
@Value("${spring.cloud.gcp.storage.credentials.location}")
private String keyFileName;
@Value("${spring.cloud.gcp.storage.bucket}")
private String bucketName;
public String exec(MultipartFile multipartFile) throws IOException {
InputStream keyFile = ResourceUtils.getURL(keyFileName).openStream();
String uuid = UUID.randomUUID().toString();
String ext = multipartFile.getContentType();
Storage storage = StorageOptions.newBuilder()
.setCredentials(GoogleCredentials.fromStream(keyFile))
.build()
.getService();
String imgUrl = "https://storage.googleapis.com/" + bucketName + "/" + uuid;
if (multipartFile.isEmpty()) {
imgUrl = null;
} else {
BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, uuid)
.setContentType(ext).build();
Blob blob = storage.create(blobInfo, multipartFile.getInputStream());
}
return imgUrl;
}
전체코드를 나눠서 보겠습니다.
Storage storage = StorageOptions.newBuilder()
.setCredentials(GoogleCredentials.fromStream(keyFile))
.build()
.getService();
이 코드가 구글 클라우드 스토리지 옵션과 제공된 인증 자격 증명을 사용하여 Storage 객체를 생성합니다.
String imgUrl = "https://storage.googleapis.com/" + bucketName + "/" + uuid;
if (multipartFile.isEmpty()) {
imgUrl = null;
} else {
BlobInfo blobInfo = BlobInfo.newBuilder(bucketName, uuid)
.setContentType(ext).build();
Blob blob = storage.create(blobInfo, multipartFile.getInputStream());
}
return imgUrl;
GCS 버킷 이름 및 생성된 고유 식별자를 사용하여 업로드된 이미지의 초기 URL을 구성합니다. 업로드된 파일이 비어있으면 imgUrl을 null로 설정합니다. 그렇지 않으면 파일을 storage.create 메소드를 사용하여 GCS에 업로드하는 로직으로 진행됩니다.
@Operation(summary = "Baby 등록")
@PostMapping("/baby")
public StateRes registerUser(@RequestPart BabyRegistReq babyRegistReq,
@RequestPart MultipartFile multipartFile) throws IOException {
return babyService.registerBaby(babyRegistReq, multipartFile);
}
Baby 등록 정보와 업로드된 파일을 받아 서비스 계층으로 전달하는 코드입니다. 여기서 주의 할 점은 매개변수를 받을 때, @RequestBody가 아닌 @RequestPart을 사용한다는 점입니다.
Postman을 활용해서 다음과 같이 요청을 보냈을 때, 오류 없이 응답이 오는 것을 확인할 수 있습니다.
DTO의 Content-Type을 application/json으로 변경해 주셔야 합니다.
또한 사진이 버킷에도 잘 들어간 것과 해당 url로 접속 시 사진이 잘 나오는 것을 확인할 수 있습니다.