2023年PrimeFaces文件上传组件完整教程:从入门到实战示例

这是文章《Primefaces的文件上传组件示例教程》的第1部分(共6部分)。

内容片段: 今天我们将介绍Primefaces的FileUpload组件。HTML提供了文件输入标签来选择文件,但要将文件上传到服务器,我们需要更多的操作。Primefaces通过提供现成的FileUpload组件,减轻了这个负担,帮助您创建美观的UI,并为文件上传提供后台支持。

Primefaces文件上传

我们将了解Primefaces FileUpload组件的功能,您可以在您的应用程序中使用。这个教程假设您具有Primeface的基本知识,如果没有,请先看Primefaces示例。

Primefaces 文件上传基本信息

标签 fileUpload
组件类 org.primefaces.component.fileupload.FileUpload
组件类型 org.primefaces.component.FileUpload
组件族 org.primefaces.component
渲染器类型 org.primefaces.component.FileUploadRenderer
渲染器类 org.primefaces.component.fileupload.FileUploadRenderer

Primefaces文件上传属性

名称 默认值 类型 描述
id null String 组件的唯一标识符。
rendered true boolean 指定组件是否渲染的布尔值,当设置为false时组件将不会被渲染。
binding null Object 映射到后端Bean中服务器端UIComponent实例的EL表达式。
value null Object 组件的值,可以是EL表达式或文本字面量。
converter null Converter/String 为组件定义转换器的EL表达式或文本字面量。当它是EL表达式时,它被解析为转换器实例。如果是静态文本,则必须引用转换器ID。
immediate false Boolean 当设置为true时,对此组件在应用请求值阶段执行验证逻辑。
required false Boolean 将组件标记为必填。
validator null MethodExpr 引用验证输入方法的表达式。
valueChangeListener null MethodExpr 引用处理valueChangeEvent方法的表达式。
requiredMessage null String 必填字段验证失败时显示的消息。
converterMessage null String 转换失败时显示的消息。
validatorMessage null String 验证失败时显示的消息。
widgetVar null String 客户端小部件的名称。
update null String 文件上传完成后要更新的组件。
process null String 在文件上传请求中要处理的组件。
fileUploadListener null MethodExpr 文件上传时调用的方法。
multiple false Boolean 允许从本机选择多个文件上传。
auto false Boolean 当设置为true时,选择文件会隐式启动上传过程。
label Choose String 浏览按钮的标签。
allowTypes null String 接受文件类型的正则表达式。
sizeLimit null Integer 单个文件大小限制(字节)。
fileLimit null Integer 允许上传的最大文件数量。
style null String 组件的内联样式。
styleClass null String 组件的样式类。
mode advanced String 文件上传的模式,可以是simple或advanced。
uploadLabel Upload String 上传按钮的标签。
cancelLabel Cancel String 取消按钮的标签。
invalidSizeMessage null String 大小限制超过时显示的消息。
invalidFileMessage null String 文件不被接受时显示的消息。
fileLimitMessage null String 文件限制超过时显示的消息。
dragDropSupport true Boolean 指定从文件系统中基于拖放的文件选择,默认为true,仅在支持的浏览器上工作。
onstart null String 上传开始时执行的客户端回调。
onerror null String 文件上传请求失败时执行的回调。
oncomplete null String 上传结束时执行的客户端回调。
disabled false Boolean 设置为true时禁用组件。
messageTemplate {name} {size} String 显示文件验证错误时使用的消息模板。
previewWidth 80 Integer 图像预览的宽度(像素)。

Primefaces文件上传示例

要使用FileUpload组件,您必须通过添加primefaces.UPLOADER的网络部署参数来提供FileUpload引擎,该参数可以接受以下值:auto、native或commons。在web.xml中的配置如下:

<context-param>
  <param-name>primefaces.UPLOADER</param-name>
  <param-value>auto|native|commons</param-value>
</context-param>

auto模式

这是默认模式,Primefaces会通过检查运行环境来尝试检测最佳方法。如果JSF运行时版本至少为2.2,则选择原生上传方式,否则选择commons。

native模式

使用servlet 3.x Part API来上传文件。如果JSF运行时版本小于2.2,则会抛出异常。

commons模式

选择commons fileUpload库,需要在部署描述符中进行以下过滤器配置。

web.xml 文件配置

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

请注意,servlet-name 应该与 JSF servlet 的配置名称匹配,也就是 Faces Servlet。或者,你也可以基于 URL-pattern 进行配置。

Primefaces 简单文件上传

简单文件上传模式适用于旧版浏览器,其中文件输入的值应该是一个已上传文件实例。简单上传不支持Ajax上传。请查看下面所需的文件以创建一个简单的文件上传示例。index.xhtml。

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data">
				<p:fileUpload value="#{fileUploadManagedBean.file}"  mode="simple"></p:fileUpload>
				<p:separator/>
				<h:commandButton value="Dummy Action" action="#{fileUploadManagedBean.dummyAction}"></h:commandButton>
		</h:form>
	</h:body>
</html>
package com.Olivia.prime.faces.beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.primefaces.model.UploadedFile;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
	UploadedFile file;

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public String dummyAction(){
		System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
		return "";
	}
}

web.xml 网络配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns="https://java.sun.com/xml/ns/javaee" xmlns:web="https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee
	https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5" metadata-complete="true">
	<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>/faces/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.xhtml</url-pattern>
	</servlet-mapping>
	<context-param>
		<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
		<param-value>client</param-value>
	</context-param>
	<context-param>
		<param-name>primefaces.UPLOADER</param-name>
		<param-value>auto</param-value>
	</context-param>
	<listener>
		<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
	</listener>
</web-app>

pom.xml -> 项目对象模型文件

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.Olivia</groupId>
  <artifactId>Primefaces-FileUpload-Sample</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Primefaces-FileUpload-Sample Maven Webapp</name>
   <url>https://maven.apache.org</url>
	<repositories>
		<repository>
			<id>prime-repo</id>
			<name>PrimeFaces Maven Repository</name>
			<url>https://repository.primefaces.org</url>
			<layout>default</layout>
		</repository>
	</repositories>
	<dependencies>
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<!-- Faces Implementation -->
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>2.2.4</version>
		</dependency>
		<!-- Faces Library -->
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>2.2.4</version>
		</dependency>
		<!-- Primefaces Version 5 -->
		<dependency>
			<groupId>org.primefaces</groupId>
			<artifactId>primefaces</artifactId>
			<version>5.0</version>
		</dependency>
		<!-- JSP Library -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
		</dependency>
		<!-- JSTL Library -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.1.2</version>
		</dependency>
	</dependencies>
</project>

简而言之:

    1. 使用的Primefaces FileUpload引擎是自动的。

 

    1. fileUpload组件的value属性与UploadedFile实例关联。

 

    1. 使用fileUpload需要在表单中包含fileUpload组件,其enctype为multipart/form-data。

 

    提供的虚拟操作用于打印上传文件的名称和大小。

在哪里,demo的结果将是:简单输入按钮已渲染到您的浏览器中。一旦您点击了”虚拟操作”,一个虚拟动作方法将执行,并且上传文件的信息将被打印到您的控制台中,如下所示。

Primefaces 高级文件上传

PrimeFaces文件上传组件高级视图教程

FileUpload组件提供了简单视图和高级视图两种模式。选择高级视图后,文件上传将通过FileUploadListener进行处理。当文件上传完成时,系统会将FileUploadEvent作为参数传递给监听器,从而触发相应的处理逻辑。请查看下方所需的文件,以帮助您使用高级模式。

index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev教程</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced"
							fileUploadListener="#{fileUploadManagedBean.fileUploadListener}"></p:fileUpload>
		</h:form>
	</h:body>
</html>

FileUploadManagedBean.java

package com.Olivia.prime.faces.beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
	UploadedFile file;

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public void fileUploadListener(FileUploadEvent e){
		// 从FileUploadEvent获取上传的文件
		this.file = e.getFile();
		// 输出文件信息
		System.out.println("上传的文件名是:"+file.getFileName()+" :: 文件大小是:"+file.getSize());
	}
}

关键点总结

  • 由于web.xml和pom.xml文件没有发生变化,因此在本部分中未提及。
  • 文件上传组件的value属性与UploadedFile实例相关联,同时组件也被FileUploadListener监听。
  • FileUploadListener接收FileUploadEvent作为参数。
  • 一旦点击”上传”按钮,FileUploadListener将被执行,同时创建并传递一个FileUploadEvent。

在演示结果中,上传组件会显示一个新的视图,包含两个额外的按钮:一个用于上传,另一个用于取消。在执行过程中,请注意以下几点:

  • 上传的文件通过FileUploadEvent传递,可以通过调用事件对象的e.getFile()方法访问,该方法返回一个UploadedFile实例。
  • 如果点击”取消”而不是”上传”,上传过程将完全终止。取消上传会阻止监听器被调用。

PrimeFaces多文件上传功能

使用FileUpload组件上传多个文件是可行的,用户可以从浏览器对话框中选择多个文件。需要注意的是,旧版本的浏览器不支持多次上传功能。将multiple属性设置为true,可以启用多文件选择功能,但需要注意的是,多文件选择并不意味着所有文件将在一个请求中发送到服务器,而是会逐个发送。请看下面所需的更改,以实现多文件选择功能:

index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev教程</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced" multiple="true"
							fileUploadListener="#{fileUploadManagedBean.fileUploadListener}"></p:fileUpload>
		</h:form>
	</h:body>
</html>

FileUploadManagedBean.java

package com.Olivia.prime.faces.beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
	UploadedFile file;

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public void fileUploadListener(FileUploadEvent e){
		// 从FileUploadEvent获取上传的文件
		this.file = e.getFile();
		// 输出文件信息
		System.out.println("上传的文件名是:"+file.getFileName()+" :: 文件大小是:"+file.getSize());
	}
}

在应用程序执行结果中,需要注意以下几点:

  • 点击”取消”按钮将取消上传操作并终止所有文件的上传过程。
  • 点击每个将要上传的文件旁边的X图标,将仅取消相应文件的上传。
  • 一旦点击了上传操作,监听器将根据已加载文件的数量被调用相应次数。

PrimeFaces自动文件上传功能

默认情况下,文件上传需要用户手动触发上传过程,但您可以通过将auto属性设置为true来更改这种行为。启用自动上传后,在选择对话框中的文件后,上传过程将立即开始。请看下面所需的更改,以实现自动上传功能:

index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev教程</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced" multiple="true" auto="true"
							fileUploadListener="#{fileUploadManagedBean.fileUploadListener}"></p:fileUpload>
		</h:form>
	</h:body>
</html>

一旦您点击了”打开”按钮,应用程序的执行结果如下所示:上传过程立即开始。

PrimeFaces文件上传局部页面更新

文件上传过程完成后,您可以使用Primefaces PPR(局部页面渲染)来更新页面上的任何组件。FileUpload的update属性就是为此目的而设计的。下面的例子展示了在文件上传后使用growl组件显示”文件上传成功”的消息。在后续的messages部分中,我们将详细讨论growl组件。下面的代码片段将帮助您在文件上传后显示一条消息。index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:growl id="msg"></p:growl>
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced"
							fileUploadListener="#{fileUploadManagedBean.fileUploadListener}" update="msg"></p:fileUpload>
		</h:form>
	</h:body>
</html>
package com.Olivia.prime.faces.beans;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
	UploadedFile file;

	public UploadedFile getFile() {
		return file;
	}

	public void setFile(UploadedFile file) {
		this.file = file;
	}

	public void fileUploadListener(FileUploadEvent e){
		// 获取上传的文件
		this.file = e.getFile();
		// 输出文件信息
		System.out.println("上传的文件名是 :: "+file.getFileName()+" :: 文件大小 :: "+file.getSize());
		// 添加消息
		FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("文件上传成功"));
	}
}

在执行的结果中,情况如下:已经将一条消息添加到FacesContext中,并且FileUpload组件定义了update属性,将通过Ajax机制渲染该消息。关于Ajax行为将在另一篇教程中讨论。

文件上传过滤器

文件上传过滤器可以限制用户只选择您配置的特定文件类型,下面的示例演示了如何设置只接受图像文件(index.xhtml)。

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:growl id="msg"></p:growl>
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
							fileUploadListener="#{fileUploadManagedBean.fileUploadListener}" update="msg"></p:fileUpload>
		</h:form>
	</h:body>
</html>

执行的结果如下:

Primefaces 文件上传大小限制与文件数量限制

有时候,您需要限制上传文件的大小或上传的文件数量。在Primefaces的FileUpload组件中,实现这些限制非常简单。您可以通过在FileUpload组件上分别设置sizeLimit和fileLimit属性来实现这些限制。以下是限制用户上传的代码片段:index.xhtml

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:growl id="msg"></p:growl>
				<p:fileUpload value="#{fileUploadManagedBean.file}" mode="advanced" multiple="true" fileLimit="3" sizeLimit="2048"
							fileUploadListener="#{fileUploadManagedBean.fileUploadListener}" update="msg"></p:fileUpload>
		</h:form>
	</h:body>
</html>

当您尝试上传超过三个文件或文件大小超过限制时,会显示以下错误消息:

Primefaces文件上传验证消息

Primefaces提供了invalidFileMessage、invalidSizeMessage和fileLimitMessage选项,用于向用户显示自定义验证消息。您可以根据需要为这些验证设置任何消息。请查看下面提供的示例,index.xhtml。

<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:ui="https://java.sun.com/jsf/facelets"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:p="https://primefaces.org/ui">
	<h:head>
		<title>Journaldev Tutorial</title>
	</h:head>
	<h:body>
		<h:form enctype="multipart/form-data" style="width:500px">
				<p:growl id="msg"></p:growl>
				<p:fileUpload value="#{fileUploadManagedBean.file}"
						invalidSizeMessage="JournalDev: 文件大小无效"
						invalidFileMessage="JournalDev: 文件类型无效"
						fileLimitMessage="JournalDev: 文件数量超出限制"
						mode="advanced" multiple="true" fileLimit="3" sizeLimit="2048"
						allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
						fileUploadListener="#{fileUploadManagedBean.fileUploadListener}"
						update="msg"></p:fileUpload>
		</h:form>
	</h:body>
</html>

消息显示效果如下:您会注意到消息内容已经更改,并显示了不同的文本值。如果您注意到受管bean代码,我们没有对文件进行任何操作。然而,在实际应用场景中,我们可以使用UploadedFile的getInputstream()方法获取文件数据,并将其保存到服务器或数据库中。

Primefaces文件上传总结

本教程旨在为您提供有关使用PrimeFaces的FileUpload组件的全面详细说明。FileUpload组件配备了许多功能,可以让您专注于业务逻辑而不是尝试实现类似功能。您可以从下面的链接下载示例项目,并通过探索其他文件上传属性来获取更多信息。

下载PrimeFaces文件上传项目

bannerAds