Skip to main content

ADF 11g : Show PDF in a Popup

In one of my previous posts I showed how to use ADF popup components to display external content such as webpages like wikipedia in an inline frame. Based on this post a colleague of mine tried to display a PDF document. That didn't work. In this post I explain how you can use a servlet to open a PDF document in the inline frame. I will not explain how to invoke popups. If you need to know how to do that, refer to the post mentioned earlier.

How to create the servlet ?

The solution for showing a PDF in a popup is to use a servlet. It's possible to have a servlet deliver PDF content to the browser by specifying the content type of the servlet response to be the 'application/pdf' MIME type via 'response.setContentType("application/pdf")'.
In JDeveloper you can create a HTTP servlet very easy via the new gallery. I decided to call the servlet ShowPdfServlet which actually is a pretty descriptive name for this servlet.


For the servlet mapping I accept the default, meaning that all request containing "/showpdfservlet" in the URL will invoke the servlet. The "create servlet" wizard of JDeveloper will make sure that teh servlet and its mapping is added to the web.xml of your application.


The servlet will get the filename form a request parameter. So in the servlet I can get this value by invoking getParameter on the request.
1: String requestedFile = request.getParameter("name");

With this parameter value, and the file path (which I hardcoded for this post) I am now able to create a new File Object.
1:     // I want to invoke a pdf that is located on the machine where the application is running
2: this.filePath =
"C:\\JDeveloper\\mywork\\11gR2\\showPdfInPopup\\ViewController\\public_html\\WEB-INF\\pdf-docs";
3: // Decode the file name (might contain spaces and on) and prepare file object.
4: File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));

Next step is to initiate the servlet response:
1: response.reset();
2: response.setBufferSize(DEFAULT_BUFFER_SIZE);
3: response.setContentType(contentType);
4: response.setHeader("Content-Length", String.valueOf(file.length()));
5: response.setHeader("Content-Disposition",
"filename=\"" + file.getName() + "\"");

And now finally get the file and write it to the response.
1:    try {  
2: // Open streams.
3: input =
4: new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
5: output =
6: new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
7: // Write file contents to response.
8: byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
9: int length;
10: while ((length = input.read(buffer)) > 0) {
11: output.write(buffer, 0, length);
12: }


How to make sure the servlet is invoked ?

Remember the servlet mapping that I used earlier ? Now I will use this to make sure that I invoke the servlet every time I open the popup containing the iframe. I simply make sure thate the source of the iframe to contains the path that I use in the servletmapping. I also add a 'name' request parameter and set its value to (in this case) a value that I get from a managed bean (line 7).
1:   <af:popup id="popupFileSpecs" animate="default"  
2: contentDelivery="lazyUncached">
3: <af:panelWindow id="pw1" modal="true"
4: title="Extra information for your flight"
5: contentHeight="625" contentWidth="700" resize="on">
6: <af:inlineFrame id="if1" shortDesc="This is an inline frame"
7: source="/showpdfservlet?name=#{pageFlowScope.GeneralBean.pdfUrl}"
8: styleClass="AFStretchWidth" inlineStyle="height:600px;"></af:inlineFrame>
9: </af:panelWindow>
10: </af:popup>


Now run the application, and invoke the popup. There you go !


Simple as that.

Resources

The BalusC Code
What is a servlet ?

A copy of the workspace can be downloaded here.

Comments

Hi,
Wonderful article.

Can you please send a copy of workspace to navaneetha.krishnan.nv@gmail.com

Thanks in advance,
Navaneeth
Luc Bors said…
The workspace You requested is on its way
giovanni said…
this a very good idea for pdf presentations, can you send a workspace copy at tonelli.giovanni@gmail.com

thank you
Luc Bors said…
The workspace You requested is on its way
radiotiger said…
This is now possible with a Software Called PDF Pop-up Creator by zeescripts ar http://www.pdfpop.com. It just like a factory where you select your pdf file, and add messages and also optin forms for list building.
Anonymous said…
Luc,
Great article. Can you please send a copy of workspace to biazhang@gmail.com .

Thanks, Bill.
Luc Bors said…
Bill,
Code sample can be downloaded here :

http://adfsamplecode.googlecode.com/files/pdfPreview-works-in-R1%20-%20with%20-facelets.zip

Thanks for your request
Luc Bors said…
On be halve of Bill :
I would appreciate if you send the workspace to biazhang at gmail dot com.

Thank you. bill.
Anonymous said…
Hi,
I have followed the steps given above, and iam able to open the pdf file in a browser when i access url directly using address bar.

But when i use the same in popup's inlineframe as shown in this post, MyServelt’s doGet() method getting called multiple times(4 times). please suggest me what would be the reason.

Please suggest.

thanks in advance.
Avi said…
Hi i have implemented pdf in popup in same way as you suggested and its working perfectly on all browsers.
I am facing problem in MAC firefox. Its showing loading 0% and not proceeding. However, i have installed a plugin in MAC firefox. I am able to open any random pdf in firefox but not pdf in popup. Please suggest. Thanks in advance!!!
Unknown said…
you are amazing man!
thank you very much!! :D
Anonymous said…
Luc Bors said…
Hi Senthil,
I emailed the workspace. I hope it can help you with your work
mmesh said…
Hi Luc,

Can You please explain if it is possible to stretch the inline frame component vertically?
In popup I need to have some other widgets like buttons and radio buttons shown on the top of the popup window and bellow it should be preview part.
I tried using a panel stretch layout and have put the inline frame component in the center facet (other widgets in the top facet) but the inline component simply refuses to stretch vertically.

Help, please!

Popular posts from this blog

ADF 12.1.3 : Implementing Default Table Filter Values

In one of my projects I ran into a requirement where the end user needs to be presented with default values in the table filters. This sounds like it is a common requirement, which is easy to implement. However it proved to be not so common, as it is not in the documentation nor are there any Blogpost to be found that talk about this feature. In this blogpost I describe how to implement this. The Use Case Explained Users of the application would typically enter today's date in a table filter in order to get all data that is valid for today. They do this each and every time. In order to facilitate them I want to have the table filter pre-filled with today's date (at the moment of writing July 31st 2015). So whenever the page is displayed, it should display 'today' in the table filter and execute the query accordingly. The problem is to get the value in the filter without the user typing it. Lets first take a look at how the ADF Search and Filters are implemented by

ADF 11g Quicky 3 : Adding Error, Info and Warning messages

How can we add a message programatically ? Last week I got this question for the second time in a months time. I decided to write a short blogpost on how this works. Adding messages is very easy, you just need to know how it works. You can add a message to your faces context by creating a new FacesMessage. Set the severity (ERROR, WARNING, INFO or FATAL ), set the message text, and if nessecary a message detail. The fragment below shows the code for an ERROR message. 1: public void setMessagesErr(ActionEvent actionEvent) { 2: String msg = "This is a message"; 3: AdfFacesContext adfFacesContext = null; 4: adfFacesContext = AdfFacesContext.getCurrentInstance(); 5: FacesContext ctx = FacesContext.getCurrentInstance(); 6: FacesMessage fm = 7: new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, ""); 8: ctx.addMessage(null, fm); 9: } I created a simple page with a couple of buttons to show the result of setting the message. When the but

How to: Adding Speech to Oracle Digital Assistant; Talk to me Goose

At Oracle Code One in October, and also on DOAG in Nurnberg Germany in November I presented on how to go beyond your regular chatbot. This presentation contained a part on exposing your Oracle Digital Assistant over Alexa and also a part on face recognition. I finally found the time to blog about it. In this blogpost I will share details of the Alexa implementation in this solution. Typically there are 3 area's of interest which I will explain. Webhook Code to enable communication between Alexa and Oracle Digital Assistant Alexa Digital Assistant (DA) Explaining the Webhook Code The overall setup contains of Alexa, a NodeJS webhook and an Oracle Digital Assistant. The webhook code will be responsible for receiving and transforming the JSON payload from the Alexa request. The transformed will be sent to a webhook configured on Oracle DA. The DA will send its response back to the webhook, which will transform into a format that can be used by an Alexa device. To code