web-dev-qa-db-ja.com

JSP / ServletとAjaxを使用してサーバーにファイルをアップロードする方法は?

JSP/Servlet Webアプリケーションを作成していますが、Ajax経由でファイルをサーブレットにアップロードしたいと思います。これをどうやってやるの? jQueryを使用しています。

これまでにやったこと:

<form class="upload-box">
    <input type="file" id="file" name="file1" />
    <span id="upload-error" class="error" />
    <input type="submit" id="upload-button" value="upload" />
</form>

このjQueryの場合:

$(document).on("#upload-button", "click", function() {
    $.ajax({
        type: "POST",
        url: "/Upload",
        async: true,
        data: $(".upload-box").serialize(),
        contentType: "multipart/form-data",
        processData: false,
        success: function(msg) {
            alert("File has been uploaded successfully");
        },
        error:function(msg) {
            $("#upload-error").html("Couldn't upload file");
        }
    });
});

ただし、ファイルの内容を送信するようには見えません。

18
Nayish

要するに、jQueryで使用されている現在のXMLHttpRequestバージョン1の時点では、XMLHttpRequestを介してJavaScriptを使用してファイルをアップロードすることはnot可能です。一般的な回避策は、JavaScriptに隠された<iframe>を作成させ、代わりにフォームを送信して、非同期に発生する印象を作成することです。 jQuery Form pluginここの例 )のように、jQueryファイルアップロードプラグインの大部分が行っていることもまさにこれです。

HTMLフォームを使用したJSPが、クライアントでJSが無効になっているときにbrokenにならないように書き換えられていると仮定します(現在のように...) )、以下のように:

<form id="upload-form" class="upload-box" action="/Upload" method="post" enctype="multipart/form-data">
    <input type="file" id="file" name="file1" />
    <span id="upload-error" class="error">${uploadError}</span>
    <input type="submit" id="upload-button" value="upload" />
</form>

次に、jQuery Formプラグインの助けを借りて、

<script src="jquery.js"></script>
<script src="jquery.form.js"></script>
<script>
    $(function() {
        $('#upload-form').ajaxForm({
            success: function(msg) {
                alert("File has been uploaded successfully");
            },
            error: function(msg) {
                $("#upload-error").text("Couldn't upload file");
            }
        });
    });
</script>

サーブレット側に関しては、ここで特別なことをする必要はありません。 Ajaxを使用しない場合とまったく同じ方法で実装します。 JSP/Servletを使用してサーバーにファイルをアップロードする方法

X-Requested-WithヘッダーがXMLHttpRequestに等しいかどうかだけがサーブレットでの追加チェックが必要になります。これにより、クライアントがJSを無効にしている場合にどのような応答を返すかがわかります(現時点では、 JSが無効になっているのは、主に古いモバイルブラウザです。

if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
    // Return ajax response (e.g. write JSON or XML).
} else {
    // Return regular response (e.g. forward to JSP).
}

比較的新しいXMLHttpRequestバージョン2は、新しいFileおよびFormData APIを使用して、選択したファイルを送信できることに注意してください。 HTML5 File Upload to Java Servlet および xmlHttpRequestを介してファイルをマルチパートとして送信 も参照してください。

21
BalusC

@Monsifのコードは、フォームにファイルタイプの入力のみがある場合に機能し、ファイルタイプ以外の入力が他にある場合、それらは失われます。そのため、各フォームデータをコピーしてFormDataオブジェクトに追加する代わりに、元のフォーム自体をコンストラクターに渡すことができます。

@Monsifのコードと https://www.new-bamboo.co.uk/blog/2012/01/10/ridiculously-simple-ajax-uploads-with-formdata/ post、Iについて私のために働いた次のコードが出てきました。他の人の助けになることを願っています。

<script type="text/javascript">
        var files = null; // when files input changes this will be initiliazed.
        $(function() {
            $('#form2Submit').on('submit', uploadFile);
    });

        function uploadFile(event) {
            event.stopPropagation();
            event.preventDefault();
            //var files = files;
            var form = document.getElementById('form2Submit');
            var data = new FormData(form);
            postFilesData(data);
}

        function postFilesData(data) {
            $.ajax({
                url :  'yourUrl',
                type : 'POST',
                data : data,
                cache : false,
                dataType : 'json',
                processData : false,
                contentType : false,
                success : function(data, textStatus, jqXHR) {
                    alert(data);
                },
                error : function(jqXHR, textStatus, errorThrown) {
                    alert('ERRORS: ' + textStatus);
                }
            });
        }
</script>

Htmlコードは次のようになります。

<form id ="form2Submit" action="yourUrl">
  First name:<br>
  <input type="text" name="firstname" value="Mickey">
  <br>
  Last name:<br>
  <input type="text" name="lastname" value="Mouse">
  <br>
<input id="fileSelect" name="fileSelect[]" type="file" multiple accept=".xml,txt">
<br>
  <input type="submit" value="Submit">
</form>
3
Memin

このコードは私のためにうまくいきます:

$('#fileUploader').on('change', uploadFile);


function uploadFile(event)
        {
            event.stopPropagation(); 
            event.preventDefault(); 
            var files = event.target.files; 
            var data = new FormData();
            $.each(files, function(key, value)
            {
                data.append(key, value);
            });
            postFilesData(data); 
         }
        
function postFilesData(data)
        {
         $.ajax({
        url: 'yourUrl',
        type: 'POST',
        data: data,
        cache: false,
        dataType: 'json',
        processData: false, 
        contentType: false, 
        success: function(data, textStatus, jqXHR)
        {
                //success
        },
        error: function(jqXHR, textStatus, errorThrown)
        {
            console.log('ERRORS: ' + textStatus);
        }
            });
        }
<form method="POST" enctype="multipart/form-data">
        <input type="file" name="file" id="fileUploader"/>
</form>
2