对于使用jsf 2实现下载按钮时遇到问题,这是一个独特而奇怪的案例。
所以我定义了一个这样的按钮:
<h:form id="downloadForm">
<h:commandButton value="Download" action="#{viewStatus.download()}" />
</h:form>
在我的支持bean中,函数如下所示:
public void download()
{
String filePath = "opt/myapplication/reports/myfile.csv";
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
try
{
File file = new File(filePath);
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.responseReset();
ec.setResponseContentType("application/x-download");
Long fileLength = file.length();
ec.setResponseContentLength(fileLength.intValue());
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
OutputStream output = ec.getResponseOutputStream();
PrintWriter printWriter = new PrintWriter(output, true);
Scanner input = new Scanner(file);
while(input.hasNextLine())
{
String line = input.nextLine();
printWriter.write(line);
}
input.close();
output.close();
printWriter.close();
fc.responseComplete();
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
正如您所看到的,我没有在按钮中使用ajax,而是使用函数responseComplete()来结束响应。
在我的页面中,当我单击下载按钮时,不会抛出任何错误,但是光标会继续循环,表示某些进程正在后台运行。它就像一个无限循环正在进行中。
在我的头撞了一千次后,当我在一个新项目中运行相同的命令时,一切正常。 所以我知道代码是正确的。
现在让我向您展示我的JSF生命周期日志:
AFTER PHASE: RESTORE_VIEW 1
BEFORE PHASE: APPLY_REQUEST_VALUES 2
AFTER PHASE: APPLY_REQUEST_VALUES 2
BEFORE PHASE: PROCESS_VALIDATIONS 3
AFTER PHASE: PROCESS_VALIDATIONS 3
BEFORE PHASE: UPDATE_MODEL_VALUES 4
AFTER PHASE: UPDATE_MODEL_VALUES 4
BEFORE PHASE: INVOKE_APPLICATION 5
AFTER PHASE: INVOKE_APPLICATION 5
如您所见,第六阶段 - &#34;前阶段:RENDER_RESPONSE 6&#34; 和&#34;阶段后:RENDER_RESPONSE 6&#34; 永远不会出现。因此我看到光标旋转的东西,因为我的浏览器试图渲染视图,但有些东西阻挡了它,因此无限循环。
So I gues my question is that does anyone know of a reason why the 6th step is not rendering and based on the given environment, can you guess what might be wrong here ?
我已经看到并尝试了谷歌中与此事有关的所有结果,但没有任何效果。我不确定我做错了什么。此外,如果除了JSF之外还有其他方法可以下载文件,我也很乐意尝试。
提前致谢。 :)
我的环境是: