I'm having trouble with fileUpload and JSF2's templating mechanism. I've searched widely and there are other's with similar problems (eg here and here, but my problem seems to be directly related to my use of the templating mechanism as it works OK outside of that mechanism.
I have an xhtml form that I insert into a template using <ui:insert>
in the template and <ui:composition
/ <ui:define>
in the form. The Listener on the bean for the file upload is never called. However, if I mod the form so as to be capable of being a standalone page, then the upload works OK. So, apparently, something to to with the templating process is changing my results.
I know that using the templating mechanism with the code fragments below results in two nested forms, but I've tried removing one and there's no change. The resulting HTML looks sensible in the browser, so what could be going on?
My xhtml form...
<?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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:myfaces="http://myfaces.apache.org/tomahawk"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="MJLSConsole.xhtml">
<ui:param name="title" value="Sender Info" />
<ui:define name="content">
<h:form id="senderInfo">
<h:panelGrid columns="2" >
<p:outputLabel for="imageId" id="icon" value="Organisation Icon"/>
<p:fileUpload id="imageId" value="#{senderInformationBean.file}" required="true" mode="simple"/>
</h:panelGrid>
<p:commandButton value="Save" action="#{senderInformationBean.save}" ajax="false" />
</h:form>
</ui:define>
</ui:composition>
</html>
and here's my template
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</h:head>
<h:body>
<h:form id="testpage" enctype="multipart/form-data">
<p:growl id="messages" sticky="true" autoUpdate="true" />
<ui:insert name="content">Content</ui:insert>
</h:form>
</h:body>
</html>
and my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Mjls_main</display-name>
<context-param>
<description>Specifies the root of the spring application context</description>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/cxf-beans.xml</param-value>
</context-param>
<listener>
<description>Starts spring application context</description>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<description>Bridges http requests to ContextLoaderListener</description>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<description>JSF server</description>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<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>facesServlet</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>MJActionService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>MJEnvelopeService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>MJActionEventService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>SenderInformationBlockService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>MJTemplateService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>MJmlService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Notification_Portal_SignallingService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>MJInboundMessageService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>MjogServiceImplService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet>
<description>Provides soap services via Apache CXF</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<filter>
<description>Provides an ACL and role-based checks for associated services</description>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>restrictAccessFilter</filter-name>
<filter-class>com.mjog.mjls.filter.RestrictAccessFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>restrictAccessFilter</filter-name>
<url-pattern>/console/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>mjlsLogin.jsf</welcome-file>
</welcome-file-list>
<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>20m</param-value>
</init-param>
</filter>
<!-- extension mapping for adding <script/>, <link/>, and other resource tags to JSF-pages -->
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<!-- servlet-name must match the name of your javax.faces.webapp.FacesServlet entry -->
<servlet-name>facesServlet</servlet-name>
</filter-mapping>
<!-- extension mapping for serving page-independent resources (javascript, stylesheets, images, etc.) -->
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
</filter-mapping>
<servlet-mapping>
<servlet-name>MJActionService</servlet-name>
<url-pattern>/MJActionService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MJEnvelopeService</servlet-name>
<url-pattern>/MJEnvelopeService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MJActionEventService</servlet-name>
<url-pattern>/MJActionEventService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SenderInformationBlockService</servlet-name>
<url-pattern>/SenderInformationBlockService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MJTemplateService</servlet-name>
<url-pattern>/MJTemplateService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MJmlService</servlet-name>
<url-pattern>/MJmlService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Notification_Portal_SignallingService</servlet-name>
<url-pattern>/Notification_Portal_SignallingService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MJInboundMessageService</servlet-name>
<url-pattern>/MJInboundMessageService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MjogServiceImplService</servlet-name>
<url-pattern>/MjogServiceImplService</url-pattern>
</servlet-mapping>
<session-config>
<!-- logs inactive web users out after n minutes-->
<session-timeout>20</session-timeout>
</session-config>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>mjog</param-value>
</context-param>
<servlet>
<servlet-name>imageServlet</servlet-name>
<servlet-class>com.mjog.mjls.filter.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>imageServlet</servlet-name>
<url-pattern>/file/*</url-pattern>
</servlet-mapping>
</web-app>
and finally my bean is
@ManagedBean(name = "senderInformationBean")
public class SenderInformationBean implements Serializable {
transient private ConsoleService consoleService;
private UploadedFile file;
public void setConsoleService(ConsoleService consoleService) {
this.consoleService = consoleService;
}
public UploadedFile getFile() {
return file;
}
public void setFile(UploadedFile file) {
this.file = file;
}
public String save() throws IOException {
consoleService.save(accountName, contactAddress, contactNumber, emailId, accountUrl, file.getBytes());
populateSenderInfo();
return "/console/senderInformation.xhtml?faces-redirect=true";
}
}