JSPで行こう!

ファイルのアップロード方法

画像を表示するには、まずサーバーに画像ファイルをアップロードする必要があります。
Servlet で行う方法は、良く見かけますが JSP だけでも可能です。

Servlet 3.0 (Tomcat 7)以降

Servlet 3.0 からファイルアップロードのサポートが標準となったので、
以前のように別途サポートクラスを追加する必要は無くなっています。

サンプルを更新しようとしたのですが、どうも JSP では動作しないようです。(Tomcat 9)
理由はわかりませんが、エラーにはならず常にファイル数が0になってしまいます。
アノテート(@MultipartConfig)が関係しているのかもしれません。
JSP ではアノテートは使えません。

とは言え、Tomcat 内部では Apache Commons を使っているので、
Apache commons から jar ファイルをわざわざ取得して Tomcat に追加設定する必要は無さそうです。
Tomcat 9 の java のドキュメントに例があります。

public void doPost(HttpServletRequest req, HttpServletResponse res) {
   DiskFileItemFactory factory = new DiskFileItemFactory();
   // メモリに保持する最大サイズ
   factory.setSizeThreshold(4096);
   // getSizeThreshold() より大きなサイズのデータを保管する場所
   factory.setRepository(new File("/tmp"));

   ServletFileUpload upload = new ServletFileUpload(factory);
   // FileUploadException が発生する前の最大サイズ
   upload.setSizeMax(1000000);

   List fileItems = upload.parseRequest(req);
   // ここでは2つのファイルがある事を想定している. 1つは小さなテキストファイル
   // 2つ目は種類は問わずサーバーにファイルとして書き出す。
   Iterator i = fileItems.iterator();
   String comment = ((FileItem)i.next()).getString();
   FileItem fi = (FileItem)i.next();
   // クライアントのファイル名
   String fileName = fi.getName();
   // コメントとファイル名をデータベースへ
   ...
   // ファイルとして書き込む
   fi.write(new File("/www/uploads/", fileName));
 }
 

このままでは、JSP では動かないので、サンプルを書きました。
ちょっと長いようですが、この jsp だけで実行できるので servlet+jsp で構成するより簡単です。

 

 

アップロードクラスの準備

Tomcat 6 以下でアップロードを行うには、 
さすがに実装は大変なので、ここでは Apache Commons のアップロードクラスを使います。
次のファイルをダウンロードします。

https://commons.apache.org/proper/commons-fileupload/

使ったバージョンは下記です。

 commons-fileupload-1.2.jar
 commons-io-1.4.jar

上記を /webapps/{アプリ名}/WEB-INF/lib 配下に置きます。
以下は、サンプルプログラムです。

JSPのコードを書く上でちょっと困るのが、サンプルはリクエスト情報が他に無いので簡単ですが、
アップロード処理は、html の "context/multipart-data" 形式で受けるので、
通常の getParameter() でリクエスト・パラメータを受ける事ができず、例のようにパラメータの値の取得方法が異なります。
ですので、<FORM>タグ内に入力項目がたくさんあると、多少面倒になります。

Ajax でファイルアップロード

サンプルでは、html で記述した<FORM>で submit していますが、最近は Ajax でやってしまったほうが簡単かもしれません。
Ajax では、現在表示されている画面には何の変化も与えず、アップロードした結果だけを JavaScript で表示すれば良くなります。
こうすれば、他の入力中の情報は渡す必要が無く、サーバー側の処理もシンプルになります。
この場合、サーバーのJSP処理も若干ですが Ajaxに対応する必要があります。
対応といっても html を返す部分を、json 形式でアップロード結果を返す、といった位の事です。

通常は、"成功"か"失敗"したかだけを返せば良いですが、間接参照用の id を返したりすることも出来ます。
クライアント側の JSP の例です。(htmlだけでも書けます)

サーバー側の処理の例です。

1つの jsp で、html、json 両方に対応することも可能です。

そのほうが良いでしょう。

クリップボードからの画像アップロード

スクリーンショットを貼りたいだけなのに、いちいちファイルに保存してそのファイルをアップロードするのは結構面倒です。
クリップボードから直接アップロードできると便利ですね。
私が仕事で使っているプロジェクト管理ツールで有名な Redmine でもちょっとしたプラグインの追加で出来ていて、
システム作業後の画面をエビデンスとして残すのに大変重宝しています。
技術的な実装例が紹介されていたので、対応してみました。
javascript でのアップロードに少し手を加えるだけで実現できます。

なお、getData('image/png') でも取得できそうですが、仕様には無いようで出来ませんでした。 
chrome の開発ツールで確認すると、確かに items の中にオブジェクトが確認できます。
面倒ですが、配列内を検索するしかないようです。

« 前頁 次頁 »