Primefaces FileUpload 組件範例教程

今天我們將深入研究 Primefaces 的文件上傳(FileUpload)組件。HTML提供了文件輸入標籤,以選擇文件,但要將文件上傳到伺服器,我們需要更多的東西。Primefaces通過提供現成的FileUpload組件,幫助您在後端支持的情況下創建美觀的用戶界面,消除了這一負擔。

Primefaces文件上傳

我們將深入了解您可以在應用程序中使用的 Primefaces 文件上傳組件功能。本教程假設您對Primeface有基本的了解,如果沒有,請參閱Primefaces示例

Primefaces文件上傳基本信息

Tag fileUpload
Component Class org.primefaces.component.fileupload.FileUpload
Component Type org.primefaces.component.FileUpload
Component Family org.primefaces.component
Renderer Type org.primefaces.component.FileUploadRenderer
Renderer Class org.primefaces.component.fileupload.FileUploadRenderer

Primefaces文件上傳屬性

Name Default Type Description
id null String Unique identifier of the component.
rendered true boolean Boolean value to specify the rendering of the component, when set to false component will not be rendered
binding null Object An el expression that maps to a server side UIComponent instance in a backing bean
value null Object Value of the component than can be either an EL expression of a literal text
converter null Converter/String An el expression or a literal text that defines a converter for the component. When it’s an EL expression, it’s resolved to a converter instance. In case it’s a static text, it must refer to a converter id.
immediate false Boolean When set true, process validations logic is executed at apply request values phase for this component
required false Boolean Marks component as required.
validator null MethodExpr A method expression that refers to a method validating the input
valueChangeListener null MethodExpr A method expression that refers to a method for handling a valueChangeEvent
requiredMessage null String Message to be displayed when required field validation fails
converterMessage null String Message to be displayed when conversion fails.
validatorMessage null String Message to be displayed when validation fails.
widgetVar null String Name of the client side widget.
update null String Component(s) to update after fileupload completes.
process null String Component(s) to process in fileupload request.
fileUploadListener null MethodExpr Method to invoke when a file is uploaded.
multiple false Boolean Allows choosing of multi file uploads from native
auto false Boolean When set to true, selecting a file starts the upload process implicitly
label Choose String Label of the browse button.
allowTypes null String Regular expression for accepted file types,
sizeLimit null Integer Individual file size limit in bytes.
fileLimit null Integer Maximum number of files allowed to upload.
style null String Inline style of the component.
styleClass null String Style class of the component.
mode advanced String Mode of the fileupload, can be simple or advanced.
uploadLabel Upload String Label of the upload button.
cancelLabel Cancel String Label of the cancel button.
invalidSizeMessage null String Message to display when size limit exceeds.
invalidFileMessage null String Message to display when file is not accepted.
fileLimitMessage null String Message to display when file limit exceeds.
dragDropSupport true Boolean Specifies dragdrop based file selection from filesystem, default is true and works only on supported browsers
onstart null String Client side callback to execute when upload begins.
onerror null String Callback to execute if fileupload request fails.
oncomplete null String Client side callback to execute when upload ends.
disabled false Boolean Disables component when set true.
messageTemplate {name} {size} String Message template to use when displaying file validation errors
previewWidth 80 Integer Width for image previews in pixels.

Primefaces 檔案上傳範例

為了使用 FileUpload,您必須通過添加 primefaces.UPLOADER 網絡部署參數來提供 FileUpload 引擎,該參數可能取以下值:web.xml

<context-param>
  <param-name>primefaces.UPLOADER</param-name>
  <param-value>auto|native|commons</param-value>
</context-param>
  1. auto: 這是默認模式,Primefaces 嘗試通過檢查運行時環境來檢測最佳方法,如果 JSF 運行時至少為 2.2,則選擇本地上傳程序,否則選擇 commons。
  2. native: 本地模式使用 servlet 3.x Part API 上傳文件,如果 JSF 運行時小於 2.2,則會拋出異常。
  3. 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 模式進行配置。

Primefaces 簡單檔案上傳

簡單檔案上傳模式適用於舊版瀏覽器,其中文件輸入的值應該是一個 UploadedFile 實例。簡單上傳不支援 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.journaldev.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.journaldev</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 引擎為 auto
  2. fileUpload 元件的值屬性與 UploadedFile 實例關聯。
  3. 使用 fileUpload 需要將 fileUpload 元件包含在表單內,其 enctype 為 multipart/form-data
  4. 提供的虛擬動作用於打印上傳文件的名稱和大小。

在哪裡,演示的結果將是:簡單的輸入按鈕已經渲染到您的瀏覽器中。 一旦您點擊了虛擬動作,將執行一個虛擬動作方法,並且上傳文件的信息將被打印到您的控制台中,如下所示。

Primefaces高級文件上傳

FileUpload元件提供了簡易檢視和高級檢視。選擇高級檢視會使訪問上傳文件的唯一可用方式是通過FileUploadListener。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 Tutorial</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>
package com.journaldev.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("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
	}
}

總結:

  1. 既未提及web.xml也未提及pom.xml,因為它們沒有更改。
  2. FileUpload元件的value屬性與UploadedFile實例關聯,因為該元件也被FileUploadListener監聽。
  3. FileUploadListener接收FileUploadEvent作為參數。
  4. 一旦您點擊了上傳操作,FileUploadListener將被執行,並創建並傳遞了FileUploadEvent。

在哪裡,demo 的結果將是一個帶有兩個額外按鈕的新的上傳組件視圖;一個用於上傳,另一個用於取消。 執行的結果要注意以下幾點:

  1. 上傳的文件在 FileUploadEvent 中傳遞,可以通過對事件對象調用e.getFile()來訪問,它返回一個 UploadedFile 實例。
  2. 上傳過程將完全取消,如果您點擊了取消而不是上傳。取消上傳將阻止呼叫程序。

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 Tutorial</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>
package com.journaldev.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("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
	}
}

在執行應用程序的結果如下所示: 從演示中注意以下要點是重要的:

  1. 使用取消按鈕取消上傳應該導致取消所有文件的上傳過程。
  2. 點擊旁邊的X圖標,將導致相應的文件上傳被取消。
  3. 一旦單擊上傳操作,侦听器將被触发,依據加載的文件數。

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 Tutorial</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 配備了更新屬性以此為目的。以下示例顯示了在文件上傳後使用growl組件顯示“文件上傳成功”消息。文件上傳後將討論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.journaldev.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){
		// 從FileUploadEvent中獲取上傳的文件
		this.file = e.getFile();
		// 輸出文件信息
		System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
		// 添加消息
		FacesContext.getCurrentInstance().addMessage(null,new FacesMessage("File Uploaded Successfully"));
	}
}

執行結果如下:一條消息已添加到FacesContext中,FileUpload組件定義了更新屬性,這將通過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 檔案上傳驗證訊息

invalidFileMessageinvalidSizeMessagefileLimitMessage 選項可用於向用戶顯示驗證訊息。您可以為這些驗證提供任何您想要的訊息。請參閱以下提供的示例: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: Invalid Size"
								invalidFileMessage="JournalDev: Invalid File Type"
								fileLimitMessage="JournalDev: Invalid File Limit"
								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 FileUpload 摘要

這個教程旨在為您提供有關使用FileUpload Primefaces組件的詳細解釋。 FileUpload組件配備了許多功能,使您專注於業務,而不是嘗試實現類似的東西。 您可以從下面的鏈接下載示例項目,並使用其他fileUpload屬性來進一步了解。

下載PrimeFaces FileUpload項目

Source:
https://www.digitalocean.com/community/tutorials/primefaces-fileupload-component-example-tutorial