【问题标题】:How can I submit a form and upload a file using ajax to a spring controller?如何使用 ajax 提交表单并将文件上传到 spring 控制器?
【发布时间】:2015-06-24 11:21:35
【问题描述】:

我有一个包含四个字段的表单,文件、名称、类型(只是一个字符串)和 taskInstanceId。

<form>
   <table id="documentDetailsTable">
       <tr>
           <td>Document Type: </td>
           <td><select id="documentType" name="type"> </select></td>
       </tr>
       <tr>
           <td>
              Document Name:
           </td>
           <td>
              <input type="text" id="documentName" name="name"/>
           </td>
       </tr>
       <tr id="newFile">
           <td>
              Choose a file:
           </td>
           <td>
               <input type="file" name="file" />
           </td>
    </table>
    <input type="text" style="display: none;" name="taskInstanceId" id="taskInstanceId">

     <input id="uploadButton" value="Upload" type="submit"/>
     <input class="closeButton" id="closeNew" value="Close" type="button"/>
 </form>

如果我提交此表单,它将连接到我的 FileUploadController 并上传文件。

@RequestMapping(value = "/formTask.do", method = RequestMethod.POST)
public ModelAndView handleFormTaskUpload(@RequestParam("name") String name,
        @RequestParam("type") String type,
        @RequestParam("file") MultipartFile file,
        @RequestParam("taskInstanceId") int taskInstanceId)...//rest of the code

现在我想使用 jquery/json 提交此表单,以便我可以返回一个指示成功上传的字符串,然后在页面上显示一个对话框来指示这一点。 (我不想返回新的 ModelAndView)。

所以我使用相同的 html 表单创建了一个新的 Controller 函数...

@RequestMapping(value = "/formTask2.json", method = RequestMethod.POST)
public String handleFormTaskUpload2(UploadTaskDocument myNewUpload)).../rest of the code

现在我想使用 jQuery 提交上面的表单。我的尝试就在这里。

每次更改文件时都会调用此函数。

function prepareUpload(event)
{
    files = event.target.files;
}

并且这个是在表单提交的时候调用的。

function uploadFiles(event)
{
event.stopPropagation(); // Stop stuff happening
event.preventDefault(); // Totally stop stuff happening

var data;
data = {
    documentName: $("#documentName").val(),
    documentType: $("#documentType").val(),
    taskInstanceId: selectedTaskInstanceId,
    uploadedfiles: files
};
var json = JSON.stringify(data);
$.ajax({
    url: '/SafeSiteLive/formTask2.json',
    type: 'POST',
    data: json,
    cache: false,
    dataType: 'json',
    processData: false, // Don't process the files
    contentType: false, // Set content type to false as jQuery will tell the server its a query string request
    success: function (data, textStatus, jqXHR)
    {
        if (typeof data.error === 'undefined')
        {
            // Success so call function to process the form
            //submitForm(event, data);
        }
        else
        {
            // Handle errors here
            console.log('ERRORS: ' + data.error);
        }
    },
    error: function (jqXHR, textStatus, errorThrown)
    {
        // Handle errors here
        console.log('ERRORS: ' + textStatus);
        // STOP LOADING SPINNER
    }
});
}

Json 数据在发布之前看起来像这样......

但是一旦它到达服务器,一切都是空的......

【问题讨论】:

  • 是的,看起来没问题,除了你的submitForm 在你的jQuery.ajax 调用的成功案例中。不确定submitForm 做了什么,但它不能再提交表单,因为您确实已经使用 ajax 请求发送了数据。在成功案例中,如果表单数据已处理并且您从服务器获得成功响应,则调用应该执行的操作。
  • 忽略这一点,我还没有编写那个阶段的代码。我现在遇到的问题是尝试提交 ajax 时出现 404 错误,我不知道为什么?

标签: javascript jquery ajax spring-mvc spring-form


【解决方案1】:

好的,这可能与您的解决方案有点不同,但我会继续执行以下操作。

据我了解,您希望使用 ajax 将数据上传到您的控制器并避免回发,然后返回一个字符串,而只返回一个字符串。我会这样做。

你有你的表格:

<form> //Remove the method type as well as where the post should happen to ensure that you do not have to prevent default behavior
   <table id="documentDetailsTable">
       <tr>
           <td>Document Type: </td>
           <td><select id="documentType" name="type"> </select></td>
       </tr>
       <tr>
           <td>
              Document Name:
           </td>
           <td>
              <input type="text" id="documentName" name="name"/>
           </td>
       </tr>
       <tr id="newFile">
           <td>
              Choose a file:
           </td>
           <td>
               <input type="file" name="file" />
           </td>
    </table>
    <input type="text" style="display: none;" name="taskInstanceId" id="taskInstanceId">

     <input id="uploadButton" value="Upload" onclick('uploadFiles()')/> //Add //the event to your submit button and remove the submit from itself
     <input class="closeButton" id="closeNew" value="Close" type="button"/>
 </form>

你的 JQuery:

//Stays the same I would suggest using a object type and then stringify it as follows
function uploadFiles(event)
{
event.stopPropagation(); // Stop stuff happening
event.preventDefault(); // Totally stop stuff happening

// START A LOADING SPINNER HERE

// Create a formdata object and add the files
//var data = new FormData();
//.each(files, function (key, value)
//{
//    data.append(key, value);
//});
//data.append('documentName', $("#documentName").val());
//data.append('documentType', $("#documentType").val());
//data.append('taskInstanceId', $("#taskInstanceId").val());

// Create a objectobject and add the files
var data;
data = {
    documentName:$("#documentName").val(),
    documentType:$("#documentType").val(),
    taskInstanceId:$("#taskInstanceId").val(),
    uploadedfiles: files
}
var json = JSON.stringify(data);
$.ajax({
    url: '/SafeSiteLive/formTask2.do',
    type: 'POST',
    data: json,
    cache: false,
    dataType: 'json',
    processData: false, // Don't process the files
    contentType: false, // Set content type to false as jQuery will tell the server its a query string request
    success: function (data, textStatus, jqXHR)
    {
        if (typeof data.error === 'undefined')
        {
            // Success so call function to process the form
            submitForm(event, data);
        }
        else
        {
            // Handle errors here
            console.log('ERRORS: ' + data.error);
        }
    },
    error: function (jqXHR, textStatus, errorThrown)
    {
        // Handle errors here
        console.log('ERRORS: ' + textStatus);
        // STOP LOADING SPINNER
    }
});
}

在您的控制器中:

当您使用 MVC 时,请使用模型,因为它是捕获参数的正确方式。

public String handleFormTaskUpload2(UploadedFile mynewUpload )
{
//rest of code here
}

然后,您的模型将看起来像这样。

public class UploadedFile
{
   public string documentName{get;set}
   public string documentType{get;set}
   public string taskInstanceId{get;set}
   prop List<byte[]> files {get;set}
}

希望对你有帮助,如果你还是不明白,请告诉我

【讨论】:

  • 感谢您,这看起来是一种更清洁的方式,它消除了我的 404 错误。但由于某种原因,到达服务器的数据为空。我已经用我正在使用的新代码更新了我的主要帖子......
猜你喜欢
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多