【问题标题】:Spring file upload not binding to model attribute objectSpring文件上传未绑定到模型属性对象
【发布时间】:2013-07-20 08:57:51
【问题描述】:

我想使用 Spring MVC 构建一个简单的文件上传功能。

我有 multipartResolver 并正在工作:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="maxUploadSize" value="10240000"/>
</bean>

上传文件时会记录:

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]

这告诉我它基本上可以工作。

这是我的 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>

这是我的模型属性对象的类:

public class PlaceEditForm
{
    @Valid
    private Place place = new Place();
    private Map<Integer, PlaceFeature> features;
    private MultipartFile imageUpload;
... getter/setter omitted...
}

这是我的控制器方法的一部分:

@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),而所有其他表单属性都是。

我发现当我在控制器中使用它时它确实有效:

@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 对象则无效。我在网上找到了数百个类似的例子,但我没有发现区别。

我还在学习 Spring,所以我可能会错过一个非常明显的点。我可以只使用控制器的第二个版本,但我不明白它,正如我所说,我正在学习。

&lt;form:form modelAttribute="xyz"&gt;...&lt;/form:form&gt; 中的所有&lt;form:input path="abc"&gt; 属性不应该绑定到xyz.abc 吗?除了文件上传之外,它对所有属性都是这样工作的。

有什么见解吗? 谢谢

【问题讨论】:

    标签: java spring spring-mvc file-upload


    【解决方案1】:

    我发现了问题:

    我在控制器中有这样的方法,但忘记添加imageUpload 属性。 一旦被发现就非常愚蠢和容易..!

    @InitBinder
    public void initBinder(WebDataBinder binder)
    {
        binder.setAllowedFields("place.placeId", "place.name", "place.description", "place.directions", "place.coordinates*", "features*", "tmpFiles*", "removeFiles*");
    }
    

    这可以防止绑定器将任何其他属性绑定到模型属性,而不是指定的属性。当您仅在前端验证您期望的内容时,非常重要的安全措施可防止作恶者将危险信息输入您的系统。

    【讨论】:

    • 我正在查看这个示例,似乎我们正在定义 class PlaceEditForm 内部的属性及其自己的属性。我在哪里可以阅读更多关于setAllowedFields 如何识别此处提供的列表以及它如何处理参数名称中的通配符的信息。这方面的任何方向都会有所帮助。谢谢!抄送@marc82ch
    • @SamarthAsthana 如果我是你,我会使用三个不同的地方来查找更多信息:1) Spring MVC 文档,2) WebDataBinder 的 JavaDoc,3) WebDataBinder 的源代码以及更多类(如果需要)。您应该只依赖记录在案的行为,但有时最好通过查看实际源代码来了解如何它是如何工作的,很高兴 Spring 是开源的。
    猜你喜欢
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    相关资源
    最近更新 更多