0

Basically, I have a web application that must generate large *.pdf reports. It's being hosted on Google App Engine, and I'm using Google Web Toolkit to deploy it. The client calls getReport() method on server, which reads the needed data and generate the report. As I can't write files on Google App Engine, I write it to memory and get its bytes, as the return response of my server method.

Once the documents may lead to large files, I get the report bytes from the server at an earlier point in my application, and, when requested by client, I need to turn those bytes into a *.pdf file and make it avaliable as a download. So I need another servlet to do that.

My remote method is implemented as below.

@Override
    public byte[] getReport(String arg0, String arg1) {
        try {
            Document document = new Document();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfWriter.getInstance(document, baos);
            document.open();
            /* Report generation */
            document.close();
            return baos.toByteArray();
        } catch (DocumentException e) {
            /* Exception handling */
            return null;
        }
    }

I implemented a servlet using GET just to generate a *.pdf file, as following, just for test purposes.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment; filename=report.pdf");
            try {
                Document document = new Document();
                PdfWriter.getInstance(document, response.getOutputStream());
                document.open();
                /* Test report generation */
                document.close();
            } catch (DocumentException e) {
                /* Exception handling */
            }
    }

I have configured both of them to /project/retrieve_report and /project/get_report, respectively, and they work from the browser. I have the bytes from remote server avaliable when I execute the method.

AsyncCallback<byte[]> callback = new AsyncCallback<byte[]>(){
                    @Override
                    public void onFailure(Throwable caught) {
                    }
                    @Override
                    public void onSuccess(byte[] result) {
                    }};
                reportService.getReport(arg0, arg1, callback);

So what I really need now and couldn't find any solid help is to redirect the client to the servlet from the onSucess() condition, sending the byte array result as a parameter, getting the report as a file download in the browser. I'll have to replace the doGet() with a doPost(), retrieve the byte array parameter and use it to build the file, but I'm kinda lost here.

I'm really new into web applications, so any help would be greatly appreciated. I've been searching around for this but I'm stuck and I have a short calendar for this graduation project.

Thanks in advance.

1 Answers1

0

you can write or call the getReport method inside servlet also. and from client you just required to call that servlet using method window.open directly for pdf download.

You have to call initial rpc which set bytes in session variable at server side.

HttpServletRequest request = this.getThreadLocalRequest();      
HttpSession session = request.getSession(); 
session.setAttribute("PdfFileInByte", getReport())

then each pdf download call, you have to read that file from session and download pdf file.

PdfWriter.getInstance(document, session.getAttribute("PdfFileInByte"));

Then, If you would like to no longer use of it, then remove it from session attribute.

bNd
  • 7,512
  • 7
  • 39
  • 72
  • 1
    That was my first thought, but the application will generate documents with hundreds of pages, so my idea was to generate the document bytes in an earlier stage, so when the user asks for it the application just send a request to the download servlet with the previously built byte array as a parameter. This way the overhead to the user is only retrieving the bytes, not processing the whole document... – Ricardo Gonçalves Mar 15 '13 at 14:30
  • @RicardoGonçalves ok, so you can set that bytes on server session also while calling first rpc, then after make call for pdf download servlet and write pdf from session byte code. because just think how did you get completion event of pdf download from server to client? see updated answer. – bNd Mar 15 '13 at 14:49
  • Similar query - http://stackoverflow.com/questions/13725198/how-to-make-user-can-download-file-in-client-side-google-web-toolkit/ – appbootup Mar 15 '13 at 16:47