Default header p:media with pdf player

雨燕双飞 提交于 2019-12-24 01:24:16

问题


I'm programming a <p:lightBox> with a streamed <p:media> to preview external PDFs.

It works fine but i'm getting a little handicap.

When the pdf dialog is rendered it shows (on mouse over) one Header where it always display the same title: "dynamiccontent.properties".

Is there an attribute or something that I can override to customize it?

JSP code:

<p:lightBox>
  <h:outputLink value="#" title="#{myDoc.fileName}">
    <i class="fa fa-eye" aria-hidden="true"></i>
  </h:outputLink>

  <f:facet name="inline">
    <p:media value="#{documentController.stream}" width="1100px" height="600px" player="pdf">
        <f:param name="idStore" value="#{myDoc.idStore}" />
    </p:media>
  </f:facet>
</p:lightBox>

Displayed header for a PDF

Thanks for your time.


回答1:


This seems to be a bug in Primefaces. Checkout Primefaces version 6.1 as they seem to have fixed this issue here. Then, setting the content name in DefaultStreamedContent works

new DefaultStreamedContent(pdfData(), "application/pdf", "document.pdf");

My <p:media> in xhtml:

<p:media value="#{pdfViewerController.fileStream}" player="pdf" cache="false" />

And the rendered <p:media> looks like this:

<object type="application/pdf"
        data="/javax.faces.resource/dynamiccontent.properties;/document.pdf?ln=primefaces&amp;v=6.1&amp;pfdrid=8881a099cd5419259117729be00f4824&amp;pfdrt=sc&amp;pfdrid_c=false&amp;uid=f6c9ade9-4d7b-47ab-832f-19b119e6cd58"
        internalinstanceid="9" title="">
</object>

Then both the pdf viewer title and the download file name in Chrome are "document.pdf".




回答2:


I have encountered the same problem when using google chrome.
The header does not appear in IE 11.
(I'm only using IE 11 and Google Chrome so I don't know what this looks like on other browser)

This is what a rendered media with a streamed value will look like:

<object type="application/pdf"
    data="/projectName/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&amp;v=6.1&amp;pfdrid=a754229fe5cdabff72537ef0693a2399&amp;pfdrt=sc&amp;pfdrid_c=true"
    height="600px" width="1100px" internalinstanceid="6">
</object>

/projectName/javax.faces.resource/dynamiccontent.properties.xhtml comes from DynamicContentSrcBuilder#build(resourcePath)

I have tried:

1. setting name in DefaultStreamedContent

new DefaultStreamedContent(getData(), "application/pdf", "test.pdf");

this does not seem to work. name becomes null in MediaRenderer#encodeEnd so the name is not added in the src.

if (streamedContent.getName() != null) {
    int index = src.indexOf("?");
    src = src.substring(0, index) + ";/" + streamedContent.getName() + ""
        + src.substring(index, src.length());
}

2. override MediaRenderer#encodeEnd and add a fixed value name(Test.pdf)

if ((value != null) && (value instanceof StreamedContent) && (player.getType().equals("application/pdf"))) {
    streamedContent = (StreamedContent) value;
    if (streamedContent.getName() != null) {
        int index = src.indexOf("?");
        src = src.substring(0, index) + ";/" + streamedContent.getName() + ""
                + src.substring(index, src.length());
    }

    src = src.substring(0, index) + ";/Test.pdf"
                + src.substring(index, src.length());
}

This also did not worked. The lightBox opens but can't display the pdf file.

3. override MediaRenderer#encodeEnd and replace the value of "dynamiccontent.properties" in the src with the value from title which is set in xhtml.

MediaRenderer#encodeEnd

if ((value != null) && (value instanceof StreamedContent) && (player.getType().equals("application/pdf"))) {
    streamedContent = (StreamedContent) value;
    if (streamedContent.getName() != null) {
        int index = src.indexOf("?");
        src = src.substring(0, index) + ";/" + streamedContent.getName() + ""
                + src.substring(index, src.length());
    }

    if (src.contains("dynamiccontent.properties")) {
        String[] urlParams = src.split("&");

        for (String param : urlParams) {
            if (param.contains("title=")) {
                String[] titleAndValue = param.split("=");
                src = src.replace("dynamiccontent.properties", titleAndValue[1]);
            }
        }
    }
}

xhtml

<p:lightBox>
    <h:outputLink value="#" title="#{myDoc.fileName}">
        <i class="fa fa-eye" aria-hidden="true"></i>
    </h:outputLink>

    <f:facet name="inline">
        <p:media value="#{documentController.stream}" width="1100px" height="600px" player="pdf">
            <f:param name="title" value="Test.pdf" />
        </p:media>
    </f:facet>
</p:lightBox>

redered media will look something like this.

<object type="application/pdf"
    data="/projectName/javax.faces.resource/Test.pdf.xhtml?ln=primefaces&amp;v=6.1&amp;pfdrid=a754229fe5cdabff72537ef0693a2399&amp;pfdrt=sc&amp;title=Test.pdf&amp;pfdrid_c=true"
    height="600px" width="1100px" internalinstanceid="6">
    <param name="title" value="Test.pdf">
</object>

This works but only on StreamedContent. following is a screenshot of the pdf header.

Note that ".xhtml" is needed. It will not work without it.

Hope this helps.




回答3:


This happend just because the DefaultStreamedContent lost the file's Propertis, this means Title and name.

It must to be used a servlet to set the header, contenttype and  file´s name. while it is downloaging:

import java.io.File; 
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.annotation.Resource;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/pdf/*")
public class ServletPdf extends HttpServlet {

private static final long serialVersionUID = 8401022908619069931L;

String fileDirectory = "C:/directory";

@Override
protected void doGet(HttpServletRequest request,
        HttpServletResponse response) {
    String fileName, filePath, absolutePath;
    Path path;
    try {
        String requestedFile = request.getPathInfo().substring(1);
        if (requestedFile == null) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }
        requestedFile = fileDirectory + File.separator + requestedFile;

        path = Paths.get(requestedFile);
        fileName = path.getFileName().toString();
        absolutePath = path.toAbsolutePath().toString();
        filePath = absolutePath.substring(0,
                absolutePath.lastIndexOf(File.separator));
        File file = new File(filePath, fileName);

        if (!file.exists()) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

        String contentType = getServletContext()
                .getMimeType(file.getName());
        if (contentType == null || !contentType.startsWith("application")) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        response.reset();
        response.setContentType(contentType);
        response.setHeader("Content-Length", String.valueOf(file.length()));

        Files.copy(file.toPath(), response.getOutputStream());
        } catch (IOException ex) {
           ex.printStackTrace();
        }
    }

 }

The method could be in this way, the servlet with the declared name it's invoked with @webservlet:

import java.io.File;
import java.io.Serializable;

import org.springframework.stereotype.Controller;

@Controller("mbPdf")
public class mbPdfFile implements Serializable(){

private static final long serialVersionUID = 8817606290129899111L;

String fileDirectory = "C:/directory";
String filePath = "resources/pdf";
String fileName = "testPdf.pdf";

public String filePathComplete() {
    String path = fileDirectory + File.separator + filePath
            + File.separator + fileName;
    File pdf = new File(path);
    if (pdf.exists()) {
        path = "/pdf//" + filePath + File.separator + fileName;
    } else {
        // Information message
    }
    return path;
  }
}

The view works with the primeface´s component: <p:media />:

<p:media id="pdf" value="#{mbPdf.filePathComplete()}" 
         width="80%" height="800" />


来源:https://stackoverflow.com/questions/44393132/default-header-pmedia-with-pdf-player

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!