Spring REST MultipartFile file is always null when do upload file - java

#RequestMapping(value = "{fileName:.+}", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<ResponseEnvelope<String>> uploadFile(
#RequestParam("ownerId") Long ownerId,
#PathVariable("fileName") String fileName,
#RequestBody MultipartFile file)
throws Exception {
ResponseEnvelope<String> env;
if(null == certFileContent) {
env = new ResponseEnvelope<String>("fail");
return new ResponseEntity<ResponseEnvelope<String>>(env, HttpStatus.OK);
}
service.uploadCertificate(ownerId, fileName, certFileContent.getBytes());
env = new ResponseEnvelope<String>("success");
return new ResponseEntity<ResponseEnvelope<String>>(env, HttpStatus.OK);
}
Why I always get the file value is null, I've configure the multipart support,see below,

The file should be binded to a RequestParam instead of the RequestBody as follows:
public ResponseEntity<ResponseEnvelope<String>> uploadFile(
#RequestParam("ownerId") Long ownerId,
#PathVariable("fileName") String fileName,
#RequestParam(value = "file") MultipartFile file)
This would correspond with the following HTML form:
<form method="post" action="some action" enctype="multipart/form-data">
<input type="file" name="file" size="35"/>
</form>
Then in your dispatcher configuration specify the CommonsMultiPartResolver
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="5000000"/>
</bean>

This is what worked for me,
Previously my input field was defined as,
<input type="file" />
I was getting null file with the above line but when I added the name="file" everything worked fine!
<input type="file" name="file" />
Hope this helps!

Related

Spring MVC file upload is passing null to the controller

i've a spring MVC application and when i try to upload a multipart file, a null value is passed to the controller. all the other text parameters are passed properly only the file input is passed as null. I've included the MultipartResolver bean and commons-io plus commons-fileupload dependencies in my project. i've checked it's passed in the browser's request but it's not bound in the modelAttribute.
here is a snippet code from my view
<form:form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/profile/secure/saveIdentity" commandName="profileModel">
<span><b>Upload your passport photo</b></span>
<form:input path="passportPhotograph" type="file" id="passportPhoto"/>
</form:form>
and here is a snippet from my controller method
#RequestMapping(value = "/secure/saveIdentity", method = RequestMethod.POST)
public ModelAndView saveIdentity(#ModelAttribute("profileModel") #Valid ProfileModel profileModel,HttpServletRequest request){
MultipartFile photo = profileModel.getPassportPhotograph();
if(photo != null){ do something.... }
}
here is my ProfileModel.java class snippet
public class ProfileModel{
private MultipartFile passportPhotograph;
public MultipartFile getPassportPhotograph() {
return passportPhotograph;
}
public void setPassportPhotograph(MultipartFile passportPhotograph) {
this.passportPhotograph = passportPhotograph;
}
............
}
And in my dispatcher-servlet file I have declared MultipartResolver bean:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="99999999999"/>
</bean>
and finally in my build.gradle file i added these dependencies
compile('commons-io:commons-io:2.0.1')
compile('commons-fileupload:commons-fileupload:1.3.1')
after all this it's passing null to my controller even though it's included in the HttpServletRequest. what should i do to fix this. Thanks in advance for you help.
you need to use #RequestMapping(value = "/secure/saveIdentity", method = RequestMethod.POST, headers = ("content-type=multipart/*"), produces = "application/json", consumes = "image/*").
Solved my issue by using the StandardServletMultipartResolver which comes with the spring web framework. But you have to use Servlet version 3.0+ for this to work.
This sample code. point is input tag name binding file in model. maybe you need library json and file. ex) commons-io, commons-fileupload and jackson, gson use to parsing in controller.
HTML
<form:form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/profile/secure/saveIdentity">
<span><b>Upload your passport photo</b></span>
<form:input type="file" name="file"/>
</form:form>
Controller
#RequestMapping(value = "test", method = RequestMethod.POST)
public String testFormData(FileAndContentModel model) {
// break point and check model.
return "success";
}
Model
public class FileAndContentModel {
private MultipartFile file;
public FileAndContentModel () {
}
// getter, setter
}
This is not the solution, I just type here because is easier to read than a comment. Please try the minimum requeriment, just upload a file and verify if works.
Form:
<form:form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/profile/secure/saveIdentity">
<span><b>Upload your passport photo</b></span>
<input name="file" type="file" id="passportPhoto"/>
</form:form>
Controller:
#RequestMapping(value = "/secure/saveIdentity", method = RequestMethod.POST)
public void saveIdentity(#RequestParam("file") MultipartFile file) {
//please verify here if the file is null

unable to fetch image from spring form

while fetching file from spring form I am getting null value and If I try this code for rest of fields i mean non multipart input types its working fine. while debugging I am getting null value from line. If I try to fetch image from existing folder i'e image under webapp and that url is able to display image in browser but not able to read value from files using browser and sorry for my bad english
edit if i comment the image code, application is working fine but when I introduce the code for image I'm getting error
MultipartFile file = domain.getImage(); //this is getting null
this is relevent code
controller
#RequestMapping(value = "/form", method = RequestMethod.GET)
public String formInputGet(Model model) {
model.addAttribute("domain", new Domain());
return "form";
}
#RequestMapping(value = "/form", method = RequestMethod.POST)
public String formInputPost(#ModelAttribute("domain") Domain domain, HttpServletRequest httpServletRequest) {
MultipartFile file = domain.getImage();
if (image== null)
throw new NullPointerException("unable to fetch "+file); //getting NPE everytime
String rootDirectory = httpServletRequest.getSession().getServletContext().getRealPath("/");
if (domain.getImage() != null && !domain.getImage().isEmpty())
try {
File path = new File(rootDirectory + "images\\" + domain.getFirstName() + ".png");
file.transferTo(path);
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
repositiry.addToList(domain);
return "redirect:/";
}
form.jsp
<form:form modelAttribute="domain" enctype="multipart/form-data">
First Name<br>
<form:input path="firstName" />
<br>Last Name :<br>
<form:input path="lastName" />
<br>upload Image<br>
<form:input path="image" type="file" />
<hr>
<input type="submit">
</form:form>
dispatcherServlet
<mvc:annotation-driven />
<mvc:resources location="/images/" mapping="/images/**" />
<context:component-scan base-package="com" />
<bean id="multipartReslover"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10240000" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/" />
<property name="suffix" value=".jsp" />
</bean>
I added some extra code to find if I am getting domain as null came to be true. And I have no Idea how to solve that.
after adding check for file i'm getting error
java.lang.NullPointerException: unable to fetch : null
domain.java
public class Domain {
private String firstName;
private String lastName;
private MultipartFile image;
//getters and setters
NOTE any helpful answer if it have other way of working is welcomed too :)
any help is appreciated, thanks :)
you should do everything #kuhajeyen said and if getting image from domain object didnt go well you can try this
public String formInputPost(#ModelAttribute("domain") Domain domain,
#RequestParam("image") MultipartFile imagefile,
HttpServletRequest httpServletRequest ) {
imagefile.transferTo(path);
}
edit :- change method attribute to POST inside the form otherwise it will make a GET request.
<form:form modelAttribute="domain" method="post" enctype="multipart/form-data">
and replace your input type file with this line, i think there is some issues when trying to bind input type file with an object.
<input type="file" name="image" />
You need to tell the spring, how to resolve multipart file
add this bean
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="409600"/>
</bean>
And also it seems you have not mapped your action in form
<form:form modelAttribute="domain" enctype="multipart/form-data" action="xxxx/form">
....
</form:form>
There were two typos in my configuration file as they are
1) <mvc:resources location="/images/" mapping="/images/**" /> here mapping was supposed to be like mapping ="images/**"
2)File path = new File(rootDirectory + "images\\" + domain.getFirstName() + ".png"); here path is supposed to be as rootDirectory+"\\images\\"+.... instead

Uploading image using Spring, commons-file upload

I'm trying to upload an image following this and this tutorial but without using maven.
Here is my config related to upload:
ApplicationContext.xml
..
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10000000">
</property></bean>
My form:
<form:form
action="${ contextPath }admin/add-product"
method="POST" modelAttribute="addInventoryItemDto"
enctype="multipart/form-data">
<table>
....
<tr>
<td><b>Image:</b></td>
<td><input type="file" name="image" /></td>
</tr>
....
Controller
#RequestMapping( value = "/add-product", method = RequestMethod.POST )
public String addProduct(
#ModelAttribute( "addInventoryItemDto" ) #Valid AddInventoryItemDto inventoryDto,
#RequestParam( "image" ) MultipartFile img ) {
System.out.println("ContentType:" + img.getContentType());
return "admin/add-product";
}
I'm getting 404 Bad Request but when I remove the file related stuff in my Controller and form the request is properly sent to my controller
What I'm I missing or did wrong?
Try adding this tag:
<spring:url value="/add-product?${_csrf.parameterName}=${_csrf.token}" var="addItem"/>
And put this to the action attribute:
<form:form
action= "${addItem}"
method="POST" modelAttribute="addInventoryItemDto"
enctype="multipart/form-data" >
<table>
....
<tr>
<td><b>Image:</b></td>
<td><input type="file" name="image" /></td>
</tr>
....
If this isn’t working try also add the MultiPartHttpServletRequest object to your controller:
#RequestMapping( value = "/add-product", method = RequestMethod.POST )
public String addProduct(
#ModelAttribute( "addInventoryItemDto" ) #Valid AddInventoryItemDto inventoryDto,
MultiPartHttpServletRequest request,
#RequestParam( "image" ) MultipartFile img ) {
System.out.println("ContentType:" + img.getContentType());
return "admin/add-product";
}
I just moved the multipartResolver
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10000000">
</property></bean>
to my servlet-dispatcher configuration. Seems like that multipartResolver is part of spring MVC not the spring core

Spring MVC mapped method not being called using POST

I am trying to upload a file using Spring MVC.
Here is the form in the .jsp page
<form:form method="post" commandName="file" enctype="multipart/form-data">
Upload your file please:
<input type="file" name="file" />
<input type="submit" value="upload" />
<form:errors path="file" cssStyle="color: #ff0000;" />
</form:form>
In my controller I have the GET and POST methods:
#RequestMapping(method = RequestMethod.GET)
public String getForm(Model model) {
File fileModel = new File();
model.addAttribute("file", fileModel);
return "file";
}
#RequestMapping(method = RequestMethod.POST)
public String fileUploaded(Model model, #Validated File file, BindingResult result) {
String returnVal = "successFile";
logger.info("I am here!!!");
if (result.hasErrors()) {
returnVal = "file";
}else{
MultipartFile multipartFile = file.getFile();
}
return returnVal;
}
The validation is just to check if the file size is zero:
public void validate(Object target, Errors errors) {
File imageFile = (File)target;
logger.info("entered validator");
if(imageFile.getFile().getSize()==0){
errors.rejectValue("file", "valid.file");
}
}
The method GET works fine and returns the file view, however the POST method in the controller does not get called. Nothing happens when the upload button is clicked.
I hope this will help you:
controller code
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String uploadInputFiles(#RequestParam("file1") MultipartFile file,
#RequestParam("fileName") String fileName,
#RequestParam("fileType") String fileType){
System.out.println("Upload File Controller has been called");
}
Form submission:
<form method="POST" action="uploadFile" enctype="multipart/form-data">
File to upload: <input type="file" name="file"><br />
Name: <input type="text" name="name"><br /> <br />
<input type="submit" value="Upload"> Press here to upload the file!
</form>
I think your configuration should be like below in mvc-servlet.xml file.
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="500000" />
</bean>
and change your post api like below.
#RequestMapping(method = RequestMethod.POST,value = "/uploadFile")
public String fileUploaded(Model model, #RequestParam("file") MultipartFile file, BindingResult result) {
String result = "not uploaded";
if(!file.isEmpty()){
MultipartFile multipartFile = file.getFile();
//code for storing the file in server(in db or system)
}
else{
result = "can not be empty;"
}
return result;
}

how to get param in method post spring mvc?

I'm using spring mvc. And I can't get param from url when method = post. But when I change method to GET, so I can get all param.
This is my form:
<form method="POST" action="http://localhost:8080/cms/customer/create_customer" id="frmRegister" name ="frmRegister" enctype="multipart/form-data">
<input class ="iptRegister" type="text" id="txtEmail" name="txtEmail" value="" />
<input class ="iptRegister" type="password" id="txtPassword" name="txtPassword" value="" />
<input class ="iptRegister" type="text" id="txtPhone" name="txtPhone" value="" />
<input type="button" id="btnRegister" name="btnRegister" value="Register" onclick="" style="cursor:pointer"/>
</form>
This is my controller:
#RequestMapping(value= "/create_customer", method = RequestMethod.POST)
#ResponseBody
public String createCustomer(HttpServletRequest request,
#RequestParam(value="txtEmail", required=false) String email,
#RequestParam(value="txtPassword", required=false) String password,
#RequestParam(value="txtPhone", required=false) String phone){
ResultDTO<String> rs = new ResultDTO<String>();
rs.setStatus(IConfig.SHOW_RESULT_SUCCESS_ON_MAIN_SCREEN);
try{
Customer c = new Customer();
c.setEmail(email);
c.setPassword(password);
c.setPhone(phone);
customerService.insert(c);
rs.setData("Insert success");
}catch(Exception ex){
log.error(ex);
rs.setStatus(IConfig.SHOW_RESULT_ERROR_ON_MAIN_SCREEN);
rs.setData("Insert failure");
}
return rs.toString();
}
How can I resolved this?
Spring annotations will work fine if you remove enctype="multipart/form-data".
#RequestParam(value="txtEmail", required=false)
You can even get the parameters from the request object .
request.getParameter(paramName);
Use a form in case the number of attributes are large. It will be convenient. Tutorial to get you started.
Configure the Multi-part resolver if you want to receive enctype="multipart/form-data".
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="250000"/>
</bean>
Refer the Spring documentation.
It also works if you change the content type
<form method="POST"
action="http://localhost:8080/cms/customer/create_customer"
id="frmRegister" name="frmRegister"
enctype="application/x-www-form-urlencoded">
In the controller also add the header value as follows:
#RequestMapping(value = "/create_customer", method = RequestMethod.POST, headers = "Content-Type=application/x-www-form-urlencoded")
When I want to get all the POST params I am using the code below,
#RequestMapping(value = "/", method = RequestMethod.POST)
public ViewForResponseClass update(#RequestBody AClass anObject) {
// Source..
}
I am using the #RequestBody annotation for post/put/delete http requests instead of the #RequestParam which reads the GET parameters.
You should use #RequestParam on those resources with method = RequestMethod.GET
In order to post parameters, you must send them as the request body. A body like JSON or another data representation would depending on your implementation (I mean, consume and produce MediaType).
Typically, multipart/form-data is used to upload files.

Categories