Wicket 在后续请求中报告相同的 FileUpload 对象

Wicket reporting same FileUpload object in subsequent requests

我在我们正在开发的应用程序的多个页面中使用了一个面板。在这个面板中是一个 FileUploadField,它在“更改”时使用 AjaxFormSubmitBehavior(扩展为 FileUploadBehavior)来上传文件,然后我通过 ajax 添加到列表,更新视图,清除 FileUploadField,然后允许他们select 另一个文件。事实上,这正是使用面板的其中一个页面中发生的情况......但不是在另一个页面中。在非工作页面中,第一个文件 selected 一遍又一遍地重复,无论在第一个文件之后选择什么文件。

在行为的 onSubmit 中,我们得到了 FileUpload 对象,该对象在请求之间应该是不同的。我可以在调试器中看到 FileUpload 是与先前请求完全相同的对象,而不仅仅是携带相同的负载。

我仔细检查了两个页面上面板的使用情况,没有发现 material 差异。当我坐在服务器上的断点处时,我可以看到页面上的文件控件确实显示了更改的文件名(所以我怀疑 java 端出了什么问题)。但我无法弄清楚为什么他们的行为会有所不同,也不知道哪里出了问题。面板和页面又大又复杂,因此这里是相关部分的片段。

FileUploadBehavior.onSubmit(AjaxRequestTarget):

FileUploadField fileUploadField = (FileUploadField) fileUploadContainer.get("fileUploadField");
FileUpload fileUpload = fileUploadField.getFileUpload();
[...]
//clear file input after each request for next upload.
fileUploadField.clearInput();
target.add(fileUploadField);

我在这行之后有一个中断,可以看到第一个文件被重复了。在面板中实例化字段和行为的代码如下所示:

FileUploadField fileUploadField = new FileUploadField("fileUploadField");
fileUploadField.add(new FileUploadBehavior("change", maxFileSize).setDefaultProcessing(false));
fileUploadContainer.add(fileUploadField);

html 标签:

我觉得它在一个页面上有效,而在另一个页面上无效,这让我认为问题出在面板之外。浏览器中的控件在测试期间显示第二个文件名这一事实让我认为它在 java 一侧。但是关于文件事件或定义的任何事情都不会发生在面板本身之外。表单元素的声明相同,并且在页面呈现时都具有多部分 enctypes。两人都成功上传了他们的第一个文件。我什至不确定去哪里寻找为什么 wicket 在一个页面中重新使用 FileUpload 对象而不是在另一个页面中。

我应该提到我们使用 Apache Wicket 6.26。

更新:我查看了 FileUploadField 的源代码,它在其内部 属性 中明确检查 FileUploads 是否为空,如果是 returns 则不检查实际请求。我看不出有任何方法可以在请求之间清除此值。 clearInput() 不会影响我所看到的。我更困惑的是它在一页中是如何工作的,而不是为什么它不在现在没有的页面中。我也不知道如何在请求之间制作 class 'reset'。

好的,明白了。正如 martin-g 指出的那样,我在更新后大约一个小时发现了 fileUploads 在 onDetach() 中设置为 null。问题是 onDetach() 首先尝试清空模型对象。但是那个方法被炸毁了,因为没有方法 'fileUploadField' 在附加到表单的模型上,这是一个复合 属性 模型。有效的页面不使用复合 属性 模型作为表单。出于某种原因,当这个错误发生时,它被吞没在调用堆栈的某个地方,并没有出现在我的控制台日志中。

我的解决方案是为 fileUploadField 提供一个本地模型,因为这不是我与控件交互的方式(我使用 ajax 并且每次都直接获取 FileUpload)。那修好了。它现在无处不在。