struts2でファイルアップロード(FileUpload Interceptorの設定、初期値、制限)

2010/04/24 01:39

struts2のファイルアップロード用インターセプターに関して、基本的には英語だが以下にまとめられている。

http://struts.apache.org/2.0.14/docs/file-upload.html

・struts2のFileUpload Interceptorのアップロード可能なファイルサイズ制限は、デフォルトでは2MBに設定されている。また、この値は個々ではなく複数アップロードした場合はその合計値

propertiesファイルで以下を設定することによりオーバーライド可能。

struts.multipart.maxSize=任意の数値(Byte)
※ struts.xmlに以下を追加する方法もある。
<constant name="struts.multipart.maxSize" value="任意の数値(Byte)" />

因みに最大サイズの制限を無くすには"-1"を指定する。FileUploadBase.javaのソースコードをみて頂ければ仕様がわかると思う。

また、FileUpload Intercepterで曲者なのが、org.apache.commons.fileupload.FileUploadBaseにデフォルトでハードコードされているエラーメッセージだ。無理やりAction周りでリプレイスする荒業もあるが、そんなことはしちゃ駄目だ。

このInterceptorはmultipartのリクエストを処理する段階で呼ばれる(かなり早い段階で呼ばれる)為、MultiPartRequestで行われるparseメソッド呼び出し対象クラスを自前のものに変更する。

propertiesファイルで以下を設定することにより呼び出しクラスを変更可能。デフォルトのクラスを継承したクラスに変更し、メソッドをオーバーライドしよう。

struts.multipart.parser=自前で用意したクラスのFQCN

といった具合です。

更に、一時ファイルの保存ディレクトリを変更する場合は

struts.multipart.saveDir=保存先ディレクトリ

を記述します。

 

フォームから値を取得する方法は

・File [fileName]  -- ファイルオブジェクト
・String [fileName]ContentType -- コンテンツタイプ
・String [fileName]FileName -- アップロードフォームのファイル名

のメンバ変数とセッターゲッターを用意すると、各々自動でバインドされます。
※ 別にFileオブジェクトだけでも可能。[fileName]部分は任意。

正規のドキュメントが英語のものしかない為情報が少ないですが(しかも本家にも書かれていないこともある)、struts2って素晴らしいですね。

大体は変なことをしなくても拡張可能な様に実装されていると思われます。

でもすごく気に入らない実装もあった気がするんだよなぁ。。忘れちゃったけど。

struts2において、フォームの値を入れ子構造の配列で受け取る際の小技

2010/04/23 17:29

Javaのフレームワークstruts2を利用した開発において、

フォームの値をプログラムで取得する際は、getModel()でフォームの値をマッピングした型を返すパターンが多いと思います。

この場合で配列を利用する際は、

【HTML】

--------------------------------------------------------------

<input type="text" name="model[0].name">

<input type="text" name="model[0].link">

<input type="text" name="model[1].name">

<input type="text" name="model[1].link">

<input type="text" name="model[2].name">

<input type="text" name="model[2].link">

--------------------------------------------------------------

【Java】

--------------------------------------------------------------

アクション

・・・

private List<HogeForm> hogeForm = new ArrayList<HogeForm>();

@Element( value = HogeForm.class )

public Object getModel() {

    return hogeForm;

}

・・・

※ HogeFormクラスにはname, linkのメンバ変数を用意

--------------------------------------------------------------

みたいな感じでアノテーション@Element( value = HogeForm.class ) を利用することで、階層を浅くする事ができるのですが、あまり知られていない様です。

現場でよくみかけるのは下記の様なソースです。

【HTML】

--------------------------------------------------------------

<input type="text" name="hogeListForm.form[0].name">

<input type="text" name="hogeListForm.form[0].link">

<input type="text" name="hogeListForm.form[1].name">

<input type="text" name="hogeListForm.form[1].link">

<input type="text" name="hogeListForm.form[2].name">

<input type="text" name="hogeListForm.form[2].link">

--------------------------------------------------------------

【Java】

--------------------------------------------------------------

アクション

・・・

private HogeListForm hogeListForm = new HogeListForm();

public Object getModel() {

    return hogeListForm;

}

・・・

※   HogeListFormクラスにはFormクラス型のリストのメンバ変数を用意、Formクラスにはname, linkのメンバ変数を用意

--------------------------------------------------------------

是非、アノテーション@Elementを使用してみて下さい。