LoginSignup
0
1

More than 5 years have passed since last update.

FormDataオブジェクトとCommons FileUploadでformデータをServletに送信・処理

Last updated at Posted at 2018-12-29

1. 目的と仕様

  1. Java Webアプリケーション(Servlet, JSP)において,JSP内のformに入力された情報(e.g. ユーザネーム, パスワード, 画像)をサーバ(Servlet)にHTTPリクエストで送信する
  2. form送信前に入力内容を確認し,不備があれば送信しない.そのため動的な処理が必要
  3. Content-Type : multipart/form-data の場合Servletでリクエストパラメータが取得できないため,フィールドとファイルを同時に取得する方法が必要

スクリーンショット 2018-12-29 17.48.21.png

2. 方法

  • JavaScript
    • FormDataオブジェクトでformデータを動的に処理
  • Servlet
    • Apache Commons FileUploadを用いて受け取ったformデータをフィールドとファイルに分けて処理

3. 環境と準備

4. 実装

sample.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Sample</title>
</head>
<body>
    <form id="form">
    Username : <input type="text" id="username" name="username"><br>
    Password : <input type="password" id="password" name="password"><br>
    Image :  <input type="file" id="image" name="image" accept="image/*"><br>
    <input type="submit" value="send">
    </form>
</body>
<script type="text/javascript" src="sample.js"></script>
</html>
sample.js
// formオブジェクトの作成
var form = document.getElementById("form");
// submitイベントが起きたときの処理
form.addEventListener("submit", function(event) {
    // formのデフォルト機能を消し,JavaScriptで管理
    event.preventDefault();
    check();
});

function check() {
    // formのvalueを取ってくる
    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;
    var image = document.getElementById("image").value;

    // 入力されている場合送信
    if (username != "" && password != "" && image != "") {
        sendData();
    } else {
        alert("Please input all item.");
    }
}

function sendData() {
    // FormDataオブジェクトの作成
    var formData = new FormData(form);
    // XMLHttpRequestでHTTPリクエストを送る
    var req = new XMLHttpRequest();

    // 送受信が完了した場合の処理
    req.addEventListener("load", function(event) {
        if (req.responseText == "done") {
            // 処理が成功した場合の処理
            alert("Succeeded.");
        } else {
            alert("Failed to send.");
        }
    });
    // 送受信が失敗した場合の処理
    req.addEventListener("error", function(event) {
        alert("Error");
    });

    // HTTPリクエストの設定
    req.open("POST", "/sample/SampleServlet"); // /application名/Servlet名
    // リクエストを送信
    req.send(formData);
}
SampleServlet.java
package controller;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("/SampleServlet")
public class SampleServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public SampleServlet() {
        super();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");

        // レスポンステキスト
        String responseText = "done";

        // DiskFileItemFactoryからServletFileUploadを作成
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload sfu = new ServletFileUpload(factory);

        try {
            // リクエストのformデータをリストに格納
            List list = sfu.parseRequest(request);
            for (Object o : list) {
                // formデータの1つ1つをFileItemとして扱う
                FileItem item = (FileItem) o;
                // FileItemがフィールドかファイルかで分岐
                if (item.isFormField()) {
                    // フィールドの場合,フィールドネームとvalueを取得
                    // (form内の<input name="フィールドネーム" value="入力内容")
                    String fieldName = item.getFieldName();
                    String value = item.getString();
                    if (fieldName.equals("username")) {
                        // ユーザネームの処理
                        System.out.println("username : " + value);
                    } else if (fieldName.equals("password")){
                        // パスワードの処理
                        System.out.println("password : " + value);
                    }
                } else {
                    File file = new File(item.getName());
                    try {
                        String dirPath = "イメージファイルの保存先";
                        String filePath = dirPath + File.separator + file.getName();
                        // イメージファイルを保存
                        item.write(new File(filePath));
                    } catch (IOException e) {
                        e.printStackTrace();
                        responseText = "error";
                    } catch (Exception e) {
                        e.printStackTrace();
                        responseText = "error";
                    }
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
            responseText = "error";
        }
        // レスポンスの送信
        response.getWriter().print(responseText);
    }
}

6. 結果

入力されていない場合
スクリーンショット 2018-12-29 17.49.27.png

全項目が入力されている場合
スクリーンショット 2018-12-29 17.49.49.png

5. 参考

JavaScript
- XMLHttpRequest : https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
- FormDataオブジェクト : https://developer.mozilla.org/ja/docs/Web/Guide/Using_FormData_Objects

Servlet
- commons fileUpload
- http://commons.apache.org/proper/commons-fileupload/using.html
- https://www.javadrive.jp/servlet/fileupload_tutorial/index4.html
- https://www.javadrive.jp/servlet/fileupload_tutorial/index5.html
- http://www.ne.jp/asahi/hishidama/home/tech/apache/commons/fileup.html

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1