Как включить файл из папки файловой системы внешнего локального диска в JSF
Я включил страницу JSP в Facelets, используя <ui:include>
, На странице JSP я могу получить PDF, но он отображает содержимое в виде простого текста. Как это вызвано и как я могу решить это?
Страница JSP:
<html>
<%@page import="java.io.File"%>
<%@page import="java.io.*"%>
<body>
<%
response.reset();
File file = new File(
"D:\\TNWRD_Documents\\Knowladge_Base\\Financial_and_Administrative_powers.pdf");
response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Disposition","inline;filename=Saba_PhBill.pdf");
response.setContentLength((int)file.length());
//OPen an input stream to the file and post the file contents thru the
//servlet output stream to the browser
FileInputStream in = new FileInputStream(file);
ServletOutputStream outs = response.getOutputStream();
response.setContentLength(in.available());
byte[] buf = new byte[8192];
int c=0;
try {
while ((c = in.read(buf, 0, buf.length)) > 0)
{
//System.out.println("size:"+c);
outs.write(buf, 0, c);
}
} catch (IOException ioe) {
ioe.printStackTrace(System.out);
} finally {
outs.flush();
outs.close();
in.close();
}
%>
</body>
</html>
Страница Facelets:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:my="http://example.com/jsf"
>
<h:form>
<table width="100%" border="1">
<tr></tr>
<tr>
<td align="left" width="200px"><rich:tree id="fileTree" toggleType="ajax" var="item">
<rich:treeModelRecursiveAdaptor
roots="#{fileSystemBean.sourceRoots}" nodes="#{item.directories}">
<rich:treeNode>
#{item.shortPath}
</rich:treeNode>
<rich:treeModelAdaptor nodes="#{item.files}">
<rich:treeNode>
<a4j:commandLink value="#{item}"
action="#{TnwrdAction.downloadFile}" oncomplete="openFile();" render="fileTree"
immediate="true">
<f:setPropertyActionListener value="#{item}"
target="#{TnwrdBean.fileName}" />
</a4j:commandLink>
</rich:treeNode>
</rich:treeModelAdaptor>
</rich:treeModelRecursiveAdaptor>
</rich:tree></td>
<td >
<ui:insert name="Barrage" >
<my:include page="/WEB-INF/jsp/page.jsp" />
</ui:insert>
</td>
</tr>
</table>
</h:form>
</ui:composition>
1 ответ
В этой конструкции есть как минимум две основные ошибки.
Прежде всего, вы не можете включать файлы JSP, используя <ui:include>
, Он может включать только файлы Facelets. Файлы JSP будут рассматриваться только как "простой ванильный" XML. Кроме того, JSP устарела с версии JSF 2.0. Вы никогда не должны думать об этом. <ui:include>
это также неправильный инструмент для вставки PDF-файла в вывод. Вы должны использовать HTML <iframe>
или же <object>
вместо.
Например
<iframe src="/url/to/file.pdf" width="500" height="300"></iframe>
или лучше
<object data="/url/to/file.pdf" type="application/pdf" width="500" height="300">
<a href="/url/to/file.pdf">Download file.pdf</a>
</object>
( <a>
ссылка подразумевается как постепенное ухудшение, когда используемый браузер не поддерживает встраивание application/pdf
содержимое в HTML-документе, т. е. когда на нем не установлен плагин Adobe Reader)
или если вам случится использовать PrimeFaces
<p:media value="/url/to/file.pdf" width="500" height="300" />
Во-вторых, JSP - неподходящий инструмент для загрузки файлов. JSP походит на Facelets, разработанные как технология представления с намерением легко произвести вывод HTML с taglibs и EL. В основном, с вашим подходом JSP, ваш файл PDF загроможден <html>
а также <body>
теги и, следовательно, повреждены и не распознаются как действительный файл PDF. Это, кстати, одна из причин, почему использование скриптлетов является плохой практикой. Именно это полностью сбило вас с толку относительно того, как вещи должны работать. Facelets не поддерживает никакие формы скриптлетов и, следовательно, "автоматически" заставляет вас делать все правильно. В данном конкретном случае это использует обычный класс Java для задания загрузки файла.
Вы должны использовать сервлет вместо этого. Вот начальный пример, предполагая, что Servlet 3.0 и Java 7 доступны:
@WebServlet("/Saba_PhBill.pdf")
public class PdfServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
File file = new File("D:\\TNWRD_Documents\\Knowladge_Base\\Financial_and_Administrative_powers.pdf");
response.setHeader("Content-Type", getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"Saba_PhBill.pdf\"");
Files.copy(file.toPath(), response.getOutputStream());
}
}
(кстати, у вас серьезная опечатка в "Knowladge", не уверен, что это более актуально для конкретной проблемы)
Просто замени "/url/to/file.pdf"
от "#{request.contextPath}/Saba_PhBill.pdf"
в приведенных выше примерах HTML, чтобы вызвать его. В <p:media>
#{request.contextPath}
не нужно