本文列举了在JSF应用中实现文件下载的几种不同方法。
方法 1- 使用Servlet
这种方法使用一个servlet来实现文件下载, 在JSF页面上则使用commandLink或outputLink来实现指向该servlet的链接。 具体示例可以参见这里. 该方法的优点在于易于实现,而不足之处在于由于servlet处于JSF生命周期之外, 如果servlet的文件处理过程需要访问JSF context或backing beans时, 则需要额外的代码来连接这两者。
方法 2- 使用JSF PhaseListener
这种方法使用JSF PhaseListener来提供文件下载, 具体实现可以参见Mojarra Scales组件库。 示例代码如下。
<sc:download id="downloadPdf" method="download" mimeType="application/pdf" fileName="sample.pdf" data="#{testBean.pdf}" text="Download here"> </sc:download>
以上代码中的<sc:download>组件在页面上实现了一个特殊格式的http链接,当用户点击该连接链接时, 相应的PhaseListener会被触发, 并在其RESTORE_VIEW阶段的beforePhase方法中提供文件下载。
通过使用JSF PhaseListener, 文件下载过程现在成为了JSF生命周期的一部分,然而, 该方法的缺陷在于下载数据内容(以上例而言, #{testBean.pdf})的填充是在页面构造时, 而不是在用户点击下载连接时。
方法 3- 使用JSF Action/ActionListener
这种方法通过对JSFcommandLink或commandButton组件实现Action/ActionListener来提供文件下载。 基于Action的实现方法可以参见这里, 基于ActionListener的实现方法可以参见PrimeFaces的FileDownload组件。
以个人观点而言, 方法3是最佳的一种解决方法。