如何使用 JSF 2.2 <h:inputFile> 上传文件?保存的文件在哪里?
Posted
技术标签:
【中文标题】如何使用 JSF 2.2 <h:inputFile> 上传文件?保存的文件在哪里?【英文标题】:How to upload file using JSF 2.2 <h:inputFile>? Where is the saved File? 【发布时间】:2015-02-24 23:05:33 【问题描述】:我希望能够在我的 JSF2.2 Web 应用程序中上传文件,因此我开始使用新的 <h:inputFile>
组件。
我唯一的问题是,如何指定位置,将文件保存在服务器中的哪个位置?我想将它们作为java.io.File
实例来获取。这必须在 backing bean 中实现,但我不清楚如何实现。
【问题讨论】:
将 h:inputFile 的值绑定到 bean 中的 Part 属性。然后,您的操作方法可以使用part.write(fileName)
将数据保存在您喜欢的任何位置。
【参考方案1】:
JSF 不会将文件保存在任何预定义的位置。它基本上只会以javax.servlet.http.Part
实例的形式为您提供上传的文件,该实例在幕后临时存储在服务器内存和/或临时磁盘存储位置中,您不必担心。
重要的是,在调用 bean 操作(侦听器)方法时,您需要尽快阅读Part
。当与HTTP请求关联的HTTP响应完成时,临时存储可能会被清除。换句话说,上传的文件不一定在后续请求中可用。
所以,给定一个
<h:form enctype="multipart/form-data">
<h:inputFile value="#bean.uploadedFile">
<f:ajax listener="#bean.upload" />
</h:inputFile>
</h:form>
你基本上有两个选择来保存它:
1。将所有原始文件内容读入byte[]
您可以为此使用InputStream#readAllBytes()
。
private Part uploadedFile; // +getter+setter
private String fileName;
private byte[] fileContents;
public void upload()
fileName = Paths.get(uploadedFile.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
try (InputStream input = uploadedFile.getInputStream())
fileContents = input.readAllBytes();
catch (IOException e)
// Show faces message?
注意Path#getFileName()
。这是关于获取提交的文件名的 MSIE 修复。此浏览器错误地沿名称发送完整的文件路径,而不仅仅是文件名。
如果您还没有使用 Java 9,因此无法使用 InputStream#readAllBytes()
,那么请前往 Convert InputStream to byte array in Java 了解将 InputStream
转换为 byte[]
的所有其他方法。
请记住,上传文件的每个字节都会占用一个字节的服务器内存。请注意,当用户经常这样做或很容易以这种方式滥用您的系统时,您的服务器不会耗尽内存。如果您想避免这种情况,最好使用本地磁盘文件系统上的(临时)文件。
2。或者,将其写入本地磁盘文件系统
为了将其保存到所需的位置,您需要通过Part#getInputStream()
获取内容,然后将copy 获取到代表该位置的Path
。您可以按照通常的方式在(ajax)操作(侦听器)方法中执行此操作。这是一个在 html DOM change
事件期间使用 ajax 侦听器执行此操作的示例:
private Part uploadedFile; // +getter+setter
private File savedFile;
public void upload()
String fileName = Paths.get(uploadedFile.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
savedFile = new File(uploads, fileName);
try (InputStream input = file.getInputStream())
Files.copy(input, savedFile.toPath());
catch (IOException e)
// Show faces message?
注意Path#getFileName()
。这是关于获取提交的文件名的 MSIE 修复。此浏览器错误地沿名称发送完整的文件路径,而不仅仅是文件名。
uploads
文件夹和filename
完全由您控制。例如。 "/path/to/uploads"
和 Part#getSubmittedFileName()
分别。请记住,任何现有文件都将被覆盖,您可能需要使用 File#createTempFile()
自动生成文件名。
不要不要使用Part#write()
,就像某些人可能建议的那样。它基本上会重命名由@MultipartConfig(location)
标识的临时存储位置中的文件。另外不使用ExternalContext#getRealPath()
将上传的文件保存在部署文件夹中。重新部署 WAR 时该文件将丢失,原因很简单,即该文件未包含在原始 WAR 中。始终将其保存在部署文件夹之外的绝对路径上。
如需上传预览功能的现场演示,请查看<o:graphicImage>
demo on OmniFaces showcase的最后一项。
另见:
Write file into disk using JSF 2.2 inputFile How to save uploaded file in JSF Recommended way to save uploaded files in a servlet application【讨论】:
这里的 f:ajax 示例中的事件是什么?点击? 只是默认的。答案是原样。 是的,我的意思是默认值是什么?以上是关于如何使用 JSF 2.2 <h:inputFile> 上传文件?保存的文件在哪里?的主要内容,如果未能解决你的问题,请参考以下文章
<t:inputFileUpload> 将 JSF 1.2 迁移到 JSF 2.2 后不再工作