问题
I'm trying to use <p:fileUpload>
to upload a file. Here's the view:
<h:form enctype="multipart/form-data">
<p:growl id="messages" showDetail="true" />
<p:fileUpload
fileUploadListener="#{viewscopedBean.handleFileUpload}"
mode="advanced" dragDropSupport="true" multiple="true"
update="messages" />
</h:form>
Bean:
@ManagedBean
@ViewScoped
public class ViewscopedBean implements Serializable{
private List<UploadedFile> uploadedFiles; //to remember which files have been uploaded
public ViewscopedBean() {
super();
System.out.println("@constructor");
uploadedFiles = new ArrayList<UploadedFile>();
}
public void handleFileUpload(FileUploadEvent event) {
System.out.println("! HANDLE FILE UPLOAD !");
// do something
}
public List<UploadedFile> getUploadedFiles() {
return uploadedFiles;
}
public void setUploadedFiles(List<UploadedFile> uploadedFiles) {
this.uploadedFiles = uploadedFiles;
}
}
web.xml
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>
org.primefaces.webapp.filter.FileUploadFilter
</filter-class>
<init-param>
<param-name>thresholdSize</param-name>
<param-value>512000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
When I click on the upload button
, the progressbar is filling up to 100% (like it does something), but then the page is reloaded (constructor is being called for every uploaded file) - the handleFileUpload
method is never called.
There aren't any errors or warnings, it just doesn't do what it should. I have JSF 2.0 and use Primefaces 4, maybe there is a problem?
How is this caused and how can I solve it?
回答1:
First things first, ensure that you have commons-fileupload
and its compile-time dependency commons-io
on your classpath. The handler not being called suggests that you have these dependencies missing.
Since 4.0
, there is now an optional context-param which specifies the server-side engine for handling FileUpload uploads:
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>auto|native|commons</param-value>
</context-param>
In the absence of the context-param
, PrimeFaces otherwise selects the most appropriate uploader engine by detection.
Given that you are not using JSF 2.2
, this means that it will first select auto, and therefore will redirect to use commons.
So you can see how important it is that you have commons-fileupload
and commons-io
in your project.
When I copied and pasted your code into a Primefaces 3.5
project containing these dependencies, your code worked for me. The constructor was called once and only once, and the handle method was called each time I uploaded a file.
I repeated the test using 4.0
and again, the constructor was called once and only once.
Here's the configuration that I used in web.xml
(needed by commons-fileupload
):
<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>
Here's the backing bean:
package uk;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
@ManagedBean(name = "tempBean")
@ViewScoped
public class TempBean {
private List<UploadedFile> uploadedFiles; //to remember which files have been uploaded
public TempBean() {
super();
System.out.println("@constructor");
uploadedFiles = new ArrayList<UploadedFile>();
}
public void handleFileUpload(FileUploadEvent event) {
System.out.println("! HANDLE FILE UPLOAD !");
// do something
}
public List<UploadedFile> getUploadedFiles() {
return uploadedFiles;
}
public void setUploadedFiles(List<UploadedFile> uploadedFiles) {
this.uploadedFiles = uploadedFiles;
}
}
Here's the page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" 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"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:body>
<h:form enctype="multipart/form-data">
<p:growl id="messages" showDetail="true" />
<p:fileUpload
fileUploadListener="#{tempBean.handleFileUpload}"
mode="advanced" dragDropSupport="true" multiple="true"
update="messages" />
</h:form>
</h:body>
</html>
And finally here is the snippet of my POM that contains the dependencies and versions for Apache Commons:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3</version>
</dependency>
来源:https://stackoverflow.com/questions/20131465/pfileupload-calls-bean-constructor-for-each-file