Jsf Render JavaServer将xhtml面向服务器上的字符串

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

我正在使用一个Liferay portlet,它的UI使用PrimeFaces 5。典型的请求呈现一些XHTML模板,并将生成的HTML发送给客户端。我希望将我选择的XHTML文件呈现为commandButton操作处理程序上下文中的字符串

为了说明我的目的,假设我有以下commandButton定义:

<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?
}