3

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.

3
  • Why is your url ending with .json when you return application/pdf? Commented Jan 7, 2013 at 20:02
  • @Michael-O Honestly, I had put it in out of habit. The way the application is written there is one URL that the whole application runs under. It never actually changes. The .json is just normally used to prevent the page from actually redirecting to another URL that doesn't actually hold anything. Commented Jan 7, 2013 at 20:11
  • 1
    That's not a servlet at all. That's a Spring MVC controller action. Commented Jan 7, 2013 at 20:33

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
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.
0
response.setHeader("Content-Disposition", "attachment;filename=" + pdfName);

Comments

-1
 response.setHeader("Content-Disposition", "inline; filename='" + pdfName + "'");

You cannot display a PDF inline. It needs to be alone on its own page (or Iframe).

3 Comments

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.
From an AJAX call? I'm not so sure.
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).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.