SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Google App Engine for Javaを使ってみよう!

Google App Engine for Javaを使ってみよう!
(2)Images Java API の使い方

Google App Engine for Javaを使ってみよう! (2)

ファイルのアップロード

 Google App Engineでは、サーバ上でファイルを扱うことができません。各種データはオンメモリで取り回し、保存が必要な場合にはDatastore Java APIを利用して、Google App Engineの擬似データベースに取り込む必要があります。Datastore Java APIについては、今後の記事でご紹介したいと思います。

 Javaで書かれたウェブサービスのファイルアップロードライブラリと言えば、通常Apache CommonsのFileUploadを指すと思いますが、このライブラリはディスク上でデータを取り扱うので、アップロードされたデータをオンメモリで処理するためのクラスを追加します。

 まず、Apache Commonsの「FileUpload 1.2.1」と依存ライブラリの「IO 1.4」のバイナリをダウンロードします。それぞれ展開後のディレクトリから「commons-fileupload-1.2.1.jar」と「commons-io-1.4.jar」を「war/WEB-INF/lib」にコピーします。

 「commons-fileupload-1.2.1.jar」はコンパイルに必要なので、ビルドパスに追加します。準備ができたら、[com.daisukeyamashita.test.images]パッケージに以下の2つのクラスを追加して下さい。

MemoryFileItem クラス
package com.daisukeyamashita.test.images;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemHeaders;
import org.apache.commons.fileupload.FileItemHeadersSupport;
import org.apache.commons.fileupload.ParameterParser;

public class MemoryFileItem implements FileItem, FileItemHeadersSupport {

    private static final long serialVersionUID = -2531086814081783645L;

    public static final String DEFAULT_CHARSET = "ISO-8859-1";

    private String fieldName;
    private String contentType;
    private boolean isFormField;
    private String fileName;

    private long size = -1;
    private byte[] cachedContent = null;
    private FileItemHeaders headers = null;

    public MemoryFileItem(String fieldName, String contentType, boolean isFormField, String fileName) {
        this.fieldName = fieldName;
        this.contentType = contentType;
        this.isFormField = isFormField;
        this.fileName = fileName;
    }

    public void delete() {
        cachedContent = null;
        baos = null;
    }

    public byte[] get() {
        if (isInMemory()) {
            if (cachedContent == null) {
                cachedContent = baos.toByteArray();
            }
            return cachedContent;
        }
        return new byte[0];
    }

    public String getContentType() {
        return contentType;
    }

    public String getFieldName() {
        return fieldName;
    }

    public InputStream getInputStream() throws IOException {
        if (cachedContent == null) {
            cachedContent = baos.toByteArray();
        }
        return new ByteArrayInputStream(cachedContent);
    }

    public String getName() {
        return fileName;
    }

    private ByteArrayOutputStream baos = null;

    public OutputStream getOutputStream() throws IOException {
        if (baos == null) {
            baos = new ByteArrayOutputStream();
        }
        return baos;
    }

    public long getSize() {
        if (size >= 0) {
            return size;
        } else if (cachedContent != null) {
            return cachedContent.length;
        } else if (baos != null) {
            return baos.toByteArray().length;
        }
        return 0;
    }

    public String getString() {
        byte[] rawdata = get();
        String charset = getCharSet();
        if (charset == null) {
            charset = DEFAULT_CHARSET;
        }
        try {
            return new String(rawdata, charset);
        } catch (UnsupportedEncodingException e) {
            return new String(rawdata);
        }
    }

    @SuppressWarnings("unchecked")
    public String getCharSet() {
        ParameterParser parser = new ParameterParser();
        parser.setLowerCaseNames(true);
        // Parameter parser can handle null input
        Map params = parser.parse(getContentType(), ';');
        return (String) params.get("charset");
    }

    public String getString(String encoding) throws UnsupportedEncodingException {
        return new String(get(), encoding);
    }

    public boolean isFormField() {
        return isFormField;
    }

    public boolean isInMemory() {
        return true;
    }

    public void setFieldName(String name) {
        this.fieldName = name;
    }

    public void setFormField(boolean state) {
        this.isFormField = state;
    }

    public void write(File file) throws Exception {
        // no process;
    }

    public FileItemHeaders getHeaders() {
        return headers;
    }

    public void setHeaders(FileItemHeaders headers) {
        this.headers = headers;
    }

}
MemoryFileItemFactory クラス
package com.daisukeyamashita.test.images;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;

public class MemoryFileItemFactory implements FileItemFactory {

    public MemoryFileItemFactory() {

    }

    public FileItem createItem(String fieldName, String contentType, boolean isFormField,
            String fileName) {
        MemoryFileItem result = new MemoryFileItem(fieldName, contentType, isFormField, fileName);
        return result;
    }
}

次のページ
Images Java APIを実行する

この記事は参考になりましたか?

Google App Engine for Javaを使ってみよう!連載記事一覧

もっと読む

この記事の著者

山下 大介(ヤマシタ ダイスケ)

  京都大学を中心とした、産官学共同プロジェクトのSOBAプロジェクトに参加後、同プロジェクトで開発したP2P配信によるVoIP技術を2005年に商業化。オープンソース、VoIP、P2P、クラウドコンピューティングに精通。趣味はGoogleの追っかけ。現在は、株式会社SOBAプロジェクト取締役。ブログ:『~ ミネルヴァの梟は黄昏とともに飛び始める ~』所属:株式会社SOBAプロジェクトGoogle Developer Day 2008サポーター, 2009サポーターGoogle App Engine API Expert

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3836 2009/04/21 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー