The JSF 1.x and 2.x specifications have not implemented support for HTML forms with
enctype="multipart/form-data" and are therefore do not support file uploads. Various
workarounds exist for use with the JSP view-handler, such as introducing a servlet filter or phase listener
to intercept the request. With the advent of the Facelets view-handler, these techniques
have become largely ineffectual. The problem has to do with the FaceletViewHandler
restoreView(FacesContext context, String viewId) method which is unable to retrieve the
javax.faces.ViewState request parameter for HTML forms with
enctype="multipart/form-data". The underlying reason why it can't retrieve the
parameter is because the ExternalContextImpl.getRequestParameterMap() method in the JSF
Reference Implementation is not equipped to handle these types of postback requests.
The PortletFaces project solves this problem by providing wrapper implementations of
FacesContext, FacesContextFactory, and
ExternalContext. These can be activated by placing the following
<faces-context-factory> element inside of your portlet WAR's
WEB-INF/faces-config.xml descriptor:
Example 6.56. Example usage of faces-context-factory element
<factory> <faces-context-factory>org.edorasframework.portletfaces.bridge.sun.FacesContextFactoryImpl</faces-context-factory> </factory>
This will ultimately cause the FacesContext.getExternalContext() method to return an instance of the org.edorasframework.portletfaces.bridge.sun.ExternalContextImpl class. This class overrides the ExternalContext.getRequestParameterMap() method, which uses Apache Commons FileUpload project to parse the request parameters. When used in conjunction with the pf:inputFile tag, JSF portlet developers can provide file upload capability in their Facelet views.