java - 使用 primefaces p :media plugin 在 liferay 上显示 pdf

标签 java pdf primefaces liferay media

我尝试使用p:media显示pdf文件,但什么也没显示(在对话框上显示pdf预览器)。该代码可以直接在浏览器上显示它,也可以下载文件。单击预览链接时没有返回错误。下面是代码:

<h:form enctype="multipart/form-data">
    <p:dataTable id="files" var="file" value="#{viewBacking.getFileList()}">
        <p:column headerText="File">
            <h:outputText value="#{file.name}" />
        </p:column>

        <p:column style="width:5%">
            <p:commandLink id="downloadLink" value="download" title="Download File" ajax="false" actionListener="#{viewBacking.getFileSelected(file, 1)}" >
                <p:fileDownload value="#{viewBacking.file}" />
            </p:commandLink>
        </p:column>

        <p:column style="width:5%">
            <p:commandLink id="previewLink" value="preview" title="Preview File" ajax="false" actionListener="#{viewBacking.getFileSelected(file, 2)}" onclick="dialogPdf.show()">
            </p:commandLink>
        </p:column>
    </p:dataTable>

    <p:dialog header="Images" widgetVar="dialogPdf" modal="true" draggable="false" resizable="false" width="1040" height="500">
        <p:media value="#{viewBacking.file}" width="100%" height="300px">  
        </p:media>
    </p:dialog>
</h:form>

这是支持 bean:

public class ViewBacking {
    private StreamedContent file;  
    public StreamedContent getFile() {  
        return file;
    }

    public StreamedContent getFileSelected(final StreamedContent doc, int mode) throws Exception {
        //Mode: 1-download, 2-preview
        try {
            File localfile = new File(getPath(doc.getName()));
            FileInputStream fis = new FileInputStream(localfile);
            //If mode preview and extension <> `pdf`, convert to `pdf`
            if (mode == 2 && !(doc.getName().substring(doc.getName().lastIndexOf(".") + 1)).matches("pdf")) {
                localfile = DocumentConversionUtil.convert(doc.getName(), fis, doc.getName().substring(doc.getName().lastIndexOf(".") + 1), "pdf");
                fis = new FileInputStream(localfile.getPath());
            }

            if (localfile.exists()) {
                try {
                    PortletResponse portletResponse = (PortletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
                    HttpServletResponse res = PortalUtil.getHttpServletResponse(portletResponse);
                    if (mode == 1)      res.setHeader("Content-Disposition", "attachment; filename=\"" + doc.getName() + "\"");
                    else if (mode == 2) res.setHeader("Content-Disposition", "inline; filename=\"" + doc.getName().substring(0, doc.getName().lastIndexOf(".")) + ".pdf\"");
                    res.setHeader("Content-Transfer-Encoding", "binary");
                    res.setContentType(getMimeType(localfile.getName().substring(localfile.getName().lastIndexOf(".") + 1)));
                    res.flushBuffer();
                    OutputStream out = res.getOutputStream();
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = fis.read(buffer)) != -1) {
                        out.write(buffer, 0, bytesRead);
                        buffer = new byte[4096];
                    }
                    file = new DefaultStreamedContent(fis, "application/pdf", "file.pdf"); //--> I tried to add this line to return the file StreamedContent

                    out.flush();
                    out.close();
                    out = null;
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    fis.close();
                    fis = null;
                    System.gc();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }
}

如果您需要更多信息,请随时询问我。谢谢。

最佳答案

PrimeFaces MediaRenderer.java 类的源代码表明 p:media 的 value 属性可以是 StreamedContent 的实例(就像您拥有的那样)或基于字符串的 URL。

我在 getFileSelected 方法中看到的问题是它在底层 HttpServletResponse 上设置 header/contenttype 等。这是有问题的,原因有两个:

1) 如果您需要做这样的事情,您应该使用 ResourceResponse 上的方法(Portlet API 的一部分)

2) 根据调用 getFileSelected 方法的时间,您可能会尝试更改 Ajax 请求的内容类型。客户端中的 PrimeFaces JavaScript 需要 JSF 部分响应,但您可能会将其更改为二进制 application/pdf。

我认为处理此问题的最佳方法是避免返回 StreamedContent 的实例,而是让 value 属性指定如下 URL:

然后像 jsf2-export-pdf-portlet 一样拥有自定义资源和 ResourceHandler。

关于java - 使用 primefaces p :media plugin 在 liferay 上显示 pdf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17246776/

相关文章:

java - 如何修复代码以删除 -Xlint :unchecked warning while compiling

ios - 在 Swift 中创建 PDF : Create New Page Automatically

java - 找不到模板位置

java - 在 Windows 64 位上运行 32 位 eclipse 和 32 位 jvm

python - 用 Python 替换 PDF 文档中的图像?

单击“primefaces”选项卡

jsf - p :dataExporter does not recognize p:cellEditor

javascript - 第一个组件集中于 <p :dialog>

java - Android Firebase 如何从 firebase 获取徽章计数响应

pdf - PhantomJs 光栅化 - 可以从多页制作多页 pdf?