Thanks Carl! Your method worked fine. It's almost fully implemented, but the only question I have that remains is the proper way to generate tokens. I haven't ever had to generate them before - is there an automatic way of generating unique tokens, or is generateToken () a function I would write myself and have to ensure that each token generated was unique?
For now, I just hard coded a random string into the code, which worked well enough to see that the PDF did indeed open in a new window and display as expected. I will also need to figure out the session settings so that they are invalidated properly, although I think I will need to do a bit more reading on this. // RPC code in the class which extends RemoteServiceServlet public String generatePDF(ReportDO report, int id) { // initialize new document for PDF Document document = new Document(); // generate one time token that the client can use to retrieve the PDF String token = "258958395ai53"; // generate test PDF try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfWriter.getInstance(document, baos); document.open(); document.add(new Paragraph("Hello World!")); document.close(); byte[] pdf = baos.toByteArray(); HttpServletRequest request = this.getThreadLocalRequest(); HttpSession session = request.getSession(); session.setAttribute(token, pdf); } catch (Exception e) { System.out.println("ReportServlet::generatePDF::Exception " + e.getMessage()); } return token; } // standard servlet public class PDFServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // create output stream from byte array in session ByteArrayOutputStream baos = new ByteArrayOutputStream(); String token = request.getParameter("token"); byte[] pdf = (byte[]) request.getSession().getAttribute(token); baos.write(pdf); // setting some response headers response.setHeader("Expires", "0"); response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); response.setHeader("Pragma", "public"); response.setContentType("application/pdf"); // content length is needed for MSIE response.setContentLength(baos.size()); // write ByteArrayOutputStream to ServletOutputStream ServletOutputStream out = response.getOutputStream(); baos.writeTo(out); out.flush(); } } // client side code section ReportController.getInstance().generatePDF(report, id, new AsyncCallback() { public void onFailure(Throwable caught) { SC.say("Failed"); } public void onSuccess(Object result) { String token = (String) result; Window.open("PDFService?token=" + token, "_blank", "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes"); } }); } }); On Apr 7, 1:04 am, Carl Pritchett <bogusggem...@gmail.com> wrote: > The simplest safest way I can think of is basically the same as other > people have already stated in this thread. > Using a token and storing data in the session means that the pdf data > is unique to the user (as long as the session is invalidated > properly). > > - Send an RPC call to generate the pdf (or at least send the > information used to generate the pdf) > - The RPC service saves the pdf (or request data) in the session: > > // use the data to create the PDF usingiTextetc > byte[] pdf = generatePDF(requestData); > > // generate a one-time token that the client can use to > retrieve the PDF > String token = generateToken(); > > HttpServletRequest req = this.getThreadLocalRequest(); > HttpSession session = req.getSession(); > session.setAttribute(token, pdf); > return token; > > - Then the client calls a normal servlet with the token as a parameter > (localhost:8080/myApp/pdfRetriever?token=...) > - This servlet looks up the data in the session using the token, > removes the attribute, and sends back the pdf > > String token = req.getParameter("token"); > byte[] pdf = (byte[])req.getSession().getAttribute(token); > > Carl. > > On Apr 7, 11:18 am, Superman859 <russ.d.hollo...@gmail.com> wrote: > > > Thanks for all the responses. I had (and still do) little > > understanding of responses and requests as I rarely work directly with > > them. However, I now see that GWT-RPC is not the way to go. From > > what I've read and what I saw using Firebug, GWT-RPC sets up the > > response variable for it's own purposes as part of GWT-RPC, so by > > going in and modifying it myself I caused problems with GWT-RPC. > > > Instead of extending RemoteServiceServlet, I extended HttpServlet and > > have been able to get a result. However, I was not able to get a > > result from the GWT app yet using RequestBuilder. I attempted to do > > so, and the function ran (I had some print statements which showed up > > in the log) successfully and the RequestCallback received a response. > > However, nothing happened. > > > Is it possible to do this using RequestBuilder? Using Firebug, I saw > > a response was generated and it seemed to have the correct headers as > > I had set. However, no PDF file opened, was offered, etc. and it > > appeared as if nothing happened. > > > I was able to get it to generate a PDF by simply typing the URL into > > my browser... > > >www.site.com/app-name/PDFServlet > > > that URL displayed a Hello World example PDF as expected. Ideally, > > this would open by clicking from GWT app. I suppose I could create a > > standard HTML link in the GWT app and that may work, but I wonder why > > the RequestBuilder did not work, even though response was returned. > > > And finally - does anyone have any tips on ways to make it more secure > > somehow? While there is a rare chance, and it probably wouldn't be > > anything serious, anyone could type in the URL in the browser and view > > the reports that will be generated, provided they pass in the report > > ID, etc. Is there a way that it would only work if accessed from the > > app (which is user protected) or are there any other tips on making it > > a bit more secure? > > > Below is my current servlet code, followed by the RequestBuilder part > > of the app that failed to work as expected. > > > public class PDFServlet extends HttpServlet { > > > public void doGet(HttpServletRequest request, HttpServletResponse > > response) throws IOException, ServletException { > > System.out.println("Hello World! to follow"); > > > Document document = new Document(); > > > // generate test PDF > > try { > > > ByteArrayOutputStream baos = new ByteArrayOutputStream(); > > //PdfWriter.getInstance(document, new FileOutputStream > > ("HelloWorld.pdf")); > > PdfWriter.getInstance(document, baos); > > document.open(); > > document.add(new Paragraph("Hello World!")); > > document.close(); > > > // setting some response headers > > response.setHeader("Expires", "0"); > > response.setHeader("Cache-Control", "must-revalidate, > > post-check=0, > > pre-check=0"); > > response.setHeader("Pragma", "public"); > > > response.setContentType("application/pdf"); > > > // content length is needed for MSIE > > response.setContentLength(baos.size()); > > > // write ByteArrayOutputStream to ServletOutputStream > > ServletOutputStream out = response.getOutputStream(); > > baos.writeTo(out); > > out.flush(); > > } > > catch (Exception e) { > > System.out.println("PDFServlet::doGet::Exception " > > + e.getMessage > > ()); > > } > > > } > > > } > > > /* > > * Code in GWT app - ultimately I will pass report type, ID to the > > servlet to generate the > > * appropriate report > > */ > > public void onRecordClick(RecordClickEvent event) { > > //need to add report ID, etc. to the > > request in the future > > RequestBuilder request = new > > RequestBuilder(RequestBuilder.GET, > > "PDFService"); > > request.setCallback(new RequestCallback() { > > > public void onError(Request > > request, Throwable exception) { > > SC.say("onError"); // this > > is just an alert > > > } > > > public void > > onResponseReceived(Request request, > > Response response) { > > > > SC.say("onResponseReceived"); // alert > > > } > > > }); > > > On Apr 6, 5:45 pm, Daniel Jue <teamp...@gmail.com> wrote: > > > > There is a PDF generation demo using a GWT entrypoint on the DynamicJasper > > > website (a wrapper for Jasper, which I think still usesiTextdeep inside). > > > >http://dynamicjasper.sourceforge.net/ > > > > Anyway you can look at the relevant servlet code there, and the hand-off > > > from the GWT "run report" button. > > > > On Mon, Apr 6, 2009 at 4:55 PM, thebuz...@gmail.com > > > <thebuz...@gmail.com>wrote: > > > > > Foritextjust do a like to like a jsp page that will run theitext > > > > gen. Thats how i do it and it works great. > > > > > On Apr 6, 11:55 am, Peter Ondruška <peter.ondru...@gmail.com> wrote: > > > > > I think you should not use GWT RPC servlet, just use normal servlet. > > > > > > 2009/4/6, Superman859 <russ.d.hollo...@gmail.com>: > > > > > > > I want to useiTextto generate a PDF file. Ideally, I can > > > > > > incorporate a generatePDF() method into my interface and my Servlet > > > > > > that is involved in GWT-RPC. When that method is called, I want it > > > > > > to > > > > > > generate a PDF file and either display it to the user in a new > > > > > > window > > > > > > or present a save dialog box or anything - something that leaves the > > > > > > GWT app as it was and allows the user to view / save / print the > > > > > > PDF. > > > > > > > Generating the PDF is not a problem. I can generate one and write > > > > > > it > > > > > > to a file on the server without any trouble. However, I am having > > > > > > trouble presenting the user with it (I would rather NOT write them > > > > > > to > > > > > > files on the server, and just let the user save on their own machine > > > > > > if they wish to do so). > > > > > > > Here is code for a sample "Hello World" > > > > > > > public boolean generatePDF(ReportDO report, int id) { > > > > > > System.out.println("hello world to follow"); > > > > > > // get request > > > > > > //HttpServletRequest request = getThreadLocalRequest(); > > > > > > > // get response > > > > > > HttpServletResponse response = getThreadLocalResponse(); > > > > > > > Document document = new Document(); > > > > > > > // generate test PDF > > > > > > try { > > > > > > > ByteArrayOutputStream baos = new ByteArrayOutputStream(); > > > > > > //PdfWriter.getInstance(document, new FileOutputStream > > > > > > ("HelloWorld.pdf")); > > > > > > PdfWriter.getInstance(document, baos); > > > > > > document.open(); > > > > > > document.add(new Paragraph("hello world")); > > > > > > document.close(); > > > > > > > // setting some response headers > > > > > > response.setHeader("Expires", "0"); > > > > > > response.setHeader("Cache-Control", "must-revalidate, > > > > post-check=0, > > > > > > pre-check=0"); > > > > > > response.setHeader("Pragma", "public"); > > > > > > > response.setContentType("application/pdf"); > > > > > > > // content length is needed for MSIE > > > > > > response.setContentLength(baos.size()); > > > > > > > // write ByteArrayOutputStream to ServletOutputStream > > > > > > ServletOutputStream out = response.getOutputStream(); > > > > > > baos.writeTo(out); > > > > > > > > ... > > read more » --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to Google-Web-Toolkit@googlegroups.com To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/Google-Web-Toolkit?hl=en -~----------~----~----~----~------~----~------~--~---