コンピュータクワガタ

かっぱのかっぱによるコンピュータ関連のサイトです

Servlet 3.0とHTML5で複数ファイルのアップロード

最初に

HTML5からinput type="file"の属性にmultipleが追加され、ファイルを複数選択することができるようになっています。今回はそれとServlet 3.0を利用して複数ファイルのアップロードを実装します。

まず、ベースとなるServlet 3.0によるファイルのアップロードは、以下を参考にしています。

Servlet 3.0 File Upload 機能 - 寺田 佳央 - Yoshio Terada

http://yoshio3.com/2010/03/11/servlet-3-0-file-upload-%E6%A9%9F%E8%83%BD/

multiple属性はChromeFirefoxでは実装されていますが、IE9以下では動作しません。実際に使用する場合にはクライアント環境に注意が必要となります。

どのように複数受け取るか

multipartリクエストの場合には、文字通り複数のPartが送られてきます。multipleで複数のファイルを選択した場合にはそのname属性の値で指定ファイルの数のPartだけデータが送信されてきます。name属性をfilesとし、3つのファイルを選択した場合にはnameがfilesのPartが3つ送信されてきます。

実装

実装は2つのファイルだけです。
index.jsp

<%@page language="java" contentType="text/html; charset=utf-8"%>
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>ファイルアップロード</title>
 </head>
 <body>
  <form action="/app/upload" enctype="multipart/form-data" method="post">
   <input type="file" name="files" multiple><br>
   <input type="submit" value="送信">
  </form>
<%
    String upload_files = (String) request.getAttribute("upload_files");
    if (upload_files != null) {
%>
<br>
<span style="color: #ff0000;">以下のファイルがアップロードされました。</span><br>
<%= upload_files %>
<%
    }
%>
 </body>
</html>

UploadServlet
MultipartConfigのlocation属性の値の場所にファイルが保管されますので、絶対パスで任意の場所に変更してください。

package net.kuwalab;

import java.io.IOException;
import java.util.Enumeration;

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(name = "Upload", urlPatterns = { "/upload" })
@MultipartConfig(fileSizeThreshold = 5000000, maxFileSize = 10000000, location = "e:/temp")
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void processRequest(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        StringBuilder sb = new StringBuilder();
        for (Part part : request.getParts()) {
            if (part.getName().equals("files")) {
                String name = getFilename(part);
                part.write(name);
                sb.append(name).append("<br>");
            }
        }
        request.setAttribute("upload_files", sb.toString());

        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        processRequest(request, response);
    }

    private String getFilename(Part part) {
        for (String cd : part.getHeader("Content-Disposition").split(";")) {
            if (cd.trim().startsWith("filename")) {
                return cd.substring(cd.indexOf('=') + 1).trim()
                        .replace("\"", "");
            }
        }

        return null;
    }
}