che*_*ffe 6 jsf message download jsf-2
我们正在按照SO问题中详细说明的程序如何从JSF支持bean提供文件下载,将二进制文件流式传输给我们的用户?
通常,工作流程按预期工作,但在生成导出文件期间,可能会发生可恢复的错误,我们希望将这些错误显示给用户.在这种情况下,仍然会生成文件本身.所以我们希望继续导出并显示面部消息.
只是强调这一点:是的,数据有些不合适,但我们的用户希望导出继续并接收有缺陷的文件.然后他们想查看该文件,联系他们的供应商并向他发送有关该漏洞的消息.
所以无论如何我都需要导出才能完成.
但它并没有像我们想要的那样成功.我创建了一个简化的例子来说明我们的方法.
作为替代方案,我们正在考虑一个Bean,它将保存消息并在导出后显示它们.但是可能有一种方法可以使用JSF内置机制来实现这一目标.
调节器
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import org.apache.tomcat.util.http.fileupload.util.Streams;
@ManagedBean
@RequestScoped
public class ExportController {
public void export() {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
byte[] exportContent = "Hy Buddys, thanks for the help!".getBytes();
// here something bad happens that the user should know about
// but this message does not go out to the user
fc.addMessage(null, new FacesMessage("record 2 was flawed"));
ec.responseReset();
ec.setResponseContentType("text/plain");
ec.setResponseContentLength(exportContent.length);
String attachmentName = "attachment; filename=\"export.txt\"";
ec.setResponseHeader("Content-Disposition", attachmentName);
try {
OutputStream output = ec.getResponseOutputStream();
Streams.copy(new ByteArrayInputStream(exportContent), output, false);
} catch (IOException ex) {
ex.printStackTrace();
}
fc.responseComplete();
}
}
Run Code Online (Sandbox Code Playgroud)
JSF页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:body>
<h:form prependId="false">
<h:messages id="messages" />
<h:commandButton id="download" value="Download"
actionListener="#{exportController.export()}" />
</h:form>
</h:body>
</f:view>
</html>
Run Code Online (Sandbox Code Playgroud)
由于您实际上是在执行文件下载响应而不是JSF,因此在同一请求发生时不可能添加您的消息.对我来说最干净的解决方案是避免hacky异步请求是使用@ViewScopedbean并分两步完成任务.因此,要有一个准备文件的按钮,稍后通知用户并允许他在准备好时下载它:
@ManagedBean
@ViewScoped
public class ExportController implements Serializable {
private byte[] exportContent;
public boolean isReady() {
return exportContent != null;
}
public void export() {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.responseReset();
ec.setResponseContentType("text/plain");
ec.setResponseContentLength(exportContent.length);
String attachmentName = "attachment; filename=\"export.txt\"";
ec.setResponseHeader("Content-Disposition", attachmentName);
try {
OutputStream output = ec.getResponseOutputStream();
Streams.copy(new ByteArrayInputStream(exportContent), output, false);
} catch (IOException ex) {
ex.printStackTrace();
}
fc.responseComplete();
}
public void prepareFile() {
exportContent = "Hy Buddys, thanks for the help!".getBytes();
// here something bad happens that the user should know about
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("record 2 was flawed"));
}
}
Run Code Online (Sandbox Code Playgroud)
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:body>
<h:form>
<h:messages id="messages" />
<h:commandButton value="Prepare"
action="#{exportController.prepareFile}" />
<h:commandButton id="download" value="Download"
disabled="#{not exportController.ready}"
action="#{exportController.export()}" />
</h:form>
</h:body>
</f:view>
</html>
Run Code Online (Sandbox Code Playgroud)
请注意,此解决方案可能对小文件有效(当用户保持在同一视图中时,它们的整个内容都存储在内存中).但是,如果您要将其用于大文件(或大量用户),最好将其内容存储在临时文件中,并显示指向它的链接而不是下载按钮.这就是@BalusC在下面的参考文献中提出的建议.
也可以看看:
| 归档时间: |
|
| 查看次数: |
15944 次 |
| 最近记录: |