ファイルアップロードのサンプル
前回2015-10-25 - tomoTakaの日記の続きですが、サーバにアップする処理も実装しました。
実装
- 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>
- upload.java
サーブレト側は、@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にアップ。