gpt4 book ai didi

java - JSF 2.0 使用 Flying Saucer 将 XHTML 页面转换为 PDF : java. lang.IllegalStateException

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:21:19 25 4
gpt4 key购买 nike

我正在尝试将 JSF 页面转换并导出为 PDF。我尝试了以下方式:

bean 类:

public void createPDF() {
try {
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(new URL(url).toString());
renderer.layout();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
response.reset();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=\"" +PDF_FILE_NAME+ "\"");
OutputStream browserStream = response.getOutputStream();
renderer.createPDF(browserStream);
} catch (Exception ex) {
Logger.getLogger(PdfBean.class.getName()).log(Level.SEVERE, null, ex);
}
}

带有创建 PDF 按钮 /home.xhtml 的页面:

<ui:define name="content">
<center>
<h:form id="pdfgen">
<h:panelGrid columns="2">
<h:outputText value="Enter Name:"/>
<h:inputText value="#{pdfBean.name}"/>
</h:panelGrid>
<h:commandButton value="Create PDF" action="#{pdfBean.createPDF()}"/>
</h:form>
</center>
</ui:define>

我要转换的页面:

<ui:define name="content">
<center>
<h:outputText value="Hello #{pdfBean.name}"/>
</center>
</ui:define>

当我尝试这样做时,我只获得了一次 PDF,然后就再也没有了。我得到以下 Facelet 异常:

SEVERE: Error Rendering View[/home.xhtml]
java.lang.IllegalStateException: PWC3991: getOutputStream() has already been called for this response
...
WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException: PWC3991: getOutputStream() has already been called for this response

我做错了什么?

更新的 Bean: 参见 BalusC 的回答:

public void createPDF() {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String servername = externalContext.getRequestServerName();
String port = String.valueOf(externalContext.getRequestServerPort());
String appname = externalContext.getRequestContextPath();
String protocol = externalContext.getRequestScheme();
this.url = protocol + "://" + servername + ":" + port + appname + PDF_PAGE;
try {
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(new URL(url).toString());
renderer.layout();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
response.reset();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=\"" + PDF_FILE_NAME + "\"");
OutputStream browserStream = response.getOutputStream();
renderer.createPDF(browserStream);

} catch (Exception ex) {
Logger.getLogger(PdfBean.class.getName()).log(Level.SEVERE, null, ex);
}
facesContext.responseComplete();
}

最佳答案

您需要指示 JSF 您已经掌握了响应处理,并且 JSF 不应在操作方法完成时处理默认导航。将其添加到操作方法的末尾:

facesContext.responseComplete();

更新 根据评论,您正在访问 ExternalContext 作为实例变量,这表明您分配了它和 FacesContext 作为类变量,static 或作为 session 作用域 bean 的属性。这绝对是一个坏主意。您应该通过 FacesContext#getCurrentInstance() 在本地方法中获取它们,并且从不将它们分配为类变量。它们即绑定(bind)到一个特定的请求线程,该线程在下一个请求中不再存在。

关于java - JSF 2.0 使用 Flying Saucer 将 XHTML 页面转换为 PDF : java. lang.IllegalStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5662455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com