How to get PDF content (served from a Spring MVC controller method) to appear in a new window

14,212

Solution 1

Specify target="_blank" in the form:form tag that submits your form.

Solution 2

Use the @RequestMapping produces to define the reponse type.

@RequestMapping(value = doc/{docId}, method = RequestMethod.GET, produces =  "application/pdf")
@ResponseBody
public byte[] getDocument(@PathVariable("docId") String docId) throws Exception
{
    return service.getDocument(docId);
}

Solution 3

You would do that on the client side with some javascript e.g.,:

<a href="http://www.myWebApp.com/somePdf.pdf" onclick="window.open('http://www.myWebApp.com/somePdf.pdf'); return false;" target="_blank">My Super Awesome Docment</a>

(substitute with pretty jQuery-ness as desired) If you want something else to happen in the main window just don't return false from the onClick event, and let the regular click do whatever thing it is that you want to happen in the main window

It's not up to you if PDFs open in a browser window or in Adobe, that's configuration on the user's computer.

--

Also, just as a Spring thing, @ResponseBody on a void method doesn't make any sense. @ResponseBody is telling spring to use the method's return type as the Response. That is, you would return the byte[] from the method and let spring deal with turning it into a servlet response. Rather than writing the response directly yourself inside the method

Share:
14,212
Ninju Bohra
Author by

Ninju Bohra

Updated on July 24, 2022

Comments

  • Ninju Bohra
    Ninju Bohra almost 2 years

    I am a newbie with Spring MVC but I'm quite impressed with its capabilities.

    I am using 3.1.0-RELEASE and I have to show a PDF in response to form:form submission.

    Here is the (small) code I wrote in the controller:

    @RequestMapping(value = "new_product", method = RequestMethod.POST, params = "print")
    @ResponseBody
    public void saveAndShowPDF(ModelMap map, ShippingRequestInfo requestInfo, HttpServletRequest request, HttpServletResponse httpServletResponse) throws IOException {
        saveProductChanges(map, requestInfo, request, httpServletResponse);
        httpServletResponse.setContentType("application/pdf");
        byte[] pdfImage = productService.getPDFImage(requestInfo.getRequestId());
        httpServletResponse.getOutputStream().write(pdfImage);
    }
    

    This code sends the PDF byte[] back to the original window.

    How do I get the PDF to be shown in a separate window so that I can still have the original browser window to show some other content? The best way would be to have the PDF shown using the client PDF view program (Adobe Reader, FoxIt etc.) but I would be fine with the PDF showing up in a separate browser window.

    EDIT: I decided to set the Content-Disposition so that the browser brings up a save/open box where the user can open Adobe (with losing the main browser page).

    httpServletResponse.setHeader("Content-Disposition","attachment;filename=cool.pdf");
    

    Thanks everyone!

  • Ninju Bohra
    Ninju Bohra about 12 years
    I don't have an <a>nchor tag that is requesting a PDF...the PDF byte[]s are coming back from a MVC controller response. You are right that the best I can do is use target"_blank" to get the response (i.e. PDF image) in a separate window. Now is it possible to have the original window render a new page (along with the PDF in a new window)?
  • Affe
    Affe about 12 years
    Something that was done on the client side triggered the request to the controller! Whether it's clicking a link or submitting a form, you need to tell the browser to open the response in a new window at the time you submit it client side.
  • Ninju Bohra
    Ninju Bohra about 12 years
    The target="_blank" will (hopefully) show the PDF in a separate window. If I make the controller method return a String can I have the original window render a new page (along with the PDF in a new window)?
  • Affe
    Affe about 12 years
    If you want something else to happen in the main window just don't return false from the onClick event, and let the regular click do whatever thing is is you want to happen in the main window.
  • Ninju Bohra
    Ninju Bohra about 12 years
    Darn...I can't use target="_blank" because the form has multiple type="submit" buttons and I only this button needs its response (the PDF) in a separate window. I decided to set the Content-Disposition to bring a save/open box where the user can open Adobe (with losing the main browser page) httpServletResponse.setHeader("Content-Disposition","attachm‌​ent;filename=_blank"‌​);
  • Ninju Bohra
    Ninju Bohra about 12 years
    Darn...I can't use target="__blank" because the form has multiple type="submit" buttons and I only this button needs its response (the PDF) in a separate window. I decided to set the Content-Disposition to bring a save/open box where the user can open Adobe (with losing the main browser page) httpServletResponse.setHeader("Content-Disposition","attachm‌​ent;filename=product‌​.pdf");
  • Affe
    Affe about 12 years
    You could still do it with javascript /shrug