如何在JSF中保存上传的文件

时间:2013-01-08 09:27:54

标签: jsf file-upload save

我在JSF上传文件。我正在使用Tomahawk的<t:inputFileUpload>,但同样的问题适用于例如PrimeFaces <p:fileUpload>和JSF 2.2 <h:inputFile>

我有以下支持bean代码:

private UploadedFile uploadedFile; // +getter+setter

public String save() throws IOException {
    String name = uploadedFile.getName();
    System.out.println("File name: " + name);

    String type = uploadedFile.getContentType();
    System.out.println("File type: " + type);

    long size = uploadedFile.getSize();
    System.out.println("File size: " + size);  

    InputStream stream = uploadedFile.getInputStream();
    byte[] buffer = new byte[(int) size];  
    stream.read(buffer, 0, (int) size);  
    stream.close();  
}

我能够获取文件名,类型和大小,但我无法将此文件保存在特定路径中。我无法找出保存上传文件的正确方法。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:53)

上传文件的getInputStream()方法表示文件内容。

InputStream input = uploadedFile.getInputStream();

您需要将其复制到文件中。您应首先在本地磁盘文件系统上准备一个文件夹,以便存储上载的文件。例如,/path/to/uploads(在Windows上,与服务器运行的磁盘位于同一磁盘上)。请注意,您应该绝对不使用相对路径将文件存储在展开的WAR文件夹中,或getRealPath()出于此处提到的原因Uploaded image only available after refreshing the page

然后,您需要自动生成文件名。否则,当其他人稍后上传具有相同名称的文件时,它将被覆盖。您可以使用Files#createTempFile()工具来获取自动生成的文件名。

Path folder = Paths.get("/path/to/uploads");
String filename = FilenameUtils.getBaseName(uploadedFile.getName()); 
String extension = FilenameUtils.getExtension(uploadedFile.getName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);

如果有必要,可以根据此问答中显示的几种方式之一参数化上传路径:Recommended way to save uploaded files in a servlet applicationFilenameUtils是Apache Commons IO的一部分,您应该已经在类路径中拥有它,因为它是Tomahawk文件上传组件的依赖项。

最后,只需将上传的文件流式传输到该文件(假设是Java 7):

try (InputStream input = uploadedFile.getInputStream()) {
    Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}

System.out.println("Uploaded file successfully saved in " + file);

然后,要将其下载回来,最简单的方法是将/path/to/uploads注册为新的webapp上下文或虚拟主机,以便所有这些文件都可通过URL获得。另请参阅Load images from outside of webapps / webcontext / deploy folder using <h:graphicImage> or <img> tag

答案 1 :(得分:1)

PrimeFaces使用两个文件上传解码器上传p:fileupload

的内容
  1. NativeFileUploadDecoder
  2. CommonsFileUploadDecoder
  3. NativeFileUploadDecoder是默认的上传解码器,它需要servlet容器3.0。因此,如果您的servlet容器小于3,那么它将无法与您一起使用。 此外,一些应用程序服务器限制使用多部分内容

    因此,如果您因任何原因遇到本机上传解码器问题,则必须使用另一个解码器“CommonsFileUploadDecoder”

    CommonsFileUploadDecoder依赖于Apache common lib 所以你必须把 commons-fileupload和commons-io jars 放在你的类路径中 版本取决于你的primefaces版本,但1.3和2.2分别适用于我。

    使用CommonsFileUploadDecoder你必须使用过滤器

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

    等待过滤器不起作用因为在过滤器内部检查上传器是否未提供,并且至少检测到JSF 2.2,因此它将绕过请求到默认解码器“Native”然后它也不适用于你的

    强制过滤器使用您必须在web.xml中放置以下上下文参数的公共解码器

    <context-param>
    <param-name>primefaces.UPLOADER</param-name>
       <param-value>commons</param-value>
    </context-param>
    
相关问题