Spring文件上传未绑定到模型属性对象 [英] Spring file upload not binding to model attribute object
问题描述
我想使用Spring MVC构建一个简单的文件上传功能。
I want to build a simple file upload functionality using Spring MVC.
我已经安装了multipartResolver并且正常工作:
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.
这是我的JSP的一部分:
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...
}
这个是我的Controller方法的一部分:
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();
}
发生的情况是,表格对象的imageUpload属性未填充( null),而所有其他表单属性都是。
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();
}
因此,将MultipartFile作为 @RequestParam
有效,但将其绑定到表单的 modelAttribute
对象则不然。我在网上发现了数百个大致相同的例子,我发现差异不大。
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.
我还在学习Spring,所以我可能会错过一个明显的一点。我可以使用控制器的第二个版本,但我不明白,正如我所说,我正在学习。
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.
不应该全部<在$ code>< form:form modelAttribute =xyz> ...< / form:form> 绑定到 xyz.abc
?对于除文件上传之外的所有属性,它都是这样的。
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
推荐答案
我发现了问题:
我在控制器中有这样的方法,但忘了添加 imageUpload
属性。
一旦找到就非常愚蠢和简单..!
I had a method like this in the controller, but forgot to add the imageUpload
property.
Very stupid and easy once found..!
@InitBinder
public void initBinder(WebDataBinder binder)
{
binder.setAllowedFields("place.placeId", "place.name", "place.description", "place.directions", "place.coordinates*", "features*", "tmpFiles*", "removeFiles*");
}
这可以防止绑定器将任何其他属性绑定到modelAttribute而不是指定的属性。非常重要的安全措施,可以防止恶意者将危险信息输入您的系统,当您只验证预期在前端的内容时。
This prevents the binder to bind any other properties to the modelAttribute than the ones specified. Very important security measure to prevent evildoers from feeding in dangerous information into your system, when you only validate what you expect to be on the front-end.
这篇关于Spring文件上传未绑定到模型属性对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!