Issue
I am new to front-end development and am having troubles piecing together a solution for this specific form setup.
I have an already created jsp representing this instance creation page. It's a form containing numerous drop downs and check boxes. I need to add a file upload option to it.
The jsp is set up like this...
<form class="form-horizontal" id="editInstanceForm" onsubmit="return false;"> ....
Here's my input field
<div class="form-group" id="uploadForm">
<label class="col-xs-4 control-label instanceDefaultLabel" for="fileSearchField">Default Location and Zoom:</label>
<div class="col-xs-3">
<input name="myFile" type="file" id="fileSearchField" multiple=false>
<button id="upload-button">Upload</button>
</div>
.....
</div>
Now I have an ajax call that I was originally wanting to use before I realized that the whole form is attempting to submit when I uploaded the file. Here it is...
$('#upload-button').click( 'click',
function() {
var form = $('#fileSearchField')[0];
var data = new FormData(form);
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/edit/uploadfile",
data: data,
processData: false,
contentType: false,
cache: false,
success: function (data) {
alert("hi stuff worked");
},
error: function (e) {
alert("nope!");
}
});
}
);
I got this suggestion in researching how to upload a file with jQuery/ajax and Spring Boot (I am using Spring Boot to create my endpoint). Here are some articles that I have been reading in an attempt to understand how to do this...
https://www.mkyong.com/spring-boot/spring-boot-file-upload-example-ajax-and-rest/
and many more. This seemed like the solution until I realized this was a form and I think I need to save all the fields at once. This is going to mean that I have to modify the already created ajax function that saves this form and passes it to the end point. Now I don't know how to get my MulitpartFile in as part of this different function. The existing one is like this...
$.ajax({
type: "POST",
url: webroot + "/viewerConfig/mapInstance/insertOrUpdate",
data: JSON.stringify(instanceData),
processData: false,
contentType: 'application/json',
success: function (data) {
if (data.status === "OK") {
alert("Instance created/updated successfully");
} else {
alert("Unknown error");
}
},
fail: function () {
alert("Unknown error");
},
error: function (a) {
alert("Unknown error");
}
});
});
This is exactly where I am stuck and I need to be pointed in the correct and productive direction.
I don't know if this will help but here's my end point that looks like the one I have to hit with my file param added...
@RequestMapping(value = "/insertOrUpdate", method = RequestMethod.POST, consumes = "application/json")
public @ResponseBody BaseStatusResponse insertOrUpdate(final @RequestBody SaveAdminInstanceView newInstance, HttpServletResponse servletResponse,
@RequestParam MultipartFile file)
EDIT: I have done some curl troubleshooting and it's the MulitpartFile that's failing. I am passing it as suggested yet I am getting this exception:
org.springframework.web.multipart.MultipartException: The current request is not a multipart request</p><p><b>Description</b> The server encountered an unexpected condition that prevented it from fulfilling the request.</p><p><b>Exception</b></p><pre>org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: The current request is not a multipart request
Solution
You can try below code:
$.ajax({
url: "/edit/uploadfile",
type: 'POST',
data: new FormData($(this)[0]),
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
cache: false,
success: function(res) {
console.log(res);
},
error: function(res) {
console.log('ERR: ' + res);
}
});
And in controller, you needn't declare consumes = "application/json"
Answered By - yuen26
Answer Checked By - Marilyn (JavaFixing Volunteer)