I want to build a simple file upload functionality using Spring MVC.
I have the multipartResolver in place and working:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10240000"/>
</bean>
When uploading a file this is logged:
DEBUG:[org.springframework.web.multipart.commons.CommonsMultipartResolver]: Found multipart file [imageUpload] of size 29081 bytes with original filename [xyz.jpg], stored at [/home/myuser/workspace/myProject/target/tmp/upload_67f1107c_1b8f_402c_bebd_6cd8a6e4c830_00000032.tmp]
which tells me that it's basically working.
This is part of my JSP:
<form:form modelAttribute="placeForm" action="/platz/save" method="post" cssClass="placeForm" enctype="multipart/form-data">
...
<label for="imageUpload">Upload</label>
<form:input type="file" path="imageUpload" id="imageUpload" accept="image/*" />
...
</form:form>
This is my model attribute object's class:
public class PlaceEditForm
{
@Valid
private Place place = new Place();
private Map<Integer, PlaceFeature> features;
private MultipartFile imageUpload;
... getter/setter omitted...
}
And this is part of my Controller method:
@RequestMapping(value="/save", method=RequestMethod.POST)
public String savePlace (@Valid @ModelAttribute("placeForm") PlaceEditForm form, BindingResult result)
{
logger.debug("saveNewPlace");
logger.debug("Upload: "+form.getImageUpload()); // null
...
return "redirect:/platz/"+place.getPlaceId();
}
What happens is, that the imageUpload attribute of the form object is not populated (null), whereas all other form properties are.
I found that it does work when I use this in the controller:
@RequestMapping(value="/save", method=RequestMethod.POST)
public String savePlace (@Valid @ModelAttribute("placeForm") PlaceEditForm form, BindingResult result, @RequestParam("imageUpload") MultipartFile upload, BindingResult uploadResult)
{
logger.debug("saveNewPlace");
logger.debug("Upload: "+upload); // Works!!
...
return "redirect:/platz/"+place.getPlaceId();
}
So, having the MultipartFile as a @RequestParam
works, but binding it to the form's modelAttribute
object doesn't. I found hundreds of examples on the web that do about the same and I don't find the difference.
I'm still learning Spring, so I might miss a very obvious point. I could just use the second version of the controller, but I don't understand it, and as I said, I'm learning.
Shouldn't all the <form:input path="abc">
properties inside the <form:form modelAttribute="xyz">...</form:form>
be bound to xyz.abc
? It works like this for all properties except the file upload.
Any insights? Thanks