Display PDF in browser with a servlet

17,923

Your JavaScript part makes no sense. You're obtaining a PDF file as ajax response and then attempting to set it as data attribute of the <object> element. The data attribute must point to a real URL, not to the file content. Fix your JS accordingly:

$("#" + this.divId).append('<object id="' + this.pdfObjectId + '" data="' + Config.server + "getPDF.json?pdfPath=" + this.pathToPdfFile + '" type="application/pdf" width="600" height="800"></object>');

The webbrowser will take care about sending the appropriate HTTP request on the given URL and initializing/rendering the <object> element using the Adobe Acrobat Reader plugin — if any available, I'd rather enclose a <a href="pdfURL">PDF</a> inside the <object> so that there's at least a graceful degradation to a download link.


Unrelated to the concrete question, that Java code is not part of a servlet at all, but a Spring MVC action. I recommend to get your terms straight and read in our Servlets wiki page to learn what they really are.

Share:
17,923
user856354
Author by

user856354

Just a normal everyday developer.

Updated on June 04, 2022

Comments

  • user856354
    user856354 almost 2 years

    I want to display a PDF file in browser. I have the path to the pdf in JS and I am making a call to grab the PDF as a servlet from java. Here's what I have so far:

    JavaScript:

    RequestManager.getJSON(Config.server + "getPDF.json?pdfPath=" + this.pathToPdfFile, (function(data){
            $("#" + this.divId).append('<object id="' + this.pdfObjectId + '" data="' + data + '" type="application/pdf" width="600" height="800"></object>');
            ResizeManager.addResizeHandler(this.pdfObjectId, this.divId, -10, -10);
        }).bind(this));
    

    Java:

    @RequestMapping("/getPDF")
    public void pdfPathToServlet(Model model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        String pdfPath = request.getParameter("pdfPath");
        if (pdfPath == null || pdfPath.equals(""))
            throw new ServletException("Invalid or non-existent file parameter in UrlServlet servlet.");
    
        if (pdfPath.indexOf(".pdf") == -1)
            pdfPath += ".pdf";
    
        File pdf = new File(pdfPath);
        String pdfName = pdfPath.substring(pdfPath.lastIndexOf("/") + 1, pdfPath.length());
        logger.debug(pdfName);
        ServletOutputStream stream = null;
        BufferedInputStream buf = null;
        try 
        {
            stream = response.getOutputStream();
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "inline; filename='" + pdfName + "'");
            FileInputStream input = new FileInputStream(pdf);
            response.setContentLength((int) pdf.length());
            buf = new BufferedInputStream(input);
            int readBytes = 0;
            while ((readBytes = buf.read()) != -1)
                stream.write(readBytes);
        } 
        catch (IOException ioe) 
        {
            throw new ServletException(ioe.getMessage());
        } 
        finally 
        {
            if (stream != null)
                stream.close();
            if (buf != null)
                buf.close();
        }
    }
    

    My problem is that this is showing the binary output in my browser as text.

    I'm not sure what I am doing incorrectly. I have tried changing the header to be attachment instead of inline, but that showed the same thing. I believe I want inline though, as I wish to show it in browser and not download it.

  • Michael-O
    Michael-O over 11 years
    That is not true. If you cann the initial url in the browser with inline header value the PDF plugin will open up in the browser otherwise it will open a new PDF viewer window.
  • Diodeus - James MacFarlane
    Diodeus - James MacFarlane over 11 years
    From an AJAX call? I'm not so sure.
  • BalusC
    BalusC over 11 years
    Even attachment wouldn't have worked at all. JS has for obvious security reasons no facilities to force a Save As dialogue with arbitrary content hold in some variable. The whole answer just doesn't apply. Note that inline works definitely on a synchronous request, provided that the browser has the appropriate plugin for it (Adobe Reader).
  • user856354
    user856354 over 11 years
    Also, I apologize for the poor terminology. I normally don't work on this side of things at all. Recent employment changes have thrown me onto this temporarily and I'm working against a very, very tight deadline. Trying to pick things up when running full speed towards a wall.
  • BalusC
    BalusC over 11 years
    You could however also have used a servlet for the job. That's more than often done, even when already using a MVC framework. Perhaps that's where the confusion is caused.