在Visual Web JSF 应用程序中上传文件
这篇教程描述了如何使用 NetBeans IDE 6.5 创建上传和显示图片(JPEG, PJPEG, GIF, PNG, 或者 X-PNG)文件的应用程序。同时,包含了一个迷你教程--怎样上传文本文件
内容

预期持续时间: 20 分钟
学习本教程需要以下软件和资源:
* 要利用 NetBeans IDE 的 Java EE 5 功能,请使用完全符合 Java EE 5 规范的应用服务器,例如 GlassFish V2 UR2 应用服务器. 如果你使用的是不同的是应用服务器,请查阅 发行注记 和 FAQs 了解已知问题和解决方法。 关于支持的服务器和Java EE 平台的更多详细信息 请看 发行注记.
关于文件上传组件
文件上传组件 允许 web 应用程序 的用户查找本地文件并且允许将文件上传的服务器上。这个组建对于收集(collecting)文本文件,图片文件,和其他数据 非常的有用。上传文件的内容将和这个文件的一些信息同时存储,包括文件名,大小,还有文件类型 (例如 text/plain 或者 image/jpeg)。
当文件小于4096 字节时,在这种情况下 服务器将文件的内容当成临时文件保存在 服务器的内存中。通过在 Web 应用程序的 web.xml 文件中修改 UploadFilter 过滤器条目的 sizeThreshold 参数,可以更改此阈值。有关修改 web.xml 文件的详细信息,请参见本教程的最后一节:执行更多操作:修改最大文件上传大小。
如果您想保留上传的文件,你有三种选择:
- 将该文件写入所选位置,如本教程中所示。
- 在受管 Bean 中创建
UploadedFile 属性,并在退出页面之前将其设置为组件的值(类似按钮的操作方法)。
- 将该文件保存到数据库。
缺省情况下,文件上传组件最多可以处理 1 MB 的文件。如本教程最后一节执行更多操作:修改最大文件上传大小中所述,通过在应用程序的 web.xml 文件中修改 UploadFilter 过滤器条目的 maxSize 参数,可以更改最大文件大小。
创建包含文件上传组件的页面
首先,生成一个表单,用户可以使用该表单选择要上传的文件。
- 创建一个新的 Web 应用程序项目,将其命名为
FileUploadExample,并启用 Visual Web JavaServer Faces 框架。
下图显示了将在后续步骤中创建的页面:

- 从组件面板的“基本”类别中,将一个标签组件拖放到页面上,键入
Choose a File to Upload:,然后按 Enter 键。
- 将一个文件上传组件拖放到页面上,并将其放在标签组件的下面。
- 将一个按钮组件拖放到页面上,键入
Upload File,然后按 Enter 键。在“属性”窗口中,将按钮的 id 属性设置为 uploadFileButton。
- 将一个标签组件拖放到页面上,并将其 text 属性设置为
File Name:
- 将一个静态文本组件放在该标签的右侧。在“属性”窗口中,将静态文本的
id 属性设置为 fileNameStaticText。
- 将另一个标签拖放到页面上。将该标签的 text 属性设置为
File Type:
- 将一个静态文本组件放在新标签的右侧:将静态文本的
id 设置为 fileTypeStaticText。
- 将另一个标签和静态文本对拖放到页面上。将标签 text 属性设置为
File Size:,并将静态文本的 id 设置为 fileSizeStaticText。
- 将一个图像组件放在静态文本组件的下方。
- 将一个消息组组件放在图像组件的下方。
添加代码以处理图像上传
现在已经具备了基本的文件上传表单,您必须添加代码才能处理文件上传。
-
双击 "Upload File" 按钮打开 Java 编辑器,并将该按钮的事件处理程序 uploadFileButton_action 添加到页面 Bean。
在将代码添加到此方法之前,您需要定义用于存储图像文件的变量,并将代码添加到 init() 和 prerender() 方法。
-
向上滚动至 init() 方法,并在该方法前添加以下两个变量。
| 代码样例 1:变量 |
private String realImageFilePath; private static final String IMAGE_URL = "/resources/image-file";
|
变量 realImageFilePath 是图像文件在服务器上的实际路径和文件名。变量 IMAGE_URL 是图像文件在运行的 Web 应用程序中的逻辑路径。
-
在 init 方法的末尾添加以下粗体行(以粗体显示),但是注意该代码包含一个“找不到类”错误。将在步骤 6 中添加 import 语句来修复此错误。在插入代码之后,可以按 Ctrl-Shift-F 组合键重新设置代码的格式。
| 代码样例 2:init 方法 |
public void init() { super.init(); // Perform application initialization that must complete // *before* managed components are initialized // TODO - add your own initialiation code here // Managed Component Initialization // Perform application initialization that must complete // *after* managed components are initialized // TODO - add your own initialization code here ServletContext theApplicationsServletContext = (ServletContext) this.getExternalContext().getContext(); this.realImageFilePath = theApplicationsServletContext.getRealPath(IMAGE_URL); }
|
此代码将 IMAGE_URL 转换为图像文件的实际路径,以便可以将该文件写入服务器上的正确目录。
-
滚动至 prerender 方法并添加以下代码:
| 代码样例 3:prerender 方法 |
public void prerender() { String uploadedFileName = (String) this.fileNameStaticText.getValue(); if ( uploadedFileName != null ) { image1.setUrl(IMAGE_URL); } }
|
如果存在要显示的图像文件,此代码会将该文件绑定到图像组件。
-
添加如下代码到 uploadFileButton_action() 方法中
| 代码样例4: 用于上传图像文件的代码 |
public String uploadFileButton_action() { UploadedFile uploadedFile = fileUpload1.getUploadedFile(); if( uploadedFile == null ) return null; String uploadedFileName = uploadedFile.getOriginalName(); // Some browsers return complete path name, some don't // Make sure we only have the file name // First, try forward slash int index = uploadedFileName.lastIndexOf('/'); String justFileName; if ( index >= 0) { justFileName = uploadedFileName.substring( index + 1 ); } else { // Try backslash index = uploadedFileName.lastIndexOf('\\'); if (index >= 0) { justFileName = uploadedFileName.substring( index + 1 ); } else { // No forward or back slashes justFileName = uploadedFileName; } } this.fileNameStaticText.setValue(justFileName); Long uploadedFileSize = new Long(uploadedFile.getSize()); this.fileSizeStaticText.setValue(uploadedFileSize); String uploadedFileType = uploadedFile.getContentType(); this.fileTypeStaticText.setValue(uploadedFileType); if ( uploadedFileType.equals("image/jpeg") || uploadedFileType.equals("image/pjpeg") || uploadedFileType.equals("image/gif") || uploadedFileType.equals("image/png") || uploadedFileType.equals("image/x-png")) { try { File file = new File(this.realImageFilePath); uploadedFile.write(file); } catch (Exception ex) { error("Cannot upload file: " + justFileName); } } else { error("You must upload a JPEG, PJPEG, GIF, PNG, or X-PNG file."); new File(this.realImageFilePath).delete(); } return null; }
|
对于每个文件,程序将从 UploadedFile 对象中提取文件名、大小和类型,并将它们绑定到静态文本组件。程序对所有上传的文件做出一个关键决策:如果文件是 JPEG、PJPEG、GIF、PNG 或 X-PNG 格式的文件,则程序将上传的文件保存到 realImageFilePath 变量。如果文件不是有效的图像文件,或者上传文件时出现其他问题,则程序会从服务器删除该图像并显示一条错误消息。
-
在 Java 编辑器中单击鼠标右键,然后选择“修复导入”。在“修复导入”对话框中,确保 java.io.File 显示在“文件”下拉列表中,然后单击“确定”。
此操作将修复代码中的错误。
测试应用程序
- 运行应用程序。
-
单击“浏览”在本地驱动器中导航,然后选择要上传的图像文件。然后单击 "Upload File" 按钮。
下图显示了上传 JPEG 文件后的应用程序。该图像存储在 project-directory\FileUploadExample\build\web\resources 中。

-
在文件上传组件中输入一个文本文件,然后单击 "Upload File" 按钮。验证是否显示错误消息。 就像下面的图片显示的那样.
注意:根据 Web 浏览器的不同,文件上传组件的呈现也会有所不同。请确保在用户要使用的 Web 浏览器中测试此组件。

执行更多操作 #1:上传文本文件
此节是一个介绍如何上传文本文件的迷你教程。在此示例中,使用一个文本区域组件显示文件的内容,并使用一个消息组组件显示文件的名称和大小。该示例不保存文件的内容。要保存文件的内容,您必须添加将文件保存到磁盘的代码,如上例所示。
- 创建一个启用 Visual Web JavaServer Faces 框架的新 Web 应用程序项目。
- 将一个文件上传组件拖放到页面上。
- 右键文件上传组件并选择 添加绑定属性。
- 添加一个按钮组件、一个文本区域组件和一个消息组组件。
- 右键按钮组件,并选择 添加绑定属性.
- 右键文本区域组件,并选择 添加绑定属性.
-
双击按钮组件,然后将以下操作代码添加到 button1_action() 方法:
- 按下Ctrl-Shift-I 快捷键 进行修复导入,就会自动的添加
UploadedFile 的导入语句。
| 代码样例 5: 用于上传文本文件的代码 |
public String button1_action() { UploadedFile uploadedFile = (UploadedFile) fileUpload1.getUploadedFile(); if( uploadedFile == null ) return null; info("Uploaded file originally named '" + uploadedFile.getOriginalName() + "' of size '" + uploadedFile.getSize() + "'"); textArea1.setText(uploadedFile.getAsString()); return null; }
|
-
运行应用程序。 下图显示了上传文本文件后的样例页。

注意: 在上传之前请确保 这个文件是一个简单的文本格式文件。否则这个格式的问文件将会被和文本文件一起显示。
执行更多操作 #2:修改最大文件上传大小
要允许上传超过 1 MB 的文件(如大的图像文件、ZIP、JAR 或可执行文件),必须在应用程序的 web.xml 文件中修改 UploadFilter 过滤器的 maxSize 参数。
- 打开“文件”窗口,然后展开 "<项目名称>" > "web" > "WEB-INF"。
- 右键单击 web-xml 节点,然后选择“打开”。
- 在 XML 编辑器中,单击“过滤器”按钮。
- 选择
UploadFilter 的 maxSize 参数,然后单击“编辑”按钮。
-
在对话框中,将“参数值”设置为所需的值,然后单击“确定”。
注意: 为安全起见,请不要将 maxSize 参数设置为负值,负值表示没有文件大小限制。
- 选择 文件 > 保存 以保存修改 然后关闭XML 编辑器.
注意:如果应用程序的用户试图上传大小超过 maxSize 参数值的文件,则会抛出以下异常,并将该异常作为验证错误捕获:
org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException
向用户显示的摘要消息为:
No file was uploaded
详细消息为:
No file was uploaded. The specified file exceeds the maximum allowable size of 1000000 Mb
其中 1000000 MB 是 maxSize 的值。
执行更多操作 #3:将上传的文件保存到其他位置
本教程介绍了如何将文件上传到 Web 应用程序的 /resources 文件夹。 如果希望将上传的文件保存到其他位置,应如何处理? 另一备选方法是将目录路径放入部署描述符中,以便您可以动态更改位置。
- 在文件窗口, 展开web结点 然后展开 WEB-INF。双击 web.xml 打开它.
- 单击“常规”按钮并展开“上下文参数”,然后单击“添加”按钮。
-
设置以下值,然后单击“确定”。
参数名称: uploadDirectory (或者任意名称)
参数值: C:/upload/images (或者其他路径)
- 关闭并保存
web.xml 文件。
-
使用以下代码:
| 代码样例 6: 用于将文件上传到目前未知目录的代码 |
String uploadDirectory = getExternalContext().getInitParameter ("uploadDirectory"); File file = new File(uploadDirectory + File.separatorChar + justFileName); uploadedFile.write(file);
|
已知问题
- 如果使用 Internet Explorer 7 运行文件上传教程,则第一次装入图像时会正常工作。第二次装入图像时将更新文件名、文件类型和文件大小,但是不更新图像。如果重新装入浏览器,图像将正确显示。
- 图像的文件名必须包含 ISO-8859-1 字符。
另请参见
本页的最新修改时间: 2008 年 11 月 26 日