jsffile-uploadservlet-filtersjsf-2.2tomahawk

<t:inputFileUpload> not working anymore after migration JSF 1.2 to JSF 2.2


I am upgrading my application from JSF 1.2 to JSF 2.2 and using Tomahawk 1.1.14 version.

After upgrading, <t:inputFileUpload> tag has stopped working and value of the component is not bound to backingbean property any more.

web.xml

<context-param>
    <param-name>facelets.LIBRARIES</param-name>
    <param-value>/WEB-INF/facelets/tags/tomahawk.taglib.xml</param-value>
</context-param>

However, I saw on myfaces site that the above parameter is deprecated. Is there any other way to include tag libraries or is it not even required with JSF 2.2?

<filter>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
    <init-param>
        <param-name>uploadMaxFileSize</param-name>
        <param-value>50m</param-value>
    </init-param>
    <init-param>
        <param-name>uploadThresholdSize</param-name>
        <param-value>1024k</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

<filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>MyFacesExtensionsFilter</filter-name>
    <url-pattern>*.faces</url-pattern>
</filter-mapping>

Before this filter, I do have another filter in my web.xml and it is

<filter>
    <filter-name>AjaxAnywhere</filter-name>
    <filter-class>org.ajaxanywhere.AAFilter</filter-class>
    <init-param>
        <param-name>preSendHandlerClass</param-name>
        <param-value>org.ajaxanywhere.jsf.MyFacesClientStateSavingPreSendHandler</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>AjaxAnywhere</filter-name>
    <url-pattern>*.faces</url-pattern>
</filter-mapping>

Can anyone please help me if I need to do any more configuration changes for Tomahawk to work with JSF 2.2?

Thanks!


Solution

  • Since JSF 2.2, the FacesServlet will automatically parse multipart/form-data requests all by itself with help of new Servlet 3.0 @MultiartConfig annotation. Also, since JSF 2.2 there is (finally!) a standard file upload component, the <h:inputFile>.

    The MyFaces extensions filter and Tomahawk file upload component is basically incompatible with JSF 2.2. The filter would consume and parse the request its own way and the FacesServlet would end up getting no request data at all (and therefore not be able to continue the JSF lifecycle "as usual"). Removing the filter alone would also not work as <t:inputFileUpload> is internally relying on the semantics/specifics of the MyFaces extensions filter.

    Your best bet is really to just remove the filter from the web.xml altogether and replace the <t:inputFileUpload> by <h:inputFile>. It must be bound to a javax.servlet.http.Part property which offers a.o. getInputStream() which you can just continue using the same way as before with <t:inputFileUpload>.

    <h:inputFile value="#{bean.uploadedFile}" />
    
    private Part uploadedFile;
    
    public void save() {
        String name = uploadedFile.getSubmittedFileName();
        String type = uploadedFile.getContentType();
        long size = uploadedFile.getSize();
        InputStream content = uploadedFile.getInputStream();
        // ...
    }
    

    The upload maximum and threshold size configuration of the filter can be migrated to <multipart-config> entry of the <servlet> entry of the FacesServlet in web.xml like below:

    <servlet>
        <servlet-name>facesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <multipart-config>
            <max-file-size>52428800</max-file-size>
            <file-size-threshold>1048576</file-size-threshold>
        </multipart-config>
    </servlet>
    <servlet-mapping>
        <servlet-name>facesServlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    

    See also:


    Unrelated to the concrete problem, the facelets.LIBRARIES is Facelets 1.x specific. During the JSF 1.x era, Facelets was a standalone view technology. Since JSF 2.0, Facelets is embedded in JSF itself and all its context parameters are migrated from facelets.XXX to javax.faces.FACELETS_XXX. You can find them all in a.o Overview of all JSF-related web.xml context parameter names and values. However, you don't need to explicitly register that Tomahawk taglib as well. Just get rid of it.