Last Modified 2018.3.26
구글 클라우드 Blobstore 예제
예제 : https://github.com/kimjonghoon/gaefile
(에이젝스 파일 업로드 예제를 Blobstore를 이용하는 것으로 수정)
실행 방법
Google Cloud SDK 설치가 필요하다.
https://cloud.google.com/sdk/downloads를 방문한다.
'대화형 설치 프로그램'의 지시를 따라 설치한다.
(대화형 설치 프로그램으로 설치해야 최신 버전이 설치된다)
설치 후 명령 프롬프트를 새로 열고 gcloud components install app-engine-java를 실행해 자바 컴포넌트를 설치한다.
내려받은 예제를 풀고 루트 디렉터리로 이동하여 mvn appengine:run 실행한다.
(이때 자바는 자바 8이어야 한다)
명령 프롬프트에 Dev App Server is now running 메시지가 보이면, 웹 브라우저로 http://localhost:8080을 방문한다.
코드 설명
- 게시글은 관계형 데이터베이스의 테이블에, 첨부파일 정보는 데이터스토어에, 첨부파일은 Blobstore에 저장된다고 가정했다.
- index.jsp에서 1099는 게시글 번호를 의미한다.
- FileGroup 엔티티는 AttachFile의 부모 엔티티다. 게시글이 엔티티로 저장된다면 이 엔티티는 필요 없다.
- FileGroup 엔티티는 1099로 키가 만들어지므로 Id 속성 타입을 String으로 했다. Id 속성 타입이 Long이면 키는 자동 생성된다.
- 다음 코드는 엔티티를 저장한다.
(import static com.googlecode.objectify.ObjectifyService.ofy;문이 필요하다)ofy().save().entity(attachFile).now();
- 다음은 목록을 구하는 코드다.
order("creation")은 오름차순으로 정렬한다.Key<FileGroup> theGroup = Key.create(FileGroup.class, group); List<AttachFile> attachFiles = ofy() .load() .type(AttachFile.class) .ancestor(theGroup) .order("creation") .list();
- 다음은 AttachFile 엔티티와 파일을 삭제하는 핸들러 메소드 코드다.
@DeleteMapping("/{group}/{id}") public ResponseEntity<String> del(@PathVariable String group, @PathVariable Long id) { Key<FileGroup> theGroup = Key.create(FileGroup.class, group); Key<AttachFile> key = Key.create(theGroup, AttachFile.class, id); AttachFile attachFile = ofy() .load() .key(key) .now(); String blobKeyString = attachFile.getBlobKeyString(); BlobKey blobKey = new BlobKey(blobKeyString); blobstoreService.delete(blobKey); ofy().delete().key(key).now(); return new ResponseEntity<>("OK", HttpStatus.NO_CONTENT); }
파일과 관련된 일은 모두 FileController가 담당하도록 구현했다.
그래서 FileController를 @RestController로 구현할 수 없었다.
반환 타입을 ResponseEntity<String> 둔 이유는 @Controller로 만든 컨트롤러는 어떻게든 뷰를 해석하려 들기 때문이다.
위와 같이 구현하면 뷰를 무시하고 반환 타입을 지정할 수 있다. - 다음은 파일을 내려받게 하는 코드다.
@GetMapping("/{group}/{id}") public void download(@PathVariable String group, @PathVariable Long id, HttpServletRequest req, HttpServletResponse resp) throws IOException { Key<FileGroup> theGroup = Key.create(FileGroup.class, group); Key<AttachFile> key = Key.create(theGroup, AttachFile.class, id); AttachFile attachFile = ofy() .load() .key(key) .now(); String blobKeyString = attachFile.getBlobKeyString(); BlobKey blobKey = new BlobKey(blobKeyString); BlobInfo blobInfo = new BlobInfoFactory().loadBlobInfo(blobKey); String filename = URLEncoder.encode(blobInfo.getFilename(), "UTF-8"); resp.setContentType("application/octet-stream"); resp.addHeader("Content-Disposition", "attachment; filename*=UTF-8''" + filename); blobstoreService.serve(blobKey, resp); }