今日の役に立たない一言 - Today’s Trifle! -

古い記事ではさまざまなテーマを書いていますが、2007年以降はプログラミング関連の話がほとんどです。

enctype="multipart/form-data"にするとreqeust.getParameter()がnullを返す問題の対策

というか、slim3だとgetParameter()は取れるけど、getParameterValues()がnullになって困った。

JSPはこんなん。

<form id="form" action="/hoge" enctype="multipart/form-data" method="post" >
  <input type="text" name="name" />
  <input type="file" name="image" accept="image/*" />
  <c:forEach var="o" items="${checks}">
    <span><input id="checks_${o.id}" type="checkbox" name="checks" value="${o.id}" ${o.checked} >
    <label>${o.name}</label></span>
  </c:forEach>
  <input type="submit" value="send" />
</form>

ぐぐるとcommons-fileupload 使えばできるとかあったけど、slim3だと相性のせいなのかできなかった。

ajaxで2回に分けてpostするようにした。
JSPのフォームからenctypeを削除しとく。
Servlet側で区別できるようにhiddenを追加しとく。

<form id="form" action="/hoge" method="post" >
  <input type="text" name="name" />
  <input type="file" name="image" accept="image/*" />
  <c:forEach var="o" items="${checks}">
    <span><input id="checks_${o.id}" type="checkbox" name="checks" value="${o.id}" ${o.checked} >
    <label>${o.name}</label></span>
  </c:forEach>
  <input type="hidden" name="upload" value="no" />
  <input type="button" value="send" onclick="send()" />
</form>

JavaScriptがこんなん。
1回目のpostではfileをdisabledにして無視させる。
2回めのpost前にenctypeを追加する。
しなくてもよさそうだけど、file以外のinputをdisabledにしとく。
hiddenの値も、念のために空文字列にしとく。

function send() {
    $('input[type=file]').prop('disabled', true);
    $.ajax({
        type: 'post',
        data: $('#form').serialize(),
        success: function (data) {
            upload();
        }
    });
}

function upload() {
    $('input').prop('disabled', true);
    $('input[type=file]').prop('disabled', false);
    $('input[type=hidden]').val('');
    $('#form').prop('enctype', 'multipart/form-data');
    $('#form').submit();
}

Servlet側は getParameter("upload") の有無で処理を切り分ける。

    String s = request.getParameter("upload");
    if (s == null || s.isEmpty()) {
        // ファイルを受信
    } else
    if (s.equals("no")) {
        // 入力フォームの値を取得
    }