我上传了多个文件。当我实际选择要上传的文件时,这很好用;他们很好地进入他们的列表,但是当我点击上传而不选择文件时,我得到一个包含空文件的List。我的验证器正在检查此List的大小是否为0,因此它会超过它。
是的,我可以解决它只是检查一个空文件,是的我可以在没有选择文件时禁用上传按钮,但我想知道为什么Spring会这样做以及可能如何阻止它执行此操作
这是jsp:
<form:form commandName="documentsBean" enctype="multipart/form-data">
<input type="hidden" name="submittedFormAction" value="attachDocumentSave"/>
<input type="file" name="files" id="attachFiles" multiple/>
<button type="submit">Attach</button>
</form:form>
豆子,这里没什么好看的:
public class DocumentsBean
{
private List<MultipartFile> files;
public List<MultipartFile> getFiles(){
return files;
}
public void setFiles(List<MultipartFile> files){
this.files = files;
}
}
控制器:
@RequestMapping( method = RequestMethod.POST, params = { "submittedFormAction=attachDocumentSave" })
public ModelAndView attachDocumentSave(HttpServletRequest request, @ModelAttribute("documentsBean") DocumentsBean documentsBean, BindingResult errors) throws Exception
{
// At this point documentsBean.files is an ArrayList<E> with size = 1
}
当我深入查看documentsBean.files
时,我看到elementData[0]
是CommonsMultipartFile
,其fileName是一个空字符串,其大小为0.
发生了什么事?
答案 0 :(得分:5)
这是您的解决方案。解释如下。
添加设置以下属性的@InitBinder
方法。理想情况下,您可以将其添加到@ControllerAdvice
类,但具有相应@RequestMapping
方法的控制器也可以。
@InitBinder
public void init(WebDataBinder binder) {
binder.setBindEmptyMultipartFiles(false);
}
您还需要像这样更改DocumentsBean
课程
private List<MultipartFile> files = Arrays.asList();
因此该字段不是null
。
Spring使用ServletModelAttributeMethodProcessor
生成@ModelAttribute
带注释参数的参数,例如你的
@ModelAttribute("documentsBean") DocumentsBean documentsBean
这个HandlerMethodArgumentResolver
使用请求(及其表单参数)通过将参数绑定到实例类来生成参数类型的实例。
实例字段。如果它检测到请求的内容类型为multipart/form-data
,则会执行特殊绑定。
此绑定在WebDataBinder#bindMultipart(..)
中完成。它检索由MultipartFile
创建的所有MulitpartResolver
个对象。如果只有一个,它会检查两件事。
if (isBindEmptyMultipartFiles() || !value.isEmpty()) {
mpvs.add(key, value);
}
第一个方法调用
返回[s]是否绑定空
MultipartFile
个参数。
,第二个检查MultipartFile
是否有任何正文内容。如果您在未选择文件的情况下提交表单(或者您选择了空文件AFAIK),则不会。
如果其中任何一个表达式解析为true
,那么Spring将为您的处理程序方法提供此空MultipartFile
持有者。否则,它将不会绑定该字段,这就是您想要一个默认值的原因(因此它不会保留null
)
private List<MultipartFile> files = Arrays.asList();
查看WebDataBinder#setBindEmptyMultipartFiles(boolean)
的javadoc状态
设置是否绑定空的MultipartFile参数。默认为“true”。
如果要在何时保留已绑定的MultipartFile,请将其关闭 用户重新提交表单而不选择其他文件。其他, 已绑定的MultipartFile将替换为空 MultipartFile持有人。
这是您应在上面显示的false
方法中设置为@InitBinder
的属性。