이 스크립트 파일은 1) App Engine 애플리케이션을 생성 2) GCLOUD_PROJECT 환경 변수를 내보냄 3) mvn clean install을 Run 4) Google Cloud Platform 프로젝트 ID를 출력
애플리케이션 실행
mvn spring-boot:run
웹 미리보기 - 포트 8080에서 미리보기를 클릭 해 아주 흥미로운 퀴즈 확인
도구 모음에서 질문 만들기를 클릭해 양식 확인
퀴즈 애플리케이션 코드 검사
Cloud Shell 텍스트 편집기 실행
편집기 왼쪽에 있는 파일 브라우저 패널을 사용하여 폴더 /cloudstorage/start 로 이동해 Spring Boot 웹 애플리케이션 검토 1) new_question.html : 질문 만들기 양식에 대한 Thyme 템플릿이 포함 2) QuesetionController.java : POST 처리기가 이미지 서비스에서 메서드를 호출 3) ImageService.java : Cloud Storage에 이미지 파일 데이터를 저장하는 코드를 작성하는 파일
Cloud Storage 버킷 생성
Ctrl + C를 눌러 애플리케이션 중지
버킷 이름을 전달하며 Cloud Storage 버킷 생성
gsutil mb gs://$DEVSHELL_PROJECT_ID-media
Cloud Storage 버킷 이름을 GCLOUD_BUCKET이라는 환경 변수로 내보냄 +) 응용 프로그램을 구성을 위해 환경 변수를 사용하므로 버킷 이름을 환경 변수로 내보낸 것이며 개발 팀은 변수를 변경하는 것만으로 애플리케이션을 개발, 테스트, 스테이징 및 프로덕션을 배포할 수 있음
export GCLOUD_BUCKET=$DEVSHELL_PROJECT_ID-media
Cloud Storage에 객체 추가
Java Cloud Storage 패키지 가져오기 및 사용
// ImageService.java
// TODO: Write a start import for Cloud Storage
// (1) ImageService.java 파일에서 Java Cloud Storage 패키지인 com.google.cloud.storage.* 를 가져옴
import com.google.cloud.storage.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@Service
public class ImageService {
// TODO: Create the storage client
// (2) StorageOptions 클래스를 사용하여 명명된 Cloud Storage 클라이언트를 구성
// The StorageOptions class has a getDefaultInstance()
// static method.
// Use the getService() method to get the storage client
private static Storage storage = StorageOptions
.getDefaultInstance()
.getService();
// TODO: Get the name of the Cloud Storage bucket
// (3) bucketName 이라는 String을 선언하고, String 값 주석으로 ${google.storage.bucket} 이라는 속성에서 값을 검색
// Use a Spring @Value annotation to get the value
// Get the value using ${google.storage.bucket}
// This references the GCLOUD_BUCKET environment variable
@Value("${google.storage.bucket}")
private String bucketName;
파일을 Cloud Storage로 보내는 코드 작성
// ImageService.java
public String saveImage(MultipartFile file)
throws IOException {
// The existing code in the method creates a unique name
// based on the file's original name. It has a
// prefix generated using the current date and time.
// This should ensure that a new file upload won't
// overwrite an existing object in the bucket
String fileName = System.nanoTime() +
file.getOriginalFilename();
// TODO: Create a new Cloud Storage object
// (1) BlobInfo 객체를 선언하고 Storage Cloud 객체를 사용하여 초기화
// BlobInfo.Builder를 사용하여 개체를 사용자 지정
// 이를 통해 파일에서 콘텐츠 유형을 설정하고 인증되지 않은 읽기 액세스를 허용하도록 ACL 설정
// Use the BlobInfo class to represent this object
// Use the BlobInfo.Builder to customize the Blob
// Set the content type from the file
// Set the object ACL to Public Read
BlobInfo blobInfo = storage.create(
BlobInfo.newBuilder(bucketName, fileName)
.setContentType(file.getContentType())
.setAcl(new ArrayList<>(
Arrays.asList(Acl.of(Acl.User.ofAllUsers(),
Acl.Role.READER))))
.build(),
file.getInputStream());
// TODO: Cloud Storage public URLs are in the form:
// (2) 새 Cloud Storage 객체의 공개 URL을 문자열로 반환
// https://storage.googleapis.com/[BUCKET]/[OBJECT]
// Use String concatentation to create return the URL
return "https://storage-download.googleapis.com/" + bucketName+ "/" +fileName;
}
전체 코드 )
// ImageService.java
// TODO: Write a start import for Cloud Storage
import com.google.cloud.storage.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@Service
public class ImageService {
// TODO: Create the storage client
// The StorageOptions class has a getDefaultInstance()
// static method.
// Use the getService() method to get the storage client
private static Storage storage = StorageOptions
.getDefaultInstance()
.getService();
// TODO: Get the name of the Cloud Storage bucket
// Use a Spring @Value annotation to get the value
// Get the value using ${google.storage.bucket}
// This references the GCLOUD_BUCKET environment variable
@Value("${google.storage.bucket}")
private String bucketName;
public String saveImage(MultipartFile file)
throws IOException {
// The existing code in the method creates a unique name
// based on the file's original name. It has a
// prefix generated using the current date and time.
// This should ensure that a new file upload won't
// overwrite an existing object in the bucket
String fileName = System.nanoTime() +
file.getOriginalFilename();
// TODO: Create a new Cloud Storage object
// Use the BlobInfo class to represent this object
// Use the BlobInfo.Builder to customize the Blob
// Set the content type from the file
// Set the object ACL to Public Read
BlobInfo blobInfo = storage.create(
BlobInfo.newBuilder(bucketName, fileName)
.setContentType(file.getContentType())
.setAcl(new ArrayList<>(
Arrays.asList(Acl.of(Acl.User.ofAllUsers(),
Acl.Role.READER))))
.build(),
file.getInputStream());
// TODO: Cloud Storage public URLs are in the form:
// https://storage.googleapis.com/[BUCKET]/[OBJECT]
// Use String concatentation to create return the URL
return "https://storage-download.googleapis.com/" + bucketName+ "/" +fileName;
}
}
애플리케이션 실행 및 Cloud Storage 객체 생성 1) 저장한 후 Cloud Shell에서 응용 프로그램 시작
mvn spring-boot:run
2) 이미지 파일을 로컬 컴퓨터로 다운로드
3) 웹 미리보기를 통해 퀴즈 애플리케이션을 연 후 질문 만들기 링크 클릭 4) 양식을 완성한 다음 저장
5) 클라우드 콘솔로 돌아가 Cloud Storage로 이동 후 브라우저에서 <Project ID>-media 버킷을 클릭
6) 이름이 지정된 새 객체를 확인
클라이언트 애플리케이션 실행 및 Cloud Storage 공개 URL 테스트 1) 퀴즈 애플리케이션의 URL 끝에 /api/quizzes/gcp 추가 웹 애플리케이션에 추가한 질문에 해당하는 클라이언트에 애플리케이션이 JSON 데이터를 반환하는 것을 확인 가능 "imageUrl" : "https://storage-download.googleapis.com/<Project ID>-media/객체이름" 즉, "https://storage-download.googleapis.com/" + bucketName+ "/" +fileName
속성에는 Cloud Storage에서 만든 새 개체에 해당하는 값 imageUrl이 존재2) 시험 응시 후 GCP를 클릭하고 질문에 대답하면 웹 애플리케이션 내에서 이미지 형식이 지정된 것을 볼 수 있음