我希望能在我的JSF2.2 Web应用程序中上传文件,因此我开始使用新的<h:inputFile>
组件。
我唯一的问题是如何指定保存文件的位置在服务器上的位置?我想把它们作为java.io.File
实例获取。这必须在后端bean中实现,但我不太清楚该如何操作。
我希望能在我的JSF2.2 Web应用程序中上传文件,因此我开始使用新的<h:inputFile>
组件。
我唯一的问题是如何指定保存文件的位置在服务器上的位置?我想把它们作为java.io.File
实例获取。这必须在后端bean中实现,但我不太清楚该如何操作。
javax.servlet.http.Part
实例的形式向您提供上传的文件,该实例在服务器的内存和/或临时磁盘存储位置中被临时存储,您不必担心这些。Part
。当与HTTP请求关联的HTTP响应完成时,临时存储可能会被清除。换句话说,在随后的请求中,上传的文件不一定可用。<h:form enctype="multipart/form-data">
<h:inputFile value="#{bean.uploadedFile}">
<f:ajax listener="#{bean.upload}" />
</h:inputFile>
</h:form>
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[]
的其他方法。
请记住,上传文件的每个字节都会消耗一字节的服务器内存。当用户经常这样做或可以轻松滥用您的系统时,请小心您的服务器不要耗尽内存。如果想避免这种情况,最好使用本地磁盘文件系统上的(临时)文件。
Part#getInputStream()
获取内容,然后将其copy到代表位置的Path
中。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()
来自动生成文件名。您可以在this answer中找到一个详细的例子。Part#write()
,因为一些人可能会建议这样做。它基本上会将文件重命名为由@MultipartConfig(location)
标识的临时存储位置中的文件。也不要使用ExternalContext#getRealPath()
将上传的文件保存在部署文件夹中。当WAR重新部署时,文件将会丢失,因为该文件并未包含在原始WAR中。请始终将其保存在部署文件夹之外的绝对路径上,以确保文件不会丢失。<o:inputFile>
页面的演示部分。
part.write(fileName)
将数据保存在任何您喜欢的地方。 - VGR