Jsf Render JavaServer将xhtml面向服务器上的字符串
我正在使用一个Liferay portlet,它的UI使用PrimeFaces 5。典型的请求呈现一些XHTML模板,并将生成的HTML发送给客户端。我希望将我选择的XHTML文件呈现为commandButton操作处理程序上下文中的字符串 为了说明我的目的,假设我有以下commandButton定义:Jsf Render JavaServer将xhtml面向服务器上的字符串,jsf,jsf-2,primefaces,facelets,portlet,Jsf,Jsf 2,Primefaces,Facelets,Portlet,我正在使用一个Liferay portlet,它的UI使用PrimeFaces 5。典型的请求呈现一些XHTML模板,并将生成的HTML发送给客户端。我希望将我选择的XHTML文件呈现为commandButton操作处理程序上下文中的字符串 为了说明我的目的,假设我有以下commandButton定义: <h:form> <p:commandButton value="Export as PDF" ajax="false" act
<h:form>
<p:commandButton value="Export as PDF" ajax="false" action="#{myBean.exportPDF}" />
</h:form>
已解决
找到以下链接,使我非常接近一个可行的解决方案:
剩下的唯一问题是,我无法在操作处理程序中呈现任何内容。getExternalContext().getResponse()返回了ActionResponse的实例,而不是呈现所需的MimerResponse。为了解决这个问题,我只是在初始页面加载期间呈现XHTML,但在将XHTML转换为PDF之前等待调用操作处理程序。如果用户不想要PDF,则效率有点低,但在其他情况下似乎可以正常工作。它是否可公开访问且幂等?换句话说,
newurl(“http://.../views/pdf.xhtml)openStream()
足以胜任这项工作吗?我不这么认为。首先,这是在portlet上下文中完成的,因此我无法完全控制输出(将添加许多其他内容)。其次,服务器的请求将不会有cookie来标识正确的会话。我想可以从请求中复制出来,但整个事情会非常混乱。啊,好吧。。Portlet。。理论上,您应该能够调用ViewHandler\renderView()
,从而传递一个自定义FacesContextWrapper
,其中createResponseWriter()
返回一个ResponseWriter
,它将写入本地StringWriter
左右。这只是一些代码,我对Portlet几乎一无所知,我不能保证这是否有效。
public void exportPDF() throws DocumentException, IOException {
FacesContext ctx = FacesContext.getCurrentInstance();
ByteArrayOutputStream buf = new ByteArrayOutputStream();
ITextRenderer r = new ITextRenderer();
r.setDocumentFromString(getExportXHTML(ctx));
r.layout();
r.createPDF(buf);
HttpServletResponse sr = PortalUtil.getHttpServletResponse(
(PortletResponse)ctx.getExternalContext().getResponse());
sendPDF(sr, buf);
ctx.responseComplete();
}
private String getExportXHTML(FacesContext ctx) throws IOException {
StringBuilder s = new StringBuilder(4096);
PortletRequest pr = (PortletRequest)ctx.getExternalContext().getRequest();
PortletContext pc = pr.getPortletSession().getPortletContext();
InputStream is = pc.getResourceAsStream("/views/pdf.xhtml");
try {
InputStreamReader r = new InputStreamReader(is, "utf-8");
char[] buf = new char[4096];
int n;
while ((n = r.read(buf)) != -1) {
s.append(buf, 0, n);
}
} finally {
is.close();
}
String template = s.toString();
return ??? // TODO: How do I render template with ctx?
}