-
1. Re: Direct PDF serving
damianharvey.damianharvey.gmail.com Mar 6, 2008 2:29 PM (in response to mki_ffm)Easy. Use the byteArrayOutputStream and hook it up to a servlet. You can keep the byteArrayOutputStream in memory in a conversation/session scoped Bean until the servlet needs it. Use Component.getInstance() in your servlet to access the Bean.
Cheers,
Damian.
-
2. Re: Direct PDF serving
keithnaas Mar 6, 2008 3:27 PM (in response to mki_ffm)mki,
Possibly an even easier way that doesn't require writing a custom servlet....write a Seam component that serves up the report - this is the approach we took for the application we demoed at JbossWorld.
@Name("reportAction") public class ReportAction { @In private FacesContext facesContext; public void run() { final HttpServletResponse resp = (HttpServletResponse) facesContext.getExternalContext().getResponse(); // run the report // write the report to resp.getOutputStream() facesContext.responseComplete(); } }
Then in xhtml
<h:commandLink action="#{reportAction.run}"/>
or
<s:link action="#{reportAction.run}"/>
etc.
Good luck!
-
3. Re: Direct PDF serving
mki_ffm Mar 6, 2008 10:03 PM (in response to mki_ffm)Thanks Keith,
that was exactly the solution i was looking for. :-)
-
4. Re: Direct PDF serving
damianharvey.damianharvey.gmail.com Mar 8, 2008 5:42 PM (in response to mki_ffm)Keith,
I gave this a go and it's very cool and easier to implement than the servlet. The only thing that escapes me at the moment is how to assign a filename to the download. With the servlet I used a servlet URL pattern so I could put any name in the link.
What is the JSF equivalent of that?
Cheers,
Damian.
-
5. Re: Direct PDF serving
mki_ffm Mar 8, 2008 7:38 PM (in response to mki_ffm)That's easy, you simply have to set the Content-Disposition in the header:
final HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse(); response.setContentType("application/pdf"); response.setHeader("Content-Disposition", " attachment; filename=invoice.pdf");
Greetings,
Manuel
-
6. Re: Direct PDF serving
keithnaas Mar 8, 2008 11:58 PM (in response to mki_ffm)Damian, Manuel has it dead on. If I remember correctly IE behaves slightly differently than the other browsers so you may or may not see the right filename in all browsers. I just found this article that describes IE's flakiness.
I would have replied sooner, but we just had a record snowfall of 16 inches and I've spent a good part of the day digging out of it!
Keith
-
7. Re: Direct PDF serving
damianharvey.damianharvey.gmail.com Mar 9, 2008 11:44 AM (in response to mki_ffm)Genius. Thanks Manuel & Keith. Much appreciated.
Cheers,
Damian.
-
8. Re: Direct PDF serving
danielc.roth Mar 9, 2008 7:06 PM (in response to mki_ffm)I have used exactly that technique a couple of times, but recently I got notice from quite a few customers that it
did not work
.The problem was Safari (3+ something, whatever ships with their newest
cat
-release), where this approch does not work. So we also had to go with the custom servlet approach, which works fine. -
9. Re: Direct PDF serving
tracker Mar 20, 2008 4:03 PM (in response to mki_ffm)I implemented the solution described by Keith Naas on 3/6, and it got it working. I'm just learning, so it took a little while. Now that I have it, I would like to expose the servlet so that it is available by direct URL, instead of by JSF commandLink. Is that possible? How would I go about doing that?
-
10. Re: Direct PDF serving
mki_ffm Mar 20, 2008 4:15 PM (in response to mki_ffm)Ken,
you can define a link to your action in pages.xml.
<page view-id="/pdf.xhtml" action="#{pdfgeneratorAction.generate}"/>
Manuel
-
11. Re: Direct PDF serving
tracker Mar 20, 2008 8:12 PM (in response to mki_ffm)Thanks Manuel. Is there a way to configure it so that the page I use (/pdf.xhtml in your example) doesn't actually have to exist? I can certainly put the page in place, but it seems sort of kludgy, since it never gets displayed, and never should.
-
12. Re: Direct PDF serving
tracker Mar 20, 2008 8:38 PM (in response to mki_ffm)Thanks for your help. I am new at this, so I'm certain I'm asking questions that would seem stupid to anyone who knows this stuff, but anyway, I have one more thing. I was hoping to pass form information in the request, and use that to manipulate the PDF created. After setting up access through pages.xml, I'm not seeing any parameters in the HttpServletRequest object. I promise I'm not trying to get you to write my code for me, but I'm up against the boundaries of my knowledge.
The HTML code that calls this looks like this:
<html> <head> <title>Connector test</title> </head> <body> <p> </p> <form action="http://localhost/hbi/services/pdf/test.seam" method="post"> <input name="content" id="content" type="text" size=20> <div><input type="submit" value="PDF"></div> </form> </body> </html>
My code looks like this, and I'm finding nothing in my parameterMap:
public class PrintServer extends SeamResourceServlet { private static final long serialVersionUID = 1278807414184735439L; @In private FacesContext facesContext; @Logger private static Log log; public void test( String message ) throws ServletException, IOException, DocumentException { final HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse(); final HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest(); log.info( "context path: " + request.getContextPath()); log.info( "method: " + request.getMethod()); log.info( "URI: " + request.getRequestURI()); Map parameterMap = request.getParameterMap(); if( parameterMap==null) { log.info( "Can't get parameter names"); } else { log.info("Request Parameters: " + parameterMap.toString()); Collection <Map.Entry> paramCollection = parameterMap.entrySet(); java.util.Iterator <Map.Entry> paramIterator = paramCollection.iterator(); while( paramIterator.hasNext()) { Map.Entry me = paramIterator.next(); String [] sa = (String [] ) me.getValue(); String sValue = ""; for( int i=0; i<sa.length; ++i ) { sValue += sa[i] + ","; } log.info("Request Parameter " + me.getKey() + " size " + sValue); } log.info("Request Parameters size: " + parameterMap.size()); } log.info("Request Querystring: " + request.getQueryString()); facesContext.responseComplete(); ServletOutputStream out = response.getOutputStream(); Document document = new Document(); PdfWriter.getInstance(document, out); document.open(); document.add(new Paragraph("Form message: " + message)); document.close(); response.setContentType("application/pdf"); response.setHeader("Content-Disposition", " attachment; filename=PrintTest.pdf"); log.info("Run GraphServer.test"); return; } }
-
13. Re: Direct PDF serving
mki_ffm Mar 21, 2008 2:48 PM (in response to mki_ffm)Ken,
the beauty of the solution in 3 is, that it does even not use a servlet to deliver the PDF, so you can do everything in a standard seam way by calling an action, create the pdf and deliver it to the browser.
Inside this action you have easy access to all form values.
So why going the hard way ?
Manuel
-
14. Re: Direct PDF serving
tracker Mar 21, 2008 5:29 PM (in response to mki_ffm)Thanks for your help Manuel.
Am I going the hard way? I thought I was replicating the solution above. I do see that my code extends the SeamResourceServlet, but I'm not using that interface - it was left over from my servlet approach, and I forgot to remove it.
I restarted my JBoss server (the whole machine, in fact) and now I'm seeing the form information. There must have been something left in my deployment that was interfering, and it got cleaned out by the restart. So the code I provided above works after all.
As a last question, is there a better/simpler way to retrieve the form information than what I do above?
Thanks again.