Five cool things you can do with Play 문서를 보면 play framework을 사용할 때 쉽게 구현할 수 있는 다섯가지 기능에 대하여 설명하고 있다. 이 다섯 가지 중의 하나가 파일 업로드를 얼마나 쉽게 구현할 수 있는지 설명하고 있다.
html form
코드 블럭 |
---|
#{form @uploadPhoto(), enctype:'multipart/form-data'} <input type="text" name="title" /> <input type="file" id="photo" name="photo" /> <input type="submit" value="Send it..." /> #{/form} |
controller code
코드 블럭 |
---|
public static void uploadPhoto(String title, File photo) { ... } |
그런데 Google App Engine에서 위와 같이 구현할 경우 에러가 발생한다. 에러가 발생하는 이유는 Google App Engine이 로컬 파일 시스템에 접근할 수 없기 때문에 위 소스 코드와 같이 File Type을 사용할 수 없기 때문이다. File Type은 로컬 파일 시스템에 접근이 가능한 상태에서 사용할 수 있는 API이다. GAE에서는 이 같은 문제를 해결하려면 HttpServletRequest로 전달되는 스트림을 읽어서 메모리에서 처리가 가능하도록 구현해야 한다.
이와 관련한 해결책을 찾기 위해 온라인상에서 검색한 결과 다양한 해결 방법을 찾을 수 있었지만 딱히 좋은 해결 방법은 없었다. 온라인 상에서 찾은 문서는 다음과 같다.
- Unoffical solution for upload photo to GAE
- Uploading a file using HTTP Post and Play! Framework Databinding on Google App engine
이 이외에도 다양한 문서들을 찾았지만 딱히 마음에 드는 방법을 찾을 수 없었다. 문서를 이리 저리 찾다보니 Play에서 Upload라는 타입을 제공하고 있다는 것을 알게 되었다. 혹시나 하는 마음으로 File Type 대신 Upload Type을 다음과 같이 적용했다.
코드 블럭 |
---|
import play.data.Upload; [...] public static void upload(Long id, Upload file) { Blob attachFile = new Blob(file.asBytes()); AttachedFile attachedFile = new AttachedFile (ServiceType.diaries, id, file.getFileName(), file.getSize(), file.getContentType(), attachFile); attachedFile.insert(); } |
위 소스코드와 같이 Play에서 제공하는 Upload Type을 활용해 데이터 바인딩을 했더니 정상적으로 파일 업로드가 가능한 것을 확인할 수 있었다. 혹시라도 Google App Engine에서 Play Framework을 활용해 파일 업로드 기능을 구현하고자 한다면 Upload Type을 활용해 쉽게 구현이 가능하다.