使用h:inputFile时,@ ViewScoped托管bean被破坏

时间:2016-01-26 20:14:06

标签: jsf file-upload jsf-2 view-scope

使用h:inputFile在JSF 2.2.7和Glassfish 4.1中上传文件时遇到问题。我试图让h:inputFile工作,但每当我使用Part中上传的h:inputFile对象时,Backing bean就会被销毁并再次创建。此外,永远不会调用Part对象的setter。我试图通过仅使用上传创建页面来隔离问题(从jsf示例项目复制),但问题仍然存在。我也尝试使用Primefaces p:fileUpload,但问题仍然存在。我也无法通过谷歌搜索找到任何解决方案。谢谢你的帮助。

JSF页面testMinUpload.xhtml(已从表单中删除prependId="false"

<?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:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui">
<f:view>
    <h:form id="form" enctype="multipart/form-data">
        <h:messages/>
        <h:panelGrid columns="2">
            <h:outputText value="File:"/>
            <h:inputFile id="file" value="#{uploadController.file}"
                         validator="#{uploadController.validateFile}"/>
        </h:panelGrid>

        <h:commandButton value="Upload File" action="#{uploadController.upload}"/>
        <h:commandButton value="Upload File (Ajax)" action="#{uploadController.upload}">
            <f:ajax execute="file" render="@all"/>
        </h:commandButton>

        <h:panelGrid id="content" columns="1">
            <h:outputText value="Content:"/>
            <h:inputTextarea readonly="true" value="#{uploadController.fileContent}"
                             rows="10" cols="100"/>
        </h:panelGrid>
    </h:form>
</f:view>
</html>

Backing Bean

@ManagedBean(name = "uploadController")
@ViewScoped
public class TestFileUploadController implements Serializable {

    private Part file;
    private String fileContent;

    @PostConstruct
    public void init() {
        System.out.println("init() called");
    }

    public Part getFile() {
        return file;
    }

    public void setFile(Part file) {
        System.out.println("setFile() has been called");
        this.file = file;
    }

    /**
     * Gets the file contents of the file.
     */
    public void upload() {
        try {
            fileContent = new Scanner(file.getInputStream())
                    .useDelimiter("\\A").next();
        } catch (IOException e) {
            // Error handling
        }
    }

    /**
     * Validates the file.
     */
    public void validateFile(FacesContext ctx,
                             UIComponent comp,
                             Object value) {
        System.out.println("validateFile() called");
        List<FacesMessage> msgs = new ArrayList<FacesMessage>();
        Part file = (Part)value;
        if (file.getSize() > 1024) {
            msgs.add(new FacesMessage("file too big"));
        }
        if (!"text/plain".equals(file.getContentType())) {
            msgs.add(new FacesMessage("not a text file"));
        }
        if (!msgs.isEmpty()) {
            throw new ValidatorException(msgs);
        }
    }

    public String getFileContent() {
        return fileContent;
    }

    public void setFileContent(String fileContent) {
        this.fileContent = fileContent;
    }
}

web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
  <display-name>MyApp</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>

  <welcome-file-list>
    <welcome-file>testMinUpload.xhtml</welcome-file>
  </welcome-file-list>

  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>

</web-app>

faces-config.xml

    <?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
    http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

    <application>
        <locale-config>
            <default-locale>de</default-locale>
            <supported-locale>en</supported-locale>
        </locale-config>

    </application>

</faces-config>

pom.xml(更新为仅包含javaee-web-api作为依赖项)

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>bar.foo</groupId>
  <artifactId>myapp</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>myapp</name>
  <url>http://foo.bar</url>
  <licenses>
    <license>
      <name>GNU Affero General Public License, Version 3</name>
      <url>https://gnu.org/licenses/agpl-3.0.txt</url>
    </license>
  </licenses>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <compilerArgument>-Xlint:all</compilerArgument>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.glassfish.embedded</groupId>
        <artifactId>maven-embedded-glassfish-plugin</artifactId>
        <version>4.1.1</version>
        <configuration>
          <autoDelete>true</autoDelete>
          <port>8080</port>
        </configuration>

        <dependencies>
          <dependency>
            <groupId>org.glassfish.main.extras</groupId>
            <artifactId>glassfish-embedded-all</artifactId>
            <version>4.1</version>
          </dependency>
        </dependencies>

        <executions>
          <execution>
            <goals>
              <goal>deploy</goal>
            </goals>
            <configuration>
              <app>target/${project.artifactId}-${project.version}.war</app>
              <name>${project.artifactId}</name>
              <contextRoot>/${project.artifactId}</contextRoot>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>2.17</version>
        <configuration>
          <configLocation>checkstyle.xml</configLocation>
          <consoleOutput>true</consoleOutput>
          <failOnViolation>true</failOnViolation>
        </configuration>
        <executions>
          <execution>
            <phase>verify</phase>
            <goals>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>findbugs-maven-plugin</artifactId>
        <version>3.0.3</version>
        <executions>
          <execution>
            <phase>verify</phase>
            <goals>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

    </plugins>
  </build>

</project>

glassfish-web.xml(我已经尝试将类加载器委托设置为true,但这并没有解决问题)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 4.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
    <class-loader delegate="false" />
</glassfish-web-app>

0 个答案:

没有答案