Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
431 views
in Technique[技术] by (71.8m points)

jsp - How to include file from external local disk file system folder in JSF

I have included a JSP page into Facelets using <ui:include>. In JSP page I am able to get the PDF, but it displays content as plain text. How is this caused and how can I solve it?

JSP page:

<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 page:

<!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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are at least two major mistakes in this construct.

First of all, you can't include JSP files using <ui:include>. It can only include Facelets files. JSP files would only be treated as "plain vanilla" XML. Further, JSP is deprecated since JSF 2.0. You shouldn't ever think of using it. The <ui:include> is also the wrong tool to embed a PDF file in output. You should be using the HTML <iframe> or <object> instead.

E.g.

<iframe src="/url/to/file.pdf" width="500" height="300"></iframe>

or, better

<object data="/url/to/file.pdf" type="application/pdf" width="500" height="300">
    <a href="/url/to/file.pdf">Download file.pdf</a>
</object>

(the <a> link is meant as graceful degradation when the browser being used doesn't support inlining application/pdf content in a HTML document, i.e. when it doesn't have Adobe Reader plugin installed)

or if you happen to use PrimeFaces

<p:media value="/url/to/file.pdf" width="500" height="300" />

Secondly, JSP is the wrong tool for the job of serving a file download. JSP is like Facelets designed as a view technology with the intent to easily produce HTML output with taglibs and EL. Basically, with your JSP approach, your PDF file is cluttered with <html> and <body> tags and therefore corrupted and not recognizable as a valid PDF file. This is by the way one of the reasons why using scriptlets is a bad practice. It has namely completely confused you as to how stuff is supposed to work. Facelets does not support any form of scriptlets and hence "automatically" forces you to do things the right way. In this particular case, that is using a normal Java class for the file download job.

You should be using a servlet instead. Here's a kickoff example, assuming that Servlet 3.0 and Java 7 is available:

@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());
    }

}

(you've by the way a serious typo in "Knowladge", not sure if that's further relevant to the concrete problem)

Just replace "/url/to/file.pdf" by "#{request.contextPath}/Saba_PhBill.pdf" in above HTML examples to invoke it. In <p:media> the #{request.contextPath} is unnecessary.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...