2
votes

I am using Primefaces fileUpload component in advanced mode to upload multiple images. When i select few files and press upload button, my @ViewScoped managed bean recreates multiple times. That is a problem for me, because i want to store all files uploaded within one view interaction in separate folder, but I'm getting multiple folders - one for each file. When I made my managed bean @SessionScoped the problem is gone, also i found that this bug appears only after server restart for the first uploading, so when i reload view and upload data second time everything is ok.

I am using Tomcat 7, jsf 2.2 and prime faces 5.1

Here is jsf 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: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>
    <f:facet name="first">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    </f:facet>

    <title>Jsf Upload</title>
</h:head>

<h:body>
    <h:form id="growlForm">
        <p:growl id="growl" showDetail="true" showSummary="true" />
    </h:form>

    <h:form id="uploadForm" enctype="multipart/form-data">
        <p:fileUpload fileUploadListener="#{uploadController.upload}"
            mode="advanced" multiple="true" label="Choose"
            uploadLabel="Upload" cancelLabel="Cancel" />
    </h:form>
</h:body>

</html>

Managed Bean:

@ManagedBean
@ViewScoped
public class UploadController implements Serializable {

    private static final long serialVersionUID = 5711090879027971547L;

    private static final Logger logger = LoggerFactory
            .getLogger(UploadController.class);

    private List<UploadedFile> files;

    public UploadController() {
        logger.info("UploadController constructor call");
        files = new ArrayList<UploadedFile>();
    }

    @PostConstruct
    public void init() {
        logger.info("Post Construct init() method call");
    }

    public void upload(FileUploadEvent event) {
        logger.info("upload() method call, file = {}", event.getFile()
                .getFileName());
        files.add(event.getFile());
        logger.info("Added file = {}", event.getFile().getFileName());
    }
}

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_2_5.xsd"
    version="2.5">
    <display-name>JsfUpload</display-name>

    <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>primefaces.THEME</param-name>
        <param-value>bootstrap</param-value>
    </context-param>

    <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>
    </filter-mapping>

    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>
</web-app>

Here is my logging output, showing that constructor and @PostConstruct method called multiple times:

2014-12-08 18:57:24,629 [http-bio-8380-exec-7] INFO  ru.duytsev.test.upload.UploadController - UploadController constructor call
2014-12-08 18:57:24,629 [http-bio-8380-exec-7] INFO  ru.duytsev.test.upload.UploadController - Post Construct init() method
2014-12-08 18:57:24,645 [http-bio-8380-exec-7] INFO  ru.duytsev.test.upload.UploadController - upload() method call, file = brick-yellow.png
2014-12-08 18:57:24,645 [http-bio-8380-exec-7] INFO  ru.duytsev.test.upload.UploadController - Added file = brick-yellow.png
2014-12-08 18:57:24,666 [http-bio-8380-exec-6] INFO  ru.duytsev.test.upload.UploadController - UploadController constructor call
2014-12-08 18:57:24,666 [http-bio-8380-exec-6] INFO  ru.duytsev.test.upload.UploadController - Post Construct init() method
2014-12-08 18:57:24,666 [http-bio-8380-exec-6] INFO  ru.duytsev.test.upload.UploadController - upload() method call, file = brick-purple.png
2014-12-08 18:57:24,666 [http-bio-8380-exec-6] INFO  ru.duytsev.test.upload.UploadController - Added file = brick-purple.png
2014-12-08 18:57:24,678 [http-bio-8380-exec-4] INFO  ru.duytsev.test.upload.UploadController - UploadController constructor call
2014-12-08 18:57:24,679 [http-bio-8380-exec-4] INFO  ru.duytsev.test.upload.UploadController - Post Construct init() method
2014-12-08 18:57:24,679 [http-bio-8380-exec-4] INFO  ru.duytsev.test.upload.UploadController - upload() method call, file = brick-green.png
2014-12-08 18:57:24,679 [http-bio-8380-exec-4] INFO  ru.duytsev.test.upload.UploadController - Added file = brick-green.png
2014-12-08 18:57:24,693 [http-bio-8380-exec-5] INFO  ru.duytsev.test.upload.UploadController - upload() method call, file = brick-orange.png
2014-12-08 18:57:24,694 [http-bio-8380-exec-5] INFO  ru.duytsev.test.upload.UploadController - Added file = brick-orange.png
2014-12-08 18:57:24,715 [http-bio-8380-exec-8] INFO  ru.duytsev.test.upload.UploadController - upload() method call, file = brick-blue.png
2014-12-08 18:57:24,715 [http-bio-8380-exec-8] INFO  ru.duytsev.test.upload.UploadController - Added file = brick-blue.png

My pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ru.duytsev.test.upload</groupId>
    <artifactId>JsfUpload</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <repositories>
        <repository>
            <id>prime-repo</id>
            <name>PrimeFaces Maven Repository</name>
            <url>http://repository.primefaces.org</url>
            <layout>default</layout>
        </repository>
    </repositories>

    <!-- PrimeFaces -->
    <dependencies>
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>5.1</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces.extensions</groupId>
            <artifactId>all-themes</artifactId>
            <version>1.0.8</version>
            <type>pom</type>
        </dependency>

        <!-- JSF -->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.2.8-02</version>
        </dependency>
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.2.8-02</version>
        </dependency>

        <!-- Java EE -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>3.0-alpha-1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- EL -->
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>el-impl</artifactId>
            <version>2.2.1-b05</version>
        </dependency>

        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.7</version>
        </dependency>

        <!-- APACHE COMMONS -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>${pom.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
1

1 Answers

-3
votes

Change to @ViewScoped. This causes the constructor to be called only once