ファイルアップロードのサンプル

前回2015-10-25 - tomoTakaの日記の続きですが、サーバにアップする処理も実装しました。

画面

  • ファイルアップをする画面

この画面で指定したファイルを、Destinationで指定したディレクトリに保存。

  • ファイルアップした結果の画面

ファイルの保存が成功した場合、この画面に遷移して保存先のパスを確認。

アップしたファイルを確認

上記処理で行ったファイルアップロードが、指定したフォルダに保存されていることを確認。

実装

  • fileupload.html

ここでは、以下の2点がポイント。
methodは「POST」、enctypeは、「multipart/form-data」

                <form method="POST" action="upload" enctype="multipart/form-data">
                    <input type="file" name="file">
                    <label class="label-info">Destination:</label>
                    <input type="text" value="/tmp" name="destination" id="destination">
                    <button type="submit" class="btn btn-primary">upload</button>
                </form>

サーブレト側は、@WebServletと@MultipartConfigを指定。
htmlで「enctype="multipart/form-data"」を指定している場合「@MultipartConfig」アノテーションを指定しないと「request.getPart」でエラーになりました。
アップしたファイルは、「part.getInputStream()」で取得できるので、保存するのに「Files.copy」を使用してみました。

@WebServlet(urlPatterns = {"/upload"})
@MultipartConfig
public class Upload extends HttpServlet {

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 保存先のディレクターを取得
        String destination = request.getParameter("destination");
        Part part = request.getPart("file");
        String fileName = getFielName(part);
        Path filePath = Paths.get(destination + File.separator + fileName);
        // アップしたファイルを取得して、保存
        InputStream in = part.getInputStream();
        Files.copy(in, filePath, StandardCopyOption.REPLACE_EXISTING);
        // 画面遷移先で保存したファイルパスを表示
        response.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet Upload</title>");            
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>File upload result</h1>");
            out.println("<div>");
            out.println("upload succeed[file path:" + filePath + "]"); 
            out.println("<div>");
            out.println("</body>");
            out.println("</html>");
        }
    }
...
    private String getFielName(Part part) {
        String header = part.getHeader("content-disposition");
        System.out.println("***" + header);
        String[] split = header.split(";");
        // headerは、以下の内容になっているので、ここからfilenameである「fileupload.png」を取得
        // form-data; name="file"; filename="fileupload.png"
        String fileName =
                Arrays.asList(split).stream()
                        .filter(s -> s.trim().startsWith("filename"))
                        .collect(Collectors.joining());
        return fileName.substring(fileName.indexOf("=") + 1).replace("\"", "");
    }

今回は、サーブレットのRequestからPartを使ってファイルをアップできることを知らなかったので、勉強になりました。
画面遷移しない実装にも次回挑戦したいです!
まだ途中ですが、とりあえずここtomoTaka01/FileUploadWeb · GitHubにアップ。