Java 使用primefaces p:media插件在liferay上显示pdf

Java 使用primefaces p:media插件在liferay上显示pdf,java,pdf,primefaces,liferay,media,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

我试图使用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;
    }
}
公共类视图备份{
私有流内容文件;
公共流内容getFile(){
返回文件;
}
公共流内容getFileSelected(最终流内容文档,int模式)引发异常{
//模式:1-下载,2-预览
试一试{
File localfile=新文件(getPath(doc.getName());
FileInputStream fis=新的FileInputStream(本地文件);
//如果模式预览和扩展为'pdf',则转换为'pdf'`
如果(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=新文件输入流(localfile.getPath());
}
if(localfile.exists()){
试一试{
PortletResponse PortletResponse=(PortletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
HttpServletResponse res=PortalUtil.getHttpServletResponse(portletResponse);
if(mode==1)res.setHeader(“内容处置”、“附件;文件名=\”“+doc.getName()+”\”);
如果(mode==2)res.setHeader(“内容处置”,“内联;文件名=\”+doc.getName().子字符串(0,doc.getName().lastIndexOf(“.”)”)+“.pdf\”);
res.setHeader(“内容传输编码”、“二进制”);
res.setContentType(getMimeType(localfile.getName().substring(localfile.getName().lastIndexOf(“.”+1));
res.flushBuffer();
OutputStream out=res.getOutputStream();
字节[]缓冲区=新字节[4096];
int字节读取;
而((字节读=fis.read(缓冲区))!=-1){
out.write(缓冲区,0,字节读取);
缓冲区=新字节[4096];
}
file=newdefaultstreamdcontent(fis,“application/pdf”,“file.pdf”);//-->我试图添加此行以返回文件streamdcontent
out.flush();
out.close();
out=null;
}捕获(IOE异常){
e、 printStackTrace();
}最后{
fis.close();
fis=null;
gc();
}
}
}捕获(例外情况除外){
例如printStackTrace();
}
返回null;
}
}

如果您需要进一步的信息,请随时询问我。谢谢。

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

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

1) 如果需要这样做,应该使用ResourceResponse上的方法(PortletAPI的一部分)

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

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


然后像jsf2导出pdf portlet那样拥有一个定制的资源和ResourceHandler。

交付pdf这样的二进制资源的最佳方法是使用jsf2 ResourceHandler。它将在webapp和portlet环境中工作。我建议您查看演示的源代码,了解如何操作。@NeilGriffin:谢谢,但我只需要在对话框中显示生成的pdf,不从头开始如何生成pdf文件。PrimeFaces MediaRenderer.java类的源代码表明p:media的value属性可以是StreamedContent的实例(如您所拥有的)或基于字符串的URL。