使用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>