「アップロードのサンプルを紹介する」と書いておいて、コードを掲載するのを忘れていました。
アップロードのサンプルです。struts-upload.zip
ポイントは2つです。
- ActionFormにFormFileフィールドを用意する
- JSPでは、multipart/form-dataでPOSTする
意外と簡単に扱えます。
FormFileというクラスが良くできているのと、Strutsがアップロードされたファイルを上手いこと
扱ってくれるので、Actionクラスの方は簡便に記述できます。
面倒なのは、受け取ったアップロードファイルをどう扱うかです。
サーバー上のファイルシステムに保存したりするわけですが、ファイル名がかぶらないように注意します。
Webシステムは、複数のアクセスを同時に処理するので、固定のファイル名で、一時的に保存したりすると、たとえ短時間であっても、他のアクセスユーザーに上書きされる可能性があります。
しかも、こういったバグは開発時には見つからず、まれに発生するバグを生みかねないので要注意です。
ここでファイルを選らんで送信すると、サーバー側に保存されて、こんなページが表示されます。
ActionForm
さきほど書いたように、FormFile(org.apache.struts.upload.FormFile)型
のフィールドを用意します。
これがファイルそのもののように扱えます。setter/getterも通常のフィールドのように用意します。
private FormFile file1;
public FormFile getFile1() {
return file1;
}
public void setFile1(FormFile file1) {
this.file1 = file1;
}
JSP
JSPでは、
を使ってアップロード用の入力フォームを用意します。
また、
のenctypeは、”multipart/form-data”とします。
これはアップロードのときのおまじないのようなものです。
Action
あとはAction側の処理です。引数のActionFormからFormFileを取り出すだけで、アップロードされたファイルを操作できます。
//uploadされたFormFileオブジェクトを取得
UploadForm uploadForm = (UploadForm)form;
FormFile ff = uploadForm.getFile1();
getInputStreamで、送信されたファイルのInputStreamを取得できます。
これを読み取ってファイルシステム上に保存したり、DBのBLOBフィールドに格納したりします。
ところで、FormFileは、アップロードされたファイルを一時ファイルとして保持したり、メモリ中のバイト配列として保持したりします。これはアップロードファイルのサイズによって適切に使い分けます。(※後述のbufferSize)
大きなファイルをアップロードした場合は、メモリで保持しつづけずに、Strutsが一時ファイルとして保持するようになります。
一時ファイルとして保存された場合に、その一時ファイルはしばらく残り続けます。
お行儀良く処理するならば、Action内で使用しなくなったタイミングで、削除しなければなりません。
そのメソッドが、destroy()
です。
destroyにより一時ファイルは開放され削除されます。
もし一時ファイルが作成されておらず、バイト配列で扱われていても、destroyはなにもしないので呼び出してOKでした。
設定
StrutsがFormFileを生成してくれるのですが、動作の設定を考えないと、セキュリティホールに繋がります。
例えば、ブラウザから100GBのファイルをアップロードされたときに、律儀に100GBの一時ファイルを作成してしまったら問題です。
これはAction処理の記述ではどうにもなりません。Strutsが生成するFormFileができた時点で、すでに一時ファイルが生成されてしまっているからです。
これらの設定は、struts-config.xmlの、controllerの属性で指定します。
bufferSize | アップロード時のバッファサイズ。 デフォルトは4096 |
maxFileSize | アップロードファイルの最大サイズ。 デフォルトは250M |
tempDir | 一時ファイルの作成場所。 デフォルトはWebアプリケーションで設定される作業ディレクトリ。 |
サイズの指定は、K(キロバイト)、M(メガバイト)、G(ギガバイト)が指定できます。
これからやろうと思っていた矢先、すごい参考になりました。
感謝感謝です。
コメントありがとうございます。参考になったようでなによりです。
僕もこれからやろうと思っていました。本当に簡単にできてびっくりしました!!とてもわかりやすかったです!!
参考になったようで書いたかいがありました。
いやー、struts-config.xmlのcontrollerの設定で、
ぴかーっと閃いたことがありました。
ヒントありがとうございます!