As Kai rightfully pointed out in his answer on the current question, the problem is caused by the NativeFileUploadDecoder
as used by FileUploadRenderer
not checking whether the request is a multipart/form-data
request or not. This will cause trouble when the component is present in a form on which a “regular” ajax request is being submitted. The CommonsFileUploadDecoder
checks that correctly and that’s why it works correctly in JSF 2.1 which didn’t have a native file upload parser yet.
His solution of workarounding this with a custom renderer is in the right direction, however the approach is quite clumsy. There’s in this particular case absolutely no need of copypasting the whole class consisting more than 200 lines just to add a few more lines. Instead, just extend exactly that class and override exactly the method with an if check before delegating to the super as follows:
package com.example;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import org.primefaces.component.fileupload.FileUploadRenderer;
public class MyFileUploadRenderer extends FileUploadRenderer {
@Override
public void decode(FacesContext context, UIComponent component) {
if (context.getExternalContext().getRequestContentType().toLowerCase().startsWith("multipart/")) {
super.decode(context, component);
}
}
}
That’s it (keep that <renderer-kit>
entry in faces-config.xml
though). There’s no point of continuing the decode if the request isn’t a multipart
request. The file parts wouldn’t be available anyway (and there’s also no point of casting back to javax.servlet.*
API when the same functionality is readily available via ExternalContext
).