gpt4 book ai didi

java - 为什么 Spring MVC 将空对象插入到应该是空列表的内容中?

转载 作者:搜寻专家 更新时间:2023-10-31 20:02:34 24 4
gpt4 key购买 nike

我正在上传多个文件。当我实际选择要上传的文件时,这很好用;他们很好地进入了他们的列表,但是当我在没有选择文件的情况下单击“上传”时,我得到的不是一个空列表,而是一个包含空文件的列表。我的 validator 正在检查此列表的大小是否为 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>

bean ,这里没什么特别的:

public class DocumentsBean
{
private List<MultipartFile> files;
public List<MultipartFile> getFiles(){
return files;
}
public void setFiles(List<MultipartFile> files){
this.files = files;
}
}

Controller :

@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,它的文件名是一个空字符串,并且它的大小为 0。

这是怎么回事?

最佳答案

这是您的解决方案。解释如下。

添加 @InitBinder设置以下属性的方法。理想情况下,您会将其添加到 @ControllerAdvice类,但具有相应 @RequestMapping 方法的 Controller 也可以正常工作。

@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通过将参数绑定(bind)到实例类,使用请求(及其表单参数)生成参数类型的实例实例字段。如果检测到请求的内容类型为multipart/form-data,它将执行特殊绑定(bind)。

此绑定(bind)在 WebDataBinder#bindMultipart(..) 中完成.它检索由 MulitpartResolver 创建的所有 MultipartFile 对象。如果只有一个,它会检查两件事。

if (isBindEmptyMultipartFiles() || !value.isEmpty()) {
mpvs.add(key, value);
}

第一个方法调用

Return[s] whether to bind empty MultipartFile parameters.

第二个检查 MultipartFile 是否有正文内容。如果您在没有选择文件的情况下提交了表单(或者如果您选择了一个空文件 AFAIK),则不会。

如果这些表达式中的任何一个解析为 true,那么 Spring 将为您的处理程序方法提供这个空的 MultipartFile holder。否则,它不会绑定(bind)该字段,这就是您需要默认值的原因(因此它不会保持 null)

private List<MultipartFile> files = Arrays.asList();

看看 WebDataBinder#setBindEmptyMultipartFiles(boolean) 的 javadoc哪个州

Set whether to bind empty MultipartFile parameters. Default is "true".

Turn this off if you want to keep an already bound MultipartFile when the user resubmits the form without choosing a different file. Else, the already bound MultipartFile will be replaced by an empty MultipartFile holder.

这是您应该在上面显示的 @InitBinder 方法中设置为 false 的属性。

关于java - 为什么 Spring MVC 将空对象插入到应该是空列表的内容中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22391064/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com