I am working on a web application for mobile devices where a user can upload a file (image) on several occasions.
Since I am using the Primefaces mobile renderkit, I have to use Primefaces' simple p:fileupload
without ajax.
The Problem:
When I want to upload an Image I can select the file (components are rendered correctly) and then hit the "Upload" button. After I hit "Upload", the page refreshes but myBean.saveImage()
is never called. myBean.fileUploadController.setFile
isn't called either. I don't get any error messages in the Netbeans console and neither in Chromes JS Console.
So far I tried to use the native HTTP Servlet Upload which is supported by primefaces since version 5.0 and the old commons.fileupload way - same result.
I followed this great guide to troubleshoot p:fileupload
but I still get the same result after doing everything suggested in the guide.
I created a fileuploadtest.xhtml page to test the upload functionality which looks like this:
<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"
xmlns:pm="http://primefaces.org/mobile">
<f:view renderKitId="PRIMEFACES_MOBILE" />
<h:head>
</h:head>
<h:body>
<pm:page>
<pm:header title="Title"></pm:header>
<pm:content>
<h:form enctype="multipart/form-data">
<p:fileUpload value="#{myBean.fileUploadController.file}" mode="simple"/>
<p:commandButton value="Upload" ajax="false" action="#{myBean.saveImage}"/>
</h:form>
</pm:content>
<pm:footer title="Footer"></pm:footer>
</pm:page>
</h:body>
</html>
Here is my bean and my FileUploadController
class:
MyBean.java:
@Component
@Scope("session")
@Named
public class MyBean implements Serializable {
@Autowired(required = true)
private FileUploadController fileUploadController;
//Bunch of unrelated methods
public void saveImage() {
this.fileUploadController.upload();
//some more code after upload() is complete
}
//getters&setters
}
FileUploadController.java:
@Component
@Scope("session")
public class FileUploadController {
private UploadedFile file;
public boolean upload() {
if (file != null) {
//upload here
return true;
} else {
return false;
}
}
public UploadedFile getFile() {
return file;
}
public void setFile(UploadedFile file) {
this.file = file;
}
}
Here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
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_3_0.xsd">
<description>Webflow Archetype</description>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring/applicationContext.xml,/WEB-INF/config/web-application-config.xml
</param-value>
</context-param>
<!-- Causes Facelets to refresh templates during development -->
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.sendPoweredByHeader</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>cupertino</param-value>
</context-param>
<context-param>
<param-name>primefaces.FONT_AWESOME</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<description>Define partial state saving as true/false.</description>
<param-name>javax.faces.PARTIAL_STATE_SAVING_METHOD</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
<param-value>true</param-value>
</context-param>
<!-- Custom MarqueeComponent -->
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/marquee-taglib.xml</param-value>
</context-param>
<context-param>
<param-name>BootsFaces_USETHEME</param-name>
<param-value>true</param-value>
</context-param>
<filter>
<filter-name>charEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>charEncodingFilter</filter-name>
<url-pattern>/ *</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Allows Jetty to serve Faces applications -->
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/ *</url-pattern>
</filter-mapping>
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value>
</context-param>
<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>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<session-config>
<session-timeout>180</session-timeout>
<cookie-config>
<secure>true</secure>
</cookie-config>
</session-config>
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value/>
</init-param>
<load-on-startup>2</load-on-startup>
<multipart-config>
<max-file-size>10485760</max-file-size>
<max-request-size>20971520</max-request-size>
<file-size-threshold>5242880</file-size-threshold>
</multipart-config>
</servlet>
<!-- Map all /spring requests to the Dispatcher Servlet for handling -->
<servlet>
<servlet-name>Jersey Spring Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>at.managementpartners.icosysmobile.rest</param-value>
</init-param>
</servlet>
<!-- <servlet>
<servlet-name>GetClientHostnameServlet</servlet-name>
<servlet-class>at.managementpartners.icosysmobile.web.util.GetClientHostnameServlet</servlet-class>
</servlet> -->
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>at.managementpartners.icosysmobile.web.util.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/spring/ *</url-pattern>
</servlet-mapping>
<!-- Faces Servlet -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<multipart-config>
<max-file-size>10485760</max-file-size>
<max-request-size>20971520</max-request-size>
<file-size-threshold>5242880</file-size-threshold>
</multipart-config>
</servlet>
<!-- Faces Servlet Mapping -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/javax.faces.resource/ *</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/ *</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/do/ *</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<!--servlet>
<servlet-name>Primefaces Resource Servlet</servlet-name>
<servlet-class>
org.primefaces.resource.ResourceServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Primefaces Resource Servlet</servlet-name>
<url-pattern>/primefaces_resource/ *</url-pattern>
</servlet-mapping-->
<!-- Welcome files -->
<servlet-mapping>
<servlet-name>Jersey Spring Servlet</servlet-name>
<url-pattern>/rest</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Jersey Spring Servlet</servlet-name>
<url-pattern>/rest/ *</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/files/ *</url-pattern>
</servlet-mapping>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<trim-directive-whitespaces>false</trim-directive-whitespaces>
</jsp-property-group>
</jsp-config>
</web-app>
I configured this web.xml to work with commons.fileupload and not with the HTTP Servlet native Upload functionality.
Please note that I had to seperate ´/*´ with a space (´/ *´) so that the rest of my code wouldn't get formatted as a comment. (If there is a smarter way to do this please don't hesitate to tell me)
My web application relies on the following technologies/libraries:
JSF 2.2.9
HTTP Servlet 3.0.1
Spring MVC
Spring Webflow
Primefaces 6.0 with <f:view renderKitId="PRIMEFACES_MOBILE" />
Omnifaces 1.5
Bootsfaces 0.8.1
Netbeans as IDE
For testing and debugging purposes I deploy the app to Jetty 8.1.5 via Netbeans.
However I tried deploying the app to a Tomcat server as well with the same result.
Please forgive the long post, I just wanted to include everything that seemed remotely useful. If you need anything else please let me know.
Thank you very much in advance.
EDIT:
It appears that my problem does not have anything to do directly with p:fileupload
but rather with my p:commandButton
s not invoking any action event at all, when I disable ajax. To test this, I added the ajax="false"
attribute to one of my comandButtons on another page. As soon as I added it, my commandButton stopped working and it just refreshed the site but never handled the event specified in the action
attribute. Does anyone have an idea why my commandbuttons stop working with ajax="false"
?
Edit2
I posted a new question since I discovered that the problem is related to something slightly different