PrimeFaces 4.0 FileUpload works with Mojarra 2.2 but not MyFaces 2.2

2k views Asked by At

I am having an interesting problem with the PrimeFaces 4.0 final FileUpload element. I am trying to run:

  • PrimeFaces 4.0 final
  • Apache MyFaces 2.2.0-beta
  • Tomcat 7.0.27

I have a very simple setup right now,

XHTML page:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form>
    <p:fileUpload
        fileUploadListener="#{fileUploadController.handleFileUpload}"
        mode="advanced" update="messages" sizeLimit="100000"
        allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />

    <p:growl id="messages" showDetail="true" />
</h:form>
</h:body>
</html>

With this backing bean:

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.FileUploadEvent;

@ManagedBean
@RequestScoped  
public class FileUploadController
{
    public void handleFileUpload(FileUploadEvent event)
    {
        FacesMessage msg = new FacesMessage("Succesful", event.getFile()
                .getFileName() + " is uploaded.");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
}

When selecting a file and uploading it, nothing happens.

The upload submit succeeds with the following response:

<?xml version="1.0" encoding="UTF-8"?><partial-response><changes><update id="j_id__v_0:javax.faces.ViewState:1"><![CDATA[2C7ZmtwSmrlbgI/wJLI2CLBaMOQP9R/pYkIXpHlXkhSKIhtfFM0sx0HmL8o9MQY2MdHXg4t1vUjJbUYkAdFBmOQUaFy7hFhPr34Za4hOuLW4CPNx]]></update></changes></partial-response>

but no message is displayed, and if I set a breakpoint, it does not get hit.

If, however, I pull out MyFaces 2.2.0-beta and put in Mojarra 2.2.0, everything works as expected.

I would prefer to continue to use MyFaces as it is what I've used in the past, so if anyone has any ideas as to a patch to get this to work, it would be much appreciated.

Thank you

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
<display-name>UploadTest</display-name>
<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
</context-param>
<context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>
<context-param>
    <description>
This parameter tells MyFaces if javascript code should be allowed in
the rendered HTML output.
If javascript is allowed, command_link anchors will have javascript code
that submits the corresponding form.
If javascript is not allowed, the state saving info and nested parameters
will be added as url parameters.
Default is 'true'</description>
    <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
    <param-value>true</param-value>
</context-param>
<context-param>
    <description>
If true, rendered HTML code will be formatted, so that it is 'human-readable'
i.e. additional line separators and whitespace will be written, that do not
influence the HTML code.
Default is 'true'</description>
    <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
    <param-value>true</param-value>
</context-param>
<context-param>
    <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
    <param-value>false</param-value>
</context-param>
<context-param>
    <description>
If true, a javascript function will be rendered that is able to restore the
former vertical scroll on every request. Convenient feature if you have pages
with long lists and you do not want the browser page to always jump to the top
if you trigger a link or button action that stays on the same page.
Default is 'false'
</description>
    <param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
    <param-value>true</param-value>
</context-param>
<listener>
    <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
<!--        <listener-class>com.sun.faces.config.ConfigureListener</listener-class> -->
</listener>

Update

It seems that Myfaces 2.2.0-beta has problems using the Part API present in servlet 3.x.

udaykiran pulipati has part of a solution with using web the web.xml filters that PrimeFaces 3.x required and the commons file upload & commons io jars, however, we also need to add the following context-param to the web.xml or the filters get ignored :

<context-param>
  <param-name>primefaces.UPLOADER</param-name>
  <param-value>commons</param-value>
</context-param>

This will force PrimeFaces to use the commons library which fixes the problem

That being said, I would still like to know why MyFaces can't seem to use the servlet Part API if anyone has any ideas. I suspect it may have to do with my Tomcat version as I am only on 7.0.27, but I doubt that.


3

There are 3 answers

1
UdayKiran Pulipati On

Mention below filters in web.xml file for uploading a file using PrimeFaces

<!-- PrimeFaces FileUpload Filter -->
<filter>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>PrimeFaces FileUpload Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

and add jars to lib folder. PrimeFaces needs below jars for fileuploading.

commons-fileupload-1.3.jar, commons-io-2.4.jar

0
lu4242 On

Recently it was found a similar issue with a better description in MYFACES-3835. It was a problem related to webkit browsers that only appears when the ajax response is large enough. It has been already fixed.

0
Howard On

udaykiran pulipati's answer motivated me to replace commons-fileupload-1.2.2.jar with commons-fileupload-1.3.jar in my project, but that didn't solve the issue for me, as I'm using MyFaces 2.2, PrimeFaces Elite 4.0.8, and TomEE 1.6.1-snapshot.

Also, per udaykiran pulipati's answer, I already added PrimeFaces FileUpload filter config to my web.xml, many months ago.

So, I looked at PrimeFaces 4.0 user guide, and recognized something 'new' that could be specified in web.xml. So, I added the following to my web.xml,

<context-param>
    <param-name>primefaces.UPLOADER</param-name>
    <param-value>commons</param-value>
</context-param>    

and finally, PrimeFaces (Elite) 4.0.x FileUpload works with MyFaces 2.2.