Как я могу отправить форму и загрузить файл с помощью ajax на контроллер Spring?

У меня есть форма, которая содержит четыре поля: файл, имя, тип (просто строка) и 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, я создаю новую функцию контроллера...

@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 выглядят так до публикации...

введите здесь описание изображения

Но как только он достигает сервера, все становится нулевым...

введите здесь описание изображения


person OneTwo    schedule 24.06.2015    source источник
comment
Да, выглядит хорошо, за исключением вашего submitForm в случае успеха вашего jQuery.ajax вызова. Не уверен, что делает submitForm, но он больше не должен отправлять форму, поскольку вы уже отправили данные с запросом ajax. В случае успеха вы вызываете то, что должно быть сделано, если данные формы были обработаны, и у вас есть успешный ответ от сервера.   -  person Bernhard    schedule 24.06.2015
comment
Не обращайте на это внимания, я просто еще не добрался до этого этапа. Проблема, с которой я столкнулся сейчас, заключается в том, что я получаю ошибку 404 при попытке отправить ajax, и я понятия не имею, почему?   -  person OneTwo    schedule 24.06.2015


Ответы (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}
}

Надеюсь, это поможет, пожалуйста, дайте мне знать, если вы все еще не понимаете

person Theunis    schedule 24.06.2015
comment
Спасибо за это, похоже, это более чистый способ сделать это, и он избавился от моей ошибки 404. Но по какой-то причине данные, которые достигают сервера, равны нулю. Я обновил свой основной пост новым кодом, который я использую... - person OneTwo; 24.06.2015