9

我目前正在研究使用 Java Server Faces 上传一些文件。我使用 RichFaces找到了这个很棒的介绍。但是,我在理解这里的过程时遇到了一些麻烦。

首先,用户选择一个文件,如果立即上传设置为 true,则使用 ajax 处理文件,到目前为止一切顺利。然而,当谈到下一步时,Bean 端的侦听器让我感到困惑:

public void listener(UploadEvent event) throws Exception{
    UploadItem item = event.getUploadItem();

    File f = item.getFile();

    System.out.println(f.getAbsolutePath());
}

绝对路径是指向我计算机上的临时目录,当然我明白这一点,但是您如何使该文件对 webbapplication 可用?我的应用程序部署为 WAR 文件。是否可以将其上传到WAR?可能听起来很愚蠢,但实际上可能很方便。

我完全知道我可以重命名文件以将其复制到新位置,但这是要走的路吗?

4

2 回答 2

6

不确定这有多大帮助(可能为时已晚!),但这是我在服务器端使用的代码,相当于你的听众。

public String uploadFile(UploadEvent event) {
    UploadItem item = event.getUploadItem();

    String name = "unnamed_attachment";
    byte[] data = item.getData();

    try {
        name = FilenameUtils.getName(item.getFileName());
        data = FileUtils.readFileToByteArray(item.getFile());
        logger.info("data.length = " + data.length);
        UploadDetails details = new UploadDetails(); // This is a javabean that gets persisted to database (actually a ejb3 entity bean, but thats irrelevant)

        details.setBytes(data);
        details.setResume(true);
        // Save to database here 

    } catch (Exception e) {
        FaceletsUtil.addSystemErrorMessage();
        logger.error(e, e);
    }
    return null;
}

剩下的大问题是您说“您如何使该文件对 webbapplication 可用?”。字节数组立即可用。如果要重新下载该文件,可以将其作为 JSF 会话/视图 bean 中方法的链接提供,例如:

<h:commandButton action="#{Manager.downloadFile}" value="Download report">                                </h:commandButton>

public void downloadFile() {
    final HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();

    response.setHeader("Content-Disposition", "attachment;filename=radar-report" + new Date() + ".pdf"); // or whatever type you're sending back
    try {
        response.getOutputStream().write(uploadDetails.getBytes()); // from the UploadDetails bean
        response.setContentLength(uploadDetails.getBytes().length);
        response.getOutputStream().flush();
        response.getOutputStream().close();
    } catch (IOException e) {
        logger.error(e, e);  
    }
    FacesContext.getCurrentInstance().responseComplete();
}
于 2010-07-18T21:13:03.997 回答
5

将内容写入您的 WAR 目录(假设 WAR 甚至被分解为一个目录)通常是一个坏主意(出于同样的原因,将数据存储在应用程序目录中通常是一个坏主意)。

您可能希望它最终存储在持久性存储中,通常是数据库。究竟如何管理这取决于您 - 您是使用文件系统并将引用存储在数据库中还是直接将 BLOB 存储在数据库中,以及您是否使用 JDBC、JPA 或 Hibernate 等。

然后可以通过使用类似<a4j:support event="onuploadcomplete" reRender="info" />.

文件下载 servlet(如果 RichFaces 没有的话)相当容易编写。

于 2009-10-22T10:00:05.887 回答