问题
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&v=6.1&pfdrid=8881a099cd5419259117729be00f4824&pfdrt=sc&pfdrid_c=false&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&v=6.1&pfdrid=a754229fe5cdabff72537ef0693a2399&pfdrt=sc&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&v=6.1&pfdrid=a754229fe5cdabff72537ef0693a2399&pfdrt=sc&title=Test.pdf&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