如何使用p:fileDownload使用流内容下载非类路径文件

Kis*_*ash 9 jsf primefaces

我正在使用Primefaces

电话号码:fileDownload

下载不在类路径中的文件.
所以我将FileInputStream作为参数传递给DefaultStreamedContent.
当我的bean保存在@SessionScoped时,每件事都可以正常工作......,
但是

java.io.NotSerializableException:java.io.FileInputStream

当我将bean保存在@Viewscoped中时抛出.

我的代码:

DownloadBean.java

@ManagedBean
@ViewScoped
public class DownloadBean implements Serializable {

    private StreamedContent dFile;

    public StreamedContent getdFile() {
        return dFile;
    }

    public void setdFile(StreamedContent dFile) {
        this.dFile = dFile;
    }

    /**
     * This Method will be called when download link is clicked
     */
    public void downloadAction()
    {
        File tempFile = new File("C:/temp.txt");
        try {
            dFile = new DefaultStreamedContent(new FileInputStream(tempFile), new MimetypesFileTypeMap().getContentType(tempFile));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

的index.xhtml

<h:form>
    <h:commandLink action="#{downloadBean.downloadAction}">
        Download
        <p:fileDownload value="#{downloadBean.dFile}"/>
    </h:commandLink>
</h:form>
Run Code Online (Sandbox Code Playgroud)

没有任何方法可以使它工作吗?

Bal*_*usC 13

NotSerializableException被抛出,因为该视图的范围由这又可以在客户端状态保存的情况下被串行化,以HTTP会话在服务器端状态保存或HTML隐藏的输入字段的情况下,JSF视图状态表示.在FileInputStream不以任何方式可以以序列化形式来表示.

如果您绝对需要保持bean视图范围,那么您不应该声明StreamedContent为实例变量,而是在getter方法中重新创建它.确实,在getter方法中执行业务逻辑通常是不受欢迎的,但这StreamedContent是一个相当特殊的情况.在action方法中,您应该只准备可序列化的变量,这些变量稍后将在DefaultStreamedContent构造期间使用.

@ManagedBean
@ViewScoped
public class DownloadBean implements Serializable {

    private String path;
    private String contentType;

    public void downloadAction() {
        path = "C:/temp.txt";
        contentType = FacesContext.getCurrentInstance().getExternalContext().getMimeType(path);
    }

    public StreamedContent getdFile() throws IOException {
        return new DefaultStreamedContent(new FileInputStream(path), contentType);
    }

}
Run Code Online (Sandbox Code Playgroud)

(请注意,我还修改了获取内容类型的方法;您可以通过<mime-mapping>条目更自由地配置mime类型web.xml)

<p:graphicImage>具有的方式完全一样的问题StreamedContent.另请参见使用p:graphicImage和StreamedContent从数据库显示动态图像.