ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Upload Files with JSF and MyFaces
Pages: 1, 2, 3, 4, 5, 6

The UploadedFileDefaultMemoryImpl class gets the content of the uploaded file as well as its name, size, and content type from a FileItem instance and stores all of this information into private fields. Therefore, even if Commons File Upload keeps the file on disk, this implementation of the UploadedFile interface maintains the content of the uploaded file in memory, wasting resources.



The UploadedFileDefaultFileImpl class uses a transient field to keep a reference to the a FileItem instance, which is used to obtain the content of the uploaded file only when the getInputStream() method is called. This implementation saves memory space, but if it's serialized, you cannot obtain the file content after deserialization. Therefore, the backing bean of the file-uploading form should not be kept in the session scope, because application servers serialize session beans when the application is restarted or when the server shuts down.

If you want an efficient solution that works properly, keep the backing beans in the request scope and specify storage="file" within <x:inputFileUpload> to save memory resources. You could also solve the serialization problem of the UploadedFileDefaultFileImpl class by adding a writeObject() method that should serialize the content of the uploaded file. To keep this implementation of UploadedFile efficient, the corresponding readObject() method should recreate the temporary file instead of reading its content in memory.

There is one more thing that you should take into account when using the MyFaces component. The UploadedFile interface doesn't define a method for deleting the temporary files that Commons File Upload creates on disk. These files will be deleted only when the FileItem instances are garbage collected. The DefaultFileItem class of Commons File Upload has a finalize() method that deletes the temporary file managed by the object that is removed from memory. If your application is uploading large files, you might want to delete them right after they are processed, without waiting for garbage collection. To be able to do that, you would have to add a getFileItem() method (in UploadedFileDefaultFileImpl) that should return the FileItem instance, which has a delete() method.

Sample Application

The previous sections have described how MyFaces supports file uploading with the help of Commons File Upload. Now let's see a real application that uses this feature. A JSF form (MyForm.jsp) lets users select a file and choose a message-digest algorithm, which is used by a backing bean (MyBean.java) to compute a hash value that is displayed by another web page (MyResult.jsp). These pages and the backing bean are glued with a JSF configuration file (faces-config.xml).

The MyForm.jsp Page

This JSF form uses the <x:inputFileUpload> tag of MyFaces, along with other standard JSF tags that render labels, messages, a drop-down list that contains message-digest algorithms, and a command button that uses a JSF expression (#{myBean.processMyFile}) to specify the action method that processes the uploaded file:

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="x"%>

<f:view>

<h:form id="MyForm" enctype="multipart/form-data" >

    <h:messages globalOnly="true" styleClass="message"/>

    <h:panelGrid columns="3" border="0" cellspacing="5">

        <h:outputLabel for="myFileId" value="File: "/>
        <x:inputFileUpload id="myFileId"
            value="#{myBean.myFile}"
            storage="file"
            required="true"/>
        <h:message for="myFileId"/>

        <h:outputLabel for="myParamId" value="Param: "/>
        <h:selectOneMenu id="myParamId"
                value="#{myBean.myParam}"
                required="true">
            <f:selectItem itemLabel="" itemValue=""/>
            <f:selectItem itemLabel="MD5" itemValue="MD5"/>
            <f:selectItem itemLabel="SHA-1" itemValue="SHA-1"/>
            <f:selectItem itemLabel="SHA-256" itemValue="SHA-256"/>
            <f:selectItem itemLabel="SHA-384" itemValue="SHA-384"/>
            <f:selectItem itemLabel="SHA-512" itemValue="SHA-512"/>
        </h:selectOneMenu>
        <h:message for="myParamId"/>

        <h:outputText value=" "/>
        <h:commandButton value="Submit"
            action="#{myBean.processMyFile}"/>
        <h:outputText value=" "/>

    </h:panelGrid>

</h:form>

</f:view>

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow