앞서 firebase storage를 이용한 이미지 업로드 처리 정리글을 올리면서 무료 사용가능 storage 용량을 toyproject 개발 중에 초과할 것으로 예상되었다.
대안으로 검색해보다가 google cloud storage를 알게되었고 google cloud 또한 처음 사용해 보지만 25년 4월까지 무료크레딧으로 이용이 가능하여 이번 프로젝트에 적합하다고 생각하였다.
그리하여 앞서 정리했던 기능을 그대로 google cloud로 변경해보았고 google cloud 경우 검색 시 정리가 잘된글이 많아 참고하기 좋았다.
springboot : 3.3.3
java : 17
google cloud : 1.2.5
google cloud storage : https://console.cloud.google.com/
goole cloud에서 새로운 프로젝트 설정 후 cloud storage 새로운 버킷을 생성한다.
아래 url에 정리가 잘되어있어 참고하여 설정하였다.
홈페이지에서 설정이 끝나면 프로젝트에서 google cloud 설정을 해보자
google cloud 관련 의존성을 추가한다.
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'
프로젝트 설정 시 받았던 키파일을 내부 resouces 아래에 포함하였다.
(git사용 시 키파일이 올라가지않도록 필수로 꼭 gitignore파일에 등록해주기)
프로젝트 실행 시 자동으로 google cloud 정보를 받아올수 있도록 config로 설정해준다.
GoogleCloudStorageConfig.java
@Bean
public Storage storage() throws IOException {
ClassPathResource resource = new ClassPathResource("키파일 내부경로");
GoogleCredentials credentials = GoogleCredentials.fromStream(resource.getInputStream());
String projectId = "키파일 내부 프로젝트id";
return StorageOptions.newBuilder()
.setProjectId(projectId)
.setCredentials(credentials)
.build()
.getService();
}
여기까지 Springboot에 google cloud 설정을 마쳤다.
그럼 이제 실제 내부로직을 추가해 이미지 업로드, 이미지 가져오는 기능을 추가해보자.
이미지 업로드 화면 구성과 스크립트를 작성한다.
Mypage.html
<table>
<tr>
<td colspan="2">
// 프로필 이미지 노출
<img id ="myImage" src="업로드이후 url" style="width: 200px;height: 200px;">
</td>
</tr>
<tr>
<td colspan="2">
<form id="uploadForm">
<label for="file">사진</label>
<input type="file" id="file" name="file" accept="image/*" required />
<button type="submit">업로드</button>
</form>
</td>
</tr>
</table>
// 이미지 업로드 해당 스크립트
$('#uploadForm').on('submit', function(event) {
var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
$.ajax({
url: '/uploadImg',
type: 'POST',
async: false,
data: formData,
contentType: false,
processData: false,
success: function(response) {
alert(response);
location.href = "/newMyPage";
},
error: function(xhr, status, error) {
alert(response);
}
});
});
ImageController.java
@PostMapping("/uploadImg")
public ResponseEntity<String> fileUpload(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) throws IOException {
HttpSession session = request.getSession();
SessionVO sessionInfo = (SessionVO) session.getAttribute(SessionConst.SESSION_INFO);
try{
if (!multipartFile.isEmpty()) {
//imageService.saveImg(multipartFile, sessionInfo.getId()); firebase storage
imageService.saveImgToGCS(multipartFile, sessionInfo.getId());
}
}catch (Exception e){
return ResponseEntity.status(500).body("파일 업로드 실패");
}
return ResponseEntity.ok("파일 업로드 성공");
}
ImageSeviceImpl.java
@Transactional
@Override
public int saveImgToGCS(MultipartFile multipartFile, String loginId) throws Exception {
String fileName = loginId.replace("@", "");
String ext = multipartFile.getContentType(); // 파일의 형식 ex) JPG
try{
// 프로필이 존재할 경우 기존 프로필 삭제처리
if(storage.get("toyproject", fileName) != null){
storage.get("toyproject", fileName).delete();
}
// 이미지 신규 업로드
BlobInfo blobInfo = storage.create(
BlobInfo.newBuilder("toyproject", fileName)
.setContentType(ext)
.build(),
multipartFile.getBytes()
);
if(blobInfo == null) throw new Exception();
}catch (Exception e){
e.getMessage();
throw new Exception();
}
return 1;
}
ImageSeviceImpl.java
@Override
public String getImgUrlFromGCS(String loginId){
String encodedURL = "";
String fileName = loginId.replace("@", "");
try{
if(storage.get("toyproject", fileName) == null){
// 이미지 없는 경우 디폴트 이미지로 노출
return "https://storage.cloud.google.com/toyproject/default.png";
}
encodedURL = "https://storage.cloud.google.com/toyproject/"+fileName;
}catch (Exception e){
e.getMessage();
}
return encodedURL;
}
이렇게 구성하면 앞서 글과 동일한 로직으로 firebase storage에서 google storage로 변경하여 사용할 수 있다. 회사에서는 AWS S3를 이용하여 이미지처리를 하고 있어서 다른 방법을 사용해 본적이 없었는데 이번 기회에 설정을 해보았다.