我正在使用Primefaces在JSF中提供文件下载操作。我正在使用的代码是:
<p:commandButton id="xlsExport" value="Export XLS"
ajax="false"
onclick="PrimeFaces.monitorDownload(startPleaseWaitMonitor, stopPleaseWaitMonitor);">
<p:fileDownload value="#{SampleBean.XLSExport}" />
</p:commandButton>
SampleBean具有以下方法:
public StreamedContent getXLSExport() {
...
byte[] content = generator.generateXLS();
return new DefaultStreamedContent(new ByteArrayInputStream(content), "application/vnd.ms-excel", fileName, "UTF-8");
}
我在两个应用程序服务器-JBoss和Websphere上使用它。如果是Websphere,我在导出时会在服务器日志中看到警告:
000000f5 SRTServletRes W com.ibm.ws.webcontainer.srt.SRTServletResponse setStatus警告: 无法设置状态。响应已提交。
当我运行类似方法但是对于CSV导出时,没有警告。对于JBoss也没有警告。
发出此类日志警告的原因可能是什么?
答案 0 :(得分:1)
我已经在本地重新创建了该文件-看来PrimeFaces的FileDownloadActionListener
正在尝试在服务器已提交响应之后设置响应状态代码。 FileDownload代码获取响应输出流,将下载文件的全部内容写入其中,然后尝试更新响应状态代码。
当传递到响应缓冲区的数据量超过某个阈值(默认为32K)时,WebSphere会提交并刷新响应。一旦提交了响应,就无法更新其标头(例如,状态码)。其他应用程序服务器的行为可能与此相同-它们可能不会记录警告消息。在这种特殊情况下,无需担心警告,因为FileDownload代码只是尝试从200-> 200更新状态代码。
使用不同的内容类型(例如CSV
)在这里不会有所不同。文件大小确实有所不同-如果下载的文件小于响应缓冲区的大小,则在PrimeFaces代码尝试设置其状态之前,不会提交响应。
此警告消息的简单修复方法是在尝试更改其状态之前检查响应是否已提交。我为此打开了一个PrimeFaces问题:https://github.com/primefaces/primefaces/issues/3955
更新:我提供了对PrimeFaces的修复,因此您不应再在每晚的build / next版本中看到此问题。