JSF Portlet File Upload
By user13334247 on Jun 09, 2010
Recently a project student had a requirement to use file upload functionality in JSF Portlet. Since Mojarra's JSF Implementation does not provide fileupload component, he wanted to use the fileupload component provided by MyFaces
Tomahawk component library. He used the example from this blog and portletized it. But it didn't work with either OpenPortal JSF Portlet Bridge or Apache MyFaces JSR329 Portlet Bridge. I found another blog post that talks about extending OpenPortal
JSF Portlet Bridge inorder to provide support for fileupload. It worked, but i wanted a generic solution that works with both OpenPortal
JSF Portlet Bridge and Apache MyFaces JSR329 Portlet Bridge or any other JSF Portlet Bridge. So i used the Portlet Filter approach based on that blog. Ofcourse this solution will work only on portals that support JSR286.
Following are the steps to add fileupload functionality in your jsf portlet
1. Add the following JARs to the WEB-INF/lib of the jsf portlet webapp. The version numbers doesn't matter as long as you get the newest.
- commons-fileupload-1.2.1-jar (supports file upload capability for a portlet)
- commons-io-1.4-jar (required by commons-fileupload)
- portlet-fileupload-filter.jar (handles the portlet filter and the fileupload functionality and makes the org.apache.commons.fileupload.FileItem available as a request attribute, Source Code)
2. Add the following portlet filter entry in the portlet.xml
<portlet-app ..... version='2.0'> <portlet> <portlet-name>name_of_the_portlet</portlet-name> ........ </portlet> <filter> <filter-name>PortletFileUploadFilter</filter-name> <filter-class>com.sun.portlet.PortletFileUploadFilter</filter-class> <lifecycle>ACTION_PHASE</lifecycle> </filter> <filter-mapping> <filter-name>PortletFileUploadFilter</filter-name> <portlet-name>name_of_the_portlet</portlet-name> </filter-mapping> </portlet-app>
3. Define the fileupload component in the JSF page (you will use the name to get FileItem from the request)
<input type="file" name="name_of_the_component" />
4. After you submit the JSF page, you can obtain the org.apache.commons.fileupload.FileItem for the input file component from the PortletRequest as follows. Once you have access to FileItem you can get the name, the I/O stream of the uploaded file.
FacesContext facesContext = FacesContext.getCurrentInstance(); PortletRequest portletRequest = (PortletRequest) facesContext.getExternalContext().getRequest(); FileItem fileItem = (FileItem)portletRequest.getAttribute("name_of_the_component");
See the example jsf fileupload portlet that uses this functionality.