Subscribed unsubscribe Subscribe Subscribe

Google App Engine でファイルをアップロードする方法 比較

Java

GAE/J でファイルをアップロードする方法を学ぶ - すぎゃーんメモ の続き。
どうやらJava版でcommons-fileuploadを使ってファイルアップロードをする場合はgetItemIteratorから取り出すのが良いようだ。そうすればFileItemFactoryは必要ない。

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@SuppressWarnings("serial")
public class UploadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        ServletFileUpload fileUpload = new ServletFileUpload();
        try {
            FileItemIterator itemIterator = fileUpload.getItemIterator(req);
            while (itemIterator.hasNext()) {
                FileItemStream itemStream = itemIterator.next();
                InputStream inputStream = itemStream.openStream();
                
                resp.setContentType(itemStream.getContentType());
                int len;
                byte[] buffer = new byte[1024];
                while ((len = inputStream.read(buffer)) != -1) {
                    resp.getOutputStream().write(buffer, 0, len);
                }
            }
        } catch (FileUploadException e) {
            resp.sendError(500);
        }
    }
}

while文を回してreadしていくなんてちょっと泥臭い、と思ったけどこうするしかないっぽい。ファイルサイズを取得しようとすると、一度InputStreamから読み切ってどこかに格納してからじゃないとできないのかな…?

Python

一方Pythonは2行で済ませた。

from google.appengine.ext import webapp

class UploadHandler(webapp.RequestHandler):
    def post(self):
        data = self.request.get('data')
        self.response.out.write(data)

普通にinputタグのname属性からgetするだけでファイルであろうと何であろうとbyteString(?)で取得できる。
ただContent-Typeを取得すると必ずmultipart/form-dataになってしまっていた(Java版だと"image/jpeg"とか取れてた)。開発サーバーでしか試してないから本番環境だと違うのかもしれないけど。