在 AJAX post 请求中使用自定义 HttpServletRequest 过滤器

Use custom HttpServletRequest Filter in AJAX post request

我为 HttpServletRequest 创建了一个自定义 MultipartFilter,使用 this example 将任何类型的文件从客户端上传到我的数据库。

表单是一个 multipart/form-data 表单,放置在 modal 中,以其他形式显示:

<!-- MAIN FORM -->
<form:form>
    <button // this button shows the modal
</form:form>

<!-- MODAL TO UPLOAD FILES -->
<div class="modal fade" id="myModal" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
    <form action="documentoSubmit" method="post" id="documentoForm" enctype="multipart/form-data">

我可以通过两种方式提交我的表单并通过我的自定义过滤器找到正确的字段和其他字段:

a) 按钮onchange方法和javascript函数:

<button type="button" class="btn btn-primary" onclick="validarDocumento()">
    <spring:message code="guardar" />
</button>

function validarDocumento() {
    // check if valid data
    $("#myform").submit();
}

b) 输入域(也可以是<button>):

<input type="submit" class="btn btn-default" >

这工作正常,但我的问题是父表单,其中包含正在重新加载表单的模态,我需要捕获结果以通过 AJAX WITHOUT 更新我的视图 正在重新加载表格。

任何与此类似的东西,但应用了 我的自定义 java Filter

$.post( "<%=session.getAttribute("URL_HOST")%>/my/url/documentoSubmit", {})
.done(function(data) {
    // do stuff...
}

$("#myForm").submit().done(function (data){
    // do stuff...
});

$("#myForm").submit(function (data){
    // do stuff...
});

您可以尝试使用 iframe 的方法。制作隐藏的假框架并为加载的 iframe 回调。

<form action="youAction" method="post" id="documentoForm" target = "fake-frame" enctype="multipart/form-data"></form>
<iframe id="fake-frame" name="fake-frame" style="display: none"></iframe>

还有回调:

iframe.load(function () {
/*you may pass some special content to detect file loaded { status = "success" }*/
}

我建议使用 fileReader、FormData 和 XMLHTTPRequest API。示例:

// button click to submit
<button type="button" class="btn btn-primary" onclick="validarDocumento()">
//input change
<input name="file" onchange='readFile'>

//global vars
       var data = new FormData(),
       reader - new FileReader(),
       xhr =  new XMLHttpRequest();    
//considering the example, you could validate file and read as binary or a base64 decoded file before upload
function readFile(e){
 file = e.target.files[0]; // reads the file input change event and returns array
 var binaryFile = reader.readAsBinaryString(file); // file reader gets file as binary
 reader.onloadend(function(e){
   //check reader data
   data.append('file', binaryFile);
 });
}
function validarDocumento(){
  // validate document and other inputs
 xhr.upload.onprogress =  function(event){
   // event that checks for progress on upload;
 };
 xhr.onload = function(e){
 // check for server responce on event and refresh view
 };
 xhr.open("POST","<%=session.getAttribute("URL_HOST")%>/my/url/documentoSubmit",true);
 xhr.send(data);
}

虽然这可能需要一些调整才能与您一起工作,但我希望它是一个简单的示例,它能为您指明正确的方向。这有助于您提交表单并通过 java 脚本检查何时刷新您的视图/考虑到文件将保留在圆顶中,因为没有刷新,可能会重置您的输入。

另请查看您可能能够读取文件的其他方式,以帮助匹配 java 服务器预期数据

你的代码问题出在这个函数中

function validarDocumento() {
    // check if valid data
    $("#myform").submit();
}

调用 jquery 元素的 submit() 将实际提交表单,这是一个同步请求,因此页面被刷新。为防止这种情况,您必须通过 AJAX 上传文件,不用担心您的自定义过滤器仍会工作,因为它基本上会拦截每个传入请求(synchronous/asynchronous 无关紧要)到您的服务器。

如果你不想使用JQuery,你可以这样做

<input type="file" id="uploadfile" name="uploadfile" />

$('.btn btn-primary').on('submit', function(event){
    event.stopPropagation(); // Stop propagating submit event to your parent form
    event.preventDefault(); // Stop form's default action in your modal

    var data = new FormData();
    var file = document.getElementById("uploadfile");
    formData.append("upload", file.files[0]);
    // append other form fields to formData

         $.ajax({
              url: 'ur-action-to-upload-file',
              type: 'POST',
              data: data,
              cache: false,
              dataType: 'json',
              processData: false,
              contentType: 'multipart/form-data' 
         }).done(function(data,jqXHR){
                if(jqXHR.status == 200){
                 // handle your success flow
                }
         });
});

有几点需要注意,

  • processData - 如果您有文件,请将此设置为 false,因为 jQuery 将 将文件数组转换为字符串,服务器无法选择它 向上。
  • contentType - 如果 multipart/form-data 不起作用,将其设置为 false 但不要保留它,因为 jQuery 默认为 application/x-www-form-urlencoded 并且不发送文件

如果您需要更多示例,请参阅 this and this