ファイルのアップロード

アップロードされたファイルは一時フォルダに保存され、アクションメソッドにはそのファイルにアクセスするためのFileオブジェクトが渡される。
GAEではローカルファイルシステムへの書き込みが禁止されているため、この方法でファイルを受信することは出来ない。
と、思っていたが、フレームワークの内部を見てみたところ、メモリ上で何とかしようという試みが行われていた。

public Map<String, String[]> parse(InputStream body) {
    Map<String, String[]> result = new HashMap<String, String[]>();
    try {
        FileItemIteratorImpl iter = new FileItemIteratorImpl(body, Request.current().headers.get("content-type").value(), Request.current().encoding);
        while (iter.hasNext()) {
            FileItemStream item = iter.next();
            FileItem fileItem = new AutoFileItem(item);
            try {
                Streams.copy(item.openStream(), fileItem.getOutputStream(), true);
            } catch (FileUploadIOException e) {
                throw (FileUploadException) e.getCause();
            } catch (IOException e) {
                throw new IOFileUploadException("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage(), e);
            }
            if (fileItem.isFormField()) {
                // must resolve encoding
                String _encoding = Request.current().encoding; // this is our default
                String _contentType = fileItem.getContentType();
                if( _contentType != null ) {
                    HTTP.ContentTypeWithEncoding contentTypeEncoding = HTTP.parseContentType(_contentType);
                    if( contentTypeEncoding.encoding != null ) {
                        _encoding = contentTypeEncoding.encoding;
                    }
                }

                putMapEntry(result, fileItem.getFieldName(), fileItem.getString( _encoding ));
            } else {
                @SuppressWarnings("unchecked") List<Upload> uploads = (List<Upload>) Request.current().args.get("__UPLOADS");
                if (uploads == null) {
                    uploads = new ArrayList<Upload>();
                    Request.current().args.put("__UPLOADS", uploads);
                }
                try {
                    uploads.add(new FileUpload(fileItem));
                } catch (Exception e) {
                    // GAE does not support it, we try in memory
                    uploads.add(new MemoryUpload(fileItem));
                }
                putMapEntry(result, fileItem.getFieldName(), fileItem.getFieldName());
            }
        }
    } catch (FileUploadIOException e) {
        Logger.debug(e, "error");
        throw new IllegalStateException("Error when handling upload", e);
    } catch (IOException e) {
        Logger.debug(e, "error");
        throw new IllegalStateException("Error when handling upload", e);
    } catch (FileUploadException e) {
        Logger.debug(e, "error");
        throw new IllegalStateException("Error when handling upload", e);
    } catch (Exception e) {
        Logger.debug(e, "error");
        throw new UnexpectedException(e);
    }
    return result;
}    // ---------------------------------------------------------- Class methods

ご丁寧に、GAEではサポートされないのでメモリで試してみる、と書かれている。

with GoogleAppEngine‎