有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Primefaces文件下载仅在使用默认构造函数时有效

我使用HttpURLConnection下载一个文件,然后我想让用户选择下载该文件。我使用这个例子http://www.primefaces.org/showcase/ui/file/download.xhtml

我的问题是,如果我通过默认构造函数下载硬编码文件(如示例中所述),一切都正常。但是,如果我将文件名传递给接受param的构造函数,就会得到一个空指针

下面是包含两个构造函数的代码(只有包含硬编码文件的默认构造函数有效)

@ManagedBean

public class FileDownloadView {

    private StreamedContent file;
    private InputStream stream;
    private String fileName;

    public String getFileName() {
        return fileName;
    }


    public FileDownloadView() {
        InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/tmp/1kb.txt");
        file = new DefaultStreamedContent(stream, "text/plain", "text.txt");
        System.out.println("fileName......." + "test.txt");

    }

    public  FileDownloadView(String fileName) {
        this.fileName = fileName;

        InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/tmp/" + fileName);
        this.fileName = fileName;
        file = new DefaultStreamedContent(stream, "text/plain", fileName);
        System.out.println("fileName......." + file.getName());

    }

    public StreamedContent getFile() {
        System.out.println("file  "+file.getName());

        return file;
    }
}

这是我如何提取文件的

     <p:commandButton value="Download" ajax="false" onclick="PrimeFaces.monitorDownload(start, stop);" icon="ui-icon-arrowthick-1-s">
                <p:fileDownload value="#{fileDownloadView.file}" />
            </p:commandButton>

            <p:outputLabel value="#{fileDownloadView.fileName}"/>
        </h:form>
        <script type="text/javascript">
                                       function start() {
                                           PF('statusDialog').show();
                                       }

                                       function stop() {
                                           PF('statusDialog').hide();
                                       }
        </script>

共 (3) 个答案

  1. # 1 楼答案

    你可以试试这个

    @ManagedBean
    public class FileDownloadView {
    
    private StreamedContent file;
    private InputStream stream;
    private String fileName = "error";
    
    public String getFileName() {
        return fileName;
    }
    public void setFileName(String _filename) {
        this.fileName = _fileName;
    }
    public FileDownloadView() {
    
    }
    

    prepareToDownload方法允许管理文件下载。通过这种方式,我们可以恢复文件名

    public void prepareToDownload(ActionEvent actionEvent){
        setFileName((String)actionEvent.getComponent().getAttributes().get("fileName"));
        InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/tmp/" + fileName);
        setFile( new DefaultStreamedContent(stream, "text/plain", fileName));
    }
    public StreamedContent getFile() {
        System.out.println("file  "+file.getName());
    
        return file;
    }
    public void setFile(StreamedContent _file) {
        this.file  = _file;
    
    }
    }
    }
    

    然后在xhtml文件中:

    <h:commandLink id="downloadLink"
    title="Download"
    actionListener="#{fileDownloadView.prepareToDownload}">
    <p:graphicImage value="/resources/common/images/download.gif"
        alt="Download" />
        <f:attribute name="fileName" value="#{fileDownloadView.fileName}" />
        <p:fileDownload value="#{fileDownloadView.file}" />
    </h:commandLink>
    <h:outputText value="#{fileDownloadView.fileName}"/> 
    
  2. # 2 楼答案

    您可以使用f:attribute将文件名从UI传递到控制器,并调用下载

    根据标签的定义,它提供了一个选项,可以通过动作监听器将属性值传递给组件,或将参数传递给组件

    因此,在您的情况下,您希望将文件名传递给控制器,并相应地下载文件

        <p:commandButton value="Download" ajax="true" actionListener="#{fileDownloadView.prepareToDownload}" icon="ui-icon-arrowthick-1-s">
                    <p:fileDownload value="#{fileDownloadView.file}" />
                    <f:attribute name="fileName" value="#{fileDownloadView.fileName}" />
       </p:commandButton>
    

    或者

    <h:commandLink id="downloadLink"
        title="Download"
        actionListener="#{fileDownloadView.prepareToDownload}">
        <p:graphicImage value="/resources/common/images/download.gif"
            alt="Download" />
            <f:attribute name="fileName" value="#{fileDownloadView.fileName}" />
            <p:fileDownload value="#{fileDownloadView.file}" />
    </h:commandLink>
    

    在控制器中编写actionEvent并管理下载

    public void prepareToDownload(ActionEvent actionEvent){
            String fileName = (String)actionEvent.getComponent().getAttributes().get("fileName");
            InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/tmp/" + fileName);
            file = new DefaultStreamedContent(stream, "text/plain", fileName);
        }
    
  3. # 3 楼答案

    不能在带有注释@ManagedBean的类中创建第二个构造函数来初始化filename变量