在JSF中提供文件下载,如download.JSF?id=123

在JSF中提供文件下载,如download.JSF?id=123,jsf,Jsf,我正在尝试以 http://www.domain.example/download.jsf?id=123 到目前为止,我的解决方案如下:(从这里复制:) GetFile.java @ManagedBean @ViewScoped public class GetFile{ // property and getter public void setId(String id) { FacesContext fc = FacesContext.getCurrentInstance()

我正在尝试以

http://www.domain.example/download.jsf?id=123
到目前为止,我的解决方案如下:(从这里复制:)

GetFile.java

@ManagedBean
@ViewScoped
public class GetFile{

// property and getter

public void setId(String id) {

    FacesContext fc = FacesContext.getCurrentInstance();
    ExternalContext ec = fc.getExternalContext();

    ec.responseReset();
    ec.setResponseContentType(contentType); 
    ec.setResponseContentLength(contentLength);
    ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

    try (OutputStream output = ec.getResponseOutputStream()) {
        // Now you can write the InputStream of the file to the above
        // OutputStream the usual way.
        // ...

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    fc.responseComplete(); 
}
@ManagedBean
@ViewScoped
public class GetFile {

    // properties, getter and setter

    public void download() {
        // your download code goes here
    }
}
我的下载.xhtml如下所示:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core">

    <f:metadata>
        <f:viewParam name="id" value="#{getFile.id}" />
    </f:metadata>

</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core">

    <f:metadata>
        <f:viewParam name="id" value="#{getFile.id}" />
        <!-- your other parameters come here -->
    </f:metadata>
    #{getFile.download()}
</html>

那么,我必须考虑设置参数的顺序,并在最后一个设置器中执行。这会奏效,但我觉得这不是一个很好的解决方案,所以我的问题是,有没有更好的方法来实现这一点


任何提示都非常感谢

在setter中启动下载通常不是一个很好的设计,应该只做它的主要目的,设置变量(可能还有一些与设置相关的检查/转换等)

要开始下载,您应该在支持bean中创建一个新方法来处理下载并使用该方法。因此,您的bean应该如下所示:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core">

    <f:metadata>
        <f:viewParam name="id" value="#{getFile.id}" />
    </f:metadata>

</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core">

    <f:metadata>
        <f:viewParam name="id" value="#{getFile.id}" />
        <!-- your other parameters come here -->
    </f:metadata>
    #{getFile.download()}
</html>
GetFile.java

@ManagedBean
@ViewScoped
public class GetFile{

// property and getter

public void setId(String id) {

    FacesContext fc = FacesContext.getCurrentInstance();
    ExternalContext ec = fc.getExternalContext();

    ec.responseReset();
    ec.setResponseContentType(contentType); 
    ec.setResponseContentLength(contentLength);
    ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

    try (OutputStream output = ec.getResponseOutputStream()) {
        // Now you can write the InputStream of the file to the above
        // OutputStream the usual way.
        // ...

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    fc.responseComplete(); 
}
@ManagedBean
@ViewScoped
public class GetFile {

    // properties, getter and setter

    public void download() {
        // your download code goes here
    }
}
通过这种方式,您可以使用任意数量的参数,并按您的方式传递它们。在您的下载.xhtml中,您可以在传递如下参数后调用bean方法:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core">

    <f:metadata>
        <f:viewParam name="id" value="#{getFile.id}" />
    </f:metadata>

</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core">

    <f:metadata>
        <f:viewParam name="id" value="#{getFile.id}" />
        <!-- your other parameters come here -->
    </f:metadata>
    #{getFile.download()}
</html>

#{getFile.download()}