jQuery File Uploadとサーブレットでファイルアップロード画面を作ってみる
TweetPosted on Friday Jan 24, 2014 at 09:13AM in Technology
jQuery File UploadとJava Servletを使ってドラッグアンドドロップで複数ファイルのアップロードが可能な画面を作ってみます。
ここでは[1]を使います。[3]が参考になりそうです。サーバ側での受け取りはサーブレットを使います。Servlet3のAPIを使って作ります。
環境
- jQuery-File-Upload-9.5.3
- WildFly 8.0.0CR1
- Oracle JDK7u51
- OS X 10.9.1
準備
- [1]からzipファイルをダウンロードしてきます。私は9.5.3.zipというファイルを取ってきました
- この要領でEclipseでJavaEE7プロジェクトを作ります
作る
画面側でHTMLファイル以外に必要なもの
- jQuery本体
- js/jquery.fileupload.js
- js/jquery.iframe-transport.js
- js/vendor/jquery.ui.widget.js
jQuery本体はCDNから取ってきます。下3つはjQuery-File-Uploadのzipファイルに含まれていますので適当な場所にコピーします。この例ではjsディレクトリを作ってそこにまとめて置きました。
プロジェクトの構造
こんな感じ

画面側
index.html
- 基本はファイル選択ボタンを押してファイルダイアログ出して選択
- 直接ブラウザの画面へドラッグアンドドロップも可
- 複数ファイルOK
- 簡単なプログレスバー的なものあり
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>jQuery File Upload Example</title>
<style>
.bar {
height: 18px;
background: green;
}
</style>
</head>
<body>
<input id="fileupload" type="file" name="files[]" data-url="upload" multiple>
<div id="progress">
<div class="bar" style="width: 0%;"></div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="js/jquery.ui.widget.js"></script>
<script src="js/jquery.iframe-transport.js"></script>
<script src="js/jquery.fileupload.js"></script>
<script>
$('#fileupload').fileupload({
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css(
'width',
progress + '%'
);
}
});
</script>
</body>
</html>
バックエンド側
UploadReceiveServlet
package jqueryfileul;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@WebServlet("/upload")
@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5)
public class UploadReceiveServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
for (Part part : request.getParts()) {
System.out.println(part.getName());
System.out.println(part.getContentType());
System.out.println(part.getSubmittedFileName());
System.out.println(part.getSize());
if ("text/plain".equals(part.getContentType())) {
try (InputStream is = part.getInputStream();
InputStreamReader r = new InputStreamReader(is);
BufferedReader br = new BufferedReader(r)) {
System.out.println(br.readLine());
}
}
}
}
}
動かしてみる
画面はこんな感じ

ドラッグアンドドロップ
わかりにくいけどFinderからファイル2個ドラッグしてるところです。

プログレスバーが緑色に

サーバ側でも取れてますね

その他
日本語ファイル名が化ける
私の環境だと何故か日本語ファイル名でアップロードすると文字化けが起こります。この設定しとけば大丈夫だろうと思っていたのだけど。またそのうち調べる。クライアント側でファイル名をURIエンコードしないといけないのかな。
PrimeFacesのファイルアップロードコンポーネントお勧め
JSFの動くWebコンテナがあるならPrimeFacesの同機能[7]を使うのがお勧めです。何故わざわざこんな風に書いているかというと[6]の問題にはまったらしく、advancedモードで動かす事が出来なかったからです。
ちなみにPrimeFacesの同コンポーネントはかつてCommons FileUploadとCommons IOに依存していて、なおかつフィルタの設定も必要だったのですが、JSF2.2上で動かすなら両者とも不要になったようです。WildFlyでは動かなかったけど。GlassFish4なら動くのかな。
参考文献
- jQuery File Upload Demo
- 7 Javascript Ajax File Upload Plugins
- Java Servlet – jQuery File Upload (multiple, drag&drop, progress…) | HMKCode
- Basic plugin · blueimp/jQuery-File-Upload Wiki
- JSF 2.2 で待ちに待ったFileUploadを試す - DENのシステムエンジニアの思うこと
- [WFLY-2329] File upload doesn't work - JBoss Issue Tracker
- PrimeFaces - ShowCase
Tags: web