p:fileUpload calls bean constructor for each file

不打扰是莪最后的温柔 提交于 2019-12-24 07:13:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!