Search code examples
wicketwicket-6wicket-1.6

Wicket reporting same FileUpload object in subsequent requests


I have a panel used in multiple pages in an app we're developing. In this panel is a FileUploadField that uses AjaxFormSubmitBehavior (extended as FileUploadBehavior) on "change" to upload a file, which I then add to a list via ajax, update the view, clear the FileUploadField, and then allow them to select another file. And this is in fact exactly what happens in one of the pages using the panel...but not in another. In the non-working page, the first file selected is repeated over and over regardless of what file is picked after the first.

In the onSubmit of the behavior, we get the the FileUpload object which is supposed to be different between requests. I can see in the debugger that the FileUpload is the exact same object as the previous request, not merely carrying the same payload.

I'm scrutinizing the usage of the panel on the two pages and see no material differences. I can see the file control on the page DOES show the changed file name while I sit at my breakpoint on the server (so I suspect whatever is going wrong is on the java side). But I can't figure out why they behave differently or see where it's going wrong. The panels and pages are large and complex, so here's snippets of the relevant pieces.

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);

I have a break right after this line and can see the first file gets repeated. The code that instantiates the field and behavior in the panel looks like:

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

The html tag: <input wicket:id="fileUploadField" class="form-control" type="file" id="formFile" multiple>

I feel like the fact that it works in one page and not in another leads me to think the problem is outside the panel. The fact that the control in the browser shows the 2nd filename during test leads me to think it's on the java side. But nothing about the file event or definition happens outside the panel itself. The form elements are declared identically, and both have multipart enctypes when the pages render. Both successfully upload their first file. I'm kind of not even sure where to look for why wicket is re-using the FileUpload object in one page but not in another.

I should mention that we use Apache Wicket 6.26.

update: I looked into the source of FileUploadField, and it has an explicit check on whether FileUploads is null in it's internal property, and if so returns it without checking the actual request. I don't see any way to clear this value between requests. clearInput() doesn't affect it from what I see. I'm more confused by how this is working in one page than why it's not in the one where it doesn't now. I also don't know how to make the class 'reset' between requests.


Solution

  • Okay, figured this out. As martin-g pointed out, the fileUploads is set null in onDetach(), which I discovered about an hour after my update. The problem is that the onDetach() first tries to null out the model object. But that method was blowing up because there was no method 'fileUploadField' on the model attached to the form which was a compound property model. The page that worked does NOT use a compound property model for the form. For some reason, when this error occurred, it was being swallowed somewhere in the call stack and did not end up in my console log.

    My solution was to provide a local model to the fileUploadField since that's not how I'm interacting with the control anyway (I'm using ajax and getting the FileUpload directly each time). That fixed it. It now works everywhere.