我想为报告导出页面构建结果页面。此结果页面必须显示导出状态并提供此导出的下载。
导出是在动作方法中完成的。我可以通过commandButton
执行它,但必须在加载时自动执行。
我该如何做到这一点?
JSF:
<h:commandButton value="Download report" action="#{resultsView.downloadReport}"/>
支持bean:
public String downloadReport() {
...
FileDownloadUtil.downloadContent(tmpReport, REPORT_FILENAME);
// Stay on this page
return null;
}
澄清:a4j这可行吗?我想到了一个解决方案,即Ajax请求触发了我的downloadReport
操作,其请求是文件下载。
答案 0 :(得分:15)
您也可以使用组件系统事件(特别是PreRenderViewEvent)在JSF 2.0中解决此问题。
只需创建一个下载视图(/download.xhtml),在渲染之前触发下载侦听器。
<?xml version="1.0" encoding="UTF-8"?>
<f:view
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core">
<f:event type="preRenderView" listener="#{reportBean.download}"/>
</f:view>
然后,在您的报告bean(使用JSR-299定义)中,您推送文件并将响应标记为完成。
public @Named @RequestScoped class ReportBean {
public void download() throws Exception {
FacesContext ctx = FacesContext.getCurrentInstance();
pushFile(
ctx.getExternalContext(),
"/path/to/a/pdf/file.pdf",
"file.pdf"
);
ctx.responseComplete();
}
private void pushFile(ExternalContext extCtx,
String fileName, String displayName) throws IOException {
File f = new File(fileName);
int length = 0;
OutputStream os = extCtx.getResponseOutputStream();
String mimetype = extCtx.getMimeType(fileName);
extCtx.setResponseContentType(
(mimetype != null) ? mimetype : "application/octet-stream");
extCtx.setResponseContentLength((int) f.length());
extCtx.setResponseHeader("Content-Disposition",
"attachment; filename=\"" + displayName + "\"");
// Stream to the requester.
byte[] bbuf = new byte[1024];
DataInputStream in = new DataInputStream(new FileInputStream(f));
while ((in != null) && ((length = in.read(bbuf)) != -1)) {
os.write(bbuf, 0, length);
}
in.close();
}
}
这就是它的全部!
您可以链接到下载页面(/download.jsf),也可以使用HTML元标记在启动页面上重定向到它。
答案 1 :(得分:7)
上一个答案将提交表单,也许会更改导航。
使用<rich:jsFunction action="#{bean.action}" name="loadFunction" />
然后是window.onload = loadFunction;
答案 2 :(得分:2)
每个请求只能发送一个响应。您不能根据请求发送两个响应(页面本身和下载文件)。最好的办法是在页面加载后使用Javascript提交(隐藏)表单。
window.onload = function() {
document.formname.submit();
}
答案 3 :(得分:0)
使用活动
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
>
<f:event type="preRenderView" listener="#{beanName.method}"/>
...
</ui:composition>