将JavaServer Faces xhtml渲染为服务器上的String

时间:2015-01-08 16:55:19

标签: jsf jsf-2 primefaces facelets portlet

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

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

<h:form>
    <p:commandButton value="Export as PDF" ajax="false" action="#{myBean.exportPDF}" />
</h:form>

单击时,它将执行辅助bean的exportPDF方法。在该方法中,我将另一个xhtml文件的内容加载到字符串中。这部分已经完成并且有效。现在,我猜我需要将字符串解析为UIComponent层次结构,然后使用当前的FacesContext呈现该层次结构。这就是我目前陷入困境的地方。

FacesContext具有{get,set} ViewRoot方法。当前视图根是客户端在其浏览器中看到的内容。如何将此视图根替换为从任意字符串生成的视图?

如按钮名称所示,所需的操作是向客户端发送PDF。我得到HttpServletResponse实例,输出正确的标题,并生成实际的PDF内容。我正在使用Flying Saucer进行PDF生成,我基本上是尝试从JSF模板创建输入XHTML。除模板位外,一切都已经有效。相关代码如下:

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

解决

找到以下链接,这些链接让我非常接近工作解决方案:

唯一剩下的问题是我无法在动作处理程序中渲染任何内容。 ctx.getExternalContext()。getResponse()返回一个ActionResponse实例,而不是渲染所需的MimeResponse。为了解决这个问题,我在初始页面加载期间简单地渲染了XHTML,但是在将XHTML转换为PDF之前等待动作处理程序被调用。如果用户不想要PDF,效率会有点低,但看起来效果不错。

0 个答案:

没有答案