I am struggling with Multipart file upload in Spring controller. I've read multiple questions, googles, but nothing seems to work.
I get
error: "Bad Request"
exception: "org.springframework.web.multipart.support.MissingServletRequestPartException"
message: "Required request part 'file' is not present"
My BE controller:
#RequestMapping(value = "/zip", method = RequestMethod.POST)
public void readFile(#RequestParam("file") MultipartFile file) throws IOException {
// code
}
FE, angularJS:
service.getZip = function getZip(file) {
var formData = new FormData();
formData.append('file', file);
return $http({
method: 'POST',
url: CONSTANTS.readFile,
data: formData,
headers: {'Content-Type': undefined}
}) .then(function (response) {
var data = response.data;
return data.id;
});
}
HTML:
<input type="file" id="file" name="file" accept=".txt"/>
also application.properties contain:
spring.http.multipart.enabled=false
UPDATE:
I no longer get that error when following #Byeon0gam advice to remove #RequestParam from my controller, but the my file is null as it comes to controller. Although in FE service, as I see, it's not empty:
change the Content-Type in your FE to:
headers: {'Content-Type': 'x-www-form-urlencoded'}
hope it will work for you.
Related
I'm trying to hit the Spring RestController and just getting:
o.s.web.servlet.PageNotFound : Request method 'POST' not supported
I believe something is missing to map the controller.
<div class="col-sm-1" style="background-color:#cccccc;" align="center"><span class="file-input btn btn-primary btn-file">Import file<input type="file" onchange="angular.element(this).scope().uploadScriptFile(this.files)"></input></span></div>
$scope.uploadCtrFile = function(files) {
console.log(">>>>>>>>>>>>>>>>uploadCtrFile");
var fd = new FormData();
//Take the first selected file
fd.append("file", files[0]);
console.log(">>>>>>>>>>>>>>>>uploadCtrFile angular.toJson: "
+ angular.toJson(fd, 2));
$http.post('/rest/uploadCtrFile/', fd,{
withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success(function(fd, status, headers, config) {
$scope.success = ">>>>>>>>>>>>>>>>uploadCtrFile Success: "+JSON.stringify({data: fd});
console.log($scope.success);
})
.error(function(fd, status, headers, config) {
$scope.success = ( "failure message: " + JSON.stringify({data: fd}));
console.log($scope.success);
});
};
The controller looks like...
#RequestMapping(value = "/uploadCtrFile/", headers = "'Content-Type': 'multipart/form-data'", method = RequestMethod.POST)
#ResponseBody
public void uploadCtrFile(MultipartHttpServletRequest request, HttpServletResponse response) {
Iterator<String> itr=request.getFileNames();
MultipartFile file=request.getFile(itr.next());
String fileName=file.getOriginalFilename();
log.debug(">>>>>>>>>>>>>>>>>>>submitted uploadCtrFile: "+fileName);
}
The front end shows these messages...
">>>>>>>>>>>>>>>>uploadCtrFile angular.toJson: {}" tl1gen.js:607:0
"failure message: {"data": {"timestamp":1457380766467,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/rest/uploadCtrFile/"}}"
What am I missing ?
You send undefined as the value of Content-Type, here:
headers: {'Content-Type': undefined }
But your controller requires the Content-Type with multipart/form-data value:
#RequestMapping(..., headers = "'Content-Type': 'multipart/form-data'", ...)
You should either send the correct Content-Type header in your request, like:
headers: {'Content-Type': 'multipart/form-data'}
or remove the headers options from your controller definition:
#RequestMapping(value = "/uploadCtrFile/", method = RequestMethod.POST)
I'm trying to post a JSON Object, with Ajax, to an Rest Spring MVC Controller, but I met some troubles.
Let's present you my code:
Controller
#RequestMapping(value = "/register/checkUsername.html", method = RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody JsonResponse checkUsername(#RequestBody JsonUsername username) {
String usernameString = username.getUsername();
JsonResponse response = new JsonResponse();
response.setMessage(usernameString + "Available");
return response;
}
Ajax Function
function displayUsernamError(data) {
var json = "<h4>Eroare</h4><pre>"
+ JSON.stringify(data, null, 4) + "</pre>";
$('#usernameError').html(json);
}
function checkUsername(){
var username = document.getElementById("username");
var search = {
"username" : username.value
}
$.ajax({
type : "POST",
contentType : 'application/json; charset=utf-8',
dataType : 'json',
url : "http://localhost:8080/skill-assessment/register/checkUsername.html",
data : JSON.stringify(search),
success : function(result) {
console.log("SUCCESS: ", data);
displayUsernamError(result);
},
error: function(e){
console.log("ERROR: ", e);
displayUsernamError(e);
},
done : function(e) {
console.log("DONE");
}
});
}
And finally the html form:
<form:form modelAttribute="user" method="POST" enctype="utf8">
<tr>
<td><label>Username</label></td>
<td><form:input path="name" id="username" /></td>
<td>
<p id="usernameError">
</p>
</td>
</tr>
<button type="button" onClick="checkUsername()">Register</button>
</form:form>
So, I'm calling the checkUsername method when I press click on the Register button, only for test.
The ajax function is called and this send the JSON to the controller. I used the debug and the controller seems to get the JSON Object.
The problem is with the controller Response, because in the error div from my html page, I get this error:
HTTP Status 406
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request \"accept\" headers.
Where is the problem? Who can give me an idea?
You need to specify the below code inside of the request mapping annotation
#RequestMapping(value = "/register/checkUsername.html", method = RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE)
you no need to specify the produces attribute because #Responsebody will produce the content based on the request object content type[optional]. if you want other then it then only you have to mention it.
; charset=utf-8 is the default one in Ajax call. you no need mention it separately. try do these changes.
use #ResponseBody need object to json,
seems missing some jar file
(jackson-mapper-asl.jar and jackson-core-asl.jar)
try to import it
First check if your controller is returning a JSON. You can use any REST client and see what is the return header. If not then add the Jackson mapper bean.
Also, try setting the Accept header in the ajax call.
$.ajax({
headers: {
Accept : "application/json",
Content-Type: "application/json"
},
data: "data",
...
})
in .js(java script)
ajax function
var variable="test";
$.ajax({
url: baseUrl + "nameController/test1",
async: false,
data: {val: variable},
dataType: 'html',
success: function (dat) {
console.log(dat);
}
});
you create nameController.java
controller
#RequestMapping(value = "test1", method = RequestMethod.POST)
public #ResponseBody
String checkRoomStatusReservation(#RequestParam(value = "val", required = true) String parse) {
System.out.println("parse"+parse);
//value from parse=test
return parse;
}
you can try this
I am trying to call a spring controller using ajax, but can not able to go to the controller. I am getting Error 405 Request method 'POST' not supported error. I am keeping my code here please give suggestion to come over it
this is my ajax code calling controller from jsp page, here i am getting the anchor attribute value.
basic.jsp
function organizationData(anchor) {
var value = anchor.getAttribute('value');
$.ajax({
url : "manageOrganization",
method : "GET",
dataType: "json",
contentType: 'application/json',
data: {organizationId : value },
success : function(response) {
alert(response);
},
error : function(e) {
alert('Error: ' + e);
}
});
}
controller
#RequestMapping(value="/manageOrganization", method = RequestMethod.GET)
public String organizationData(#RequestParam String organizationId) {
return organizationId+" associated";
}
here i should get the string to the jsp as a ajax response, but i am getting the error message. Any body can help me.
Regards Sree
For json response you need to add #ResponseBody annotation to your controller method.
You need to use type:"GET" not method:"GET" try it like,
$.ajax({
url : "manageOrganization",
type : "GET", // its type not method
dataType: "json",
.....
Read jQuery.ajax()
Also check that you are returning a json or not.
Your controller is returning String which may be resolved into some other jsp file IF you have configured viewResolver in spring configuration file. Try adding #ResponseBody like this:
#RequestMapping(value="/manageOrganization", method = RequestMethod.GET)
public #ResponseBody
String organizationData(#RequestParam String organizationId) {
return organizationId+" associated";
}
var urlUpload = "${root}manager/uploadFile.html";
var params = $('#topicForm').serialize();
$.ajax({
type: 'POST',
url: urlUpload,
data: params,
contentType: 'multipart/form-data',
processData: false,
success: function(data) {
alert("success");
}
});
#RequestMapping(value="/manager/uploadFile.html", method = RequestMethod.POST)
public String uploadFile(#ModelAttribute("topicForm") TopicForm topicForm,
#RequestParam("topicDoc") MultipartFile multipartFile ModelMap model) { ... }
I am getting the below exception
org.springframework.web.multipart.MultipartException: Could not parse
multipart servlet request; nested exception is
org.apache.commons.fileupload.FileUploadException: the request was
rejected because no multipart boundary was found.
The plugin is working fine thank you.
var urlUpload = "${root}manager/uploadFile.html?categoryId="+$("#category").val()+"&topicName="+$("#topicName").val();
$.ajaxFileUpload({
url:urlUpload,
secureuri:false,
fileElementId:'fileupload',
dataType: 'html',
success: function (data, status) {
alert("success");
}
});
The plugin is working fine, now i need to send few form fields to the controller along with the input file. in the above ajax call i appended the values to url. Is there any other solution for this?
The problem is that you're attempting to upload a URL-encoded serialization of the form, while claiming that it's multipart (see documentation of JQuery's serialize() function).
You need to use a plugin that will create the proper request. Here's one that I've used.
Alternatively, you can use HTML5 to upload files. I haven't done this.
This is my first post. I'm sorry for my english...
I have problem with postJSON and returning partial view with ModelAndView.
My controller:
#RequestMapping(method=RequestMethod.POST, value = "/addUrl.html")
public #ResponseBody ModelAndView addSubMenu(#RequestBody Menu menu) {
ModelAndView mav = new ModelAndView(PathConfig.MENU_DIR + "show_url");
int id = menuService.saveOrUpdateMenu(1, menu.getTitle(), menu.getUrl(), 4, "pl");
mav.addObject("submenu", menuService.get(id));
return mav;
}
My ajax code:
$("#menuUrl").submit(function(){
var menu = $(this).serializeObject();
$.ajax({
type: "POST",
url: config.resourcePath+"/addUrl.html",
data: JSON.stringify(menu),
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function(response){
$( "#site" ).append(response);
},
error: function(e){
alert("Server did not response.");
}
});
});
But... I have error: Server did not response...
How I can render partial view with json?
Thanks.
There are a few things which could be wrong here:
By specifying a Content-type header of application/json you are expecting a response of json back, however looking at the way you are handling the response it looks like what you want is an html
if it is html that you are looking for as a response then remove the Content-Type header from the request, remove the #ResponseBody annotation from ModelAndView response , instead just return a view which points to a normal jsp which can create the html response that you are expecting..
#RequestMapping(method=RequestMethod.POST, value = "/addUrl.html")
public ModelAndView addSubMenu(#RequestBody Menu menu) {
...
}
If what you want is json to update some parts of the page don't return a ModelAndView, return String, make sure to have a json serializer
#RequestMapping(method=RequestMethod.POST, value = "/addUrl.html")
public #ResponseBody String addSubMenu() {
//yourvariable
return yourvariable.toString();
}
$("#menuUrl").submit(function(){
var obj = $(this).serializeObject();
obj.parentId = getParentId(menuDivId);
$.ajax({
url: config.resourcePath+"/addUrl.html",
data : JSON.stringify(obj),
contentType : 'application/json',
type : 'POST',
context: document.body,
}).done(function(response) {
$("#site").append(response);
});
return false;
});
And controller returning ModelAndView.
It's working.