9. ファイルアップロード

WebWork2ではファイルアップロード処理の実装を選ぶことが出来ます。
ファイルアップロードの設定はwebwork.propertiesに書きます。

webwork.propertiesの設定

今回は実装にJakarta Commons FileUploadを使います

webwork.multipart.parser=jakarta
webwork.multipart.saveDir=/tmp
webwork.multipart.maxSize=5242880

webwork.multipart.parser: ファイルアップロード処理の実装(pell,cos,jakartaから選べます)
webwork.multipart.saveDir: アップロードファイルの一時保存ディレクトリ
webwork.multipart.maxSize: アップロードファイルの最大サイズ(リクエストボディ部のサイズ)

Jarファイルの追加

Jakarta Commons FileUploadとJakarta Commons IO(サンプルコード内で使用)を追加します。
※ 使う実装が違う場合は使用するJarが異なります。pell=pell-multipart.jar、cos=cos-multipart.jar

FileUploadActionの作成

ファイルアップロードのプロパティにはjava.io.Fileクラスを使用します。
またFileクラスだけだと、サーバに一時保存したファイルにしかアクセスできないので、
それ以外の情報を使いたい場合はMultiPartRequestWrapperクラスを使用して、情報を取り出します。

public class FileUploadAction extends ActionSupport {
    private File file;
    private String text;

    public String execute() throws Exception {
        System.out.println("ファイルパス(サーバ側)" + file.getPath());
        System.out.println("ファイル名(サーバ側)" + file.getName());
        FileUtils.copyFile(file, new File("c:/test"));

        // クライアント側のファイル名やコンテントタイプをとりたい場合は
        // MultiPartRequestWrapperクラスを使う。
        MultiPartRequestWrapper multiWrapper =
             (MultiPartRequestWrapper) ServletActionContext.getRequest();
        System.out.println("アップロードファイル名(クライアント側):"
                + multiWrapper.getFileNames("file")[0]);
        System.out.println("コンテントタイプ:"
                + multiWrapper.getContentTypes("file")[0]);
        System.out.println("文字パラメータ:" + text);
        return super.execute();
    }

    public File getFile() {
        return file;
    }
    public void setFile(File file) {
        this.file = file;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
}

xwork.xmlの設定

fileuploadinitはfileupload.vmの表示用で、fileuploadがアップロードファイルを処理するアクションです。
fileuploadにはintercepterにfileUploadStackを設定します。

<action name="fileuploadinit" class="com.opensymphony.xwork.ActionSupport">
    <result name="success" type="dispatcher">
        <param name="location">/WEB-INF/vm/fileupload.vm</param>
    </result>
</action>
<action name="fileupload" class="ww2.examples.event.FileUploadAction">
    <interceptor-ref name="fileUploadStack"/>
    <result name="success" type="redirect">
        <param name="location">fileuploadinit.action</param>
    </result>
</action>

fileupload.vmの作成

<form method="POST" action="fileupload.action" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="text" name="text">
    <input type="submit">
<form>

結果

FileUploadAction内でアップロードしたファイルの情報が取得できます

結果(その2):日本語処理について

ファイルアップロード処理実装による日本語パラメータ、日本語ファイル名処理の結果は以下のとおりです。(文字エンコーディング:Shift_JIS、クライアント:InternetExplorer6.0SP2の場合)

  • jakarta: 日本語パラメータ=○、日本語ファイル名=△(デフォルトエンコーディングとファイルのエンコーディングが同じ場合はOK)
  • pell: 日本語パラメータ=○、日本語ファイル名=○
  • cos: 日本語パラメータ=×、日本語ファイル名=×

jakartaはDiskFileUpload#setHeaderEncoding()を使えば日本語が通るようになるかもしれません。

結果(その3):最大サイズを超えた場合

  • jakarta: エラーログが出力されるだけ
  • pell,cos: エラーログが出力され、ActionErrorsにエラーメッセージが追加される

JakartaMultiPartRequestはエラー握りつぶしちゃってますねぇ。

独り言

WebWork2ではpellが標準的な実装みたいですねぇ。
でも個人的には、実績のありそうなCommonsFileUploadを使いたいので、時間を見てバグレポート出したいと思います。