downloading file from servlet

1,559 views
Skip to first unread message

mike b

unread,
Oct 19, 2010, 11:49:12 PM10/19/10
to Google Web Toolkit
I have read all the other posts about downloading Excel files and how
to do it w/ an IFRAME, with RequestBuilder, and Window.open().
However, none of them actually work. Luckily, I have a working
servlet which executes and returns successfully with javascript.
However, we'd like to do it all in GWT. The error message from IE is
below. The Window.open() DOES work with FF, but not with IE.
Unfortunately, we must deploy to IE, no options there.

Situation:
GWT 2.0.4 mvp4g 1.2.0
Need to download a file to open in Excel. At this point, its actually
a text file, but the MIME type is setup for Excel.

The servlet has been tested w/ straight java script using
"document.body.appendChild(iframe);". This works like a champ in IE
and FF.

However, when I do "Window.open(url, "_self",null);" in GWT, IE can't
download the file. It throws an error saying...

"
Internet Exploroer cannot download MyFile from localhost

IE was not able to open this Internet site. The requests site is
either unavailable or cannot be found. Please try again later.
"

In GWT, I have also tried just using a Frame, adding it to a Panel,
and then calling myFrame.setUrl("myUrl");

This also successfully gets to the servlet, but fails w/ the above
error message while trying to "open" the file.

It seems as if GWT is telling the browser to cancel the download when
it pops up.

Any suggestions? Any guesses?

Thanks,
mikeb

Jim Douglas

unread,
Oct 20, 2010, 12:28:40 AM10/20/10
to Google Web Toolkit
This is what I'm doing. YMMV and assorted disclaimers; it's quite
likely that this can be improved upon.

(1) I generate this place-holder for the file download in my GWT web
pages:

out.println("<div id=\"__gwt_downloadFrame\" tabIndex='-1'></
div>");

(2) To initiate a download from the client side, I do this:

public static void download(String p_uuid, String p_filename)
{
String fileDownloadURL = "/fileDownloadServlet"
+ "?id=" + p_uuid
+ "&filename=" +
URL.encode(p_filename);
Frame fileDownloadFrame = new Frame(fileDownloadURL);
fileDownloadFrame.setSize("0px", "0px");
fileDownloadFrame.setVisible(false);
RootPanel panel = RootPanel.get("__gwt_downloadFrame");
while (panel.getWidgetCount() > 0)
panel.remove(0);
panel.add(fileDownloadFrame);
}

(3) The corresponding FileDownloadServlet does this (with unimportant
details omitted):

@Override
protected void doGet(HttpServletRequest p_request,
HttpServletResponse p_response)
throws ServletException, IOException
{
String filename = p_request.getParameter("filename");
if (filename == null)
{
p_response.sendError(SC_BAD_REQUEST, "Missing filename");
return;
}

File file = /* however you choose to go about resolving
filename */

long length = file.length();
FileInputStream fis = new FileInputStream(file);
p_response.addHeader("Content-Disposition",
"attachment; filename=\"" + filename +
"\"");
p_response.setContentType("application/octet-stream");
if (length > 0 && length <= Integer.MAX_VALUE);
p_response.setContentLength((int)length);
ServletOutputStream out = p_response.getOutputStream();
p_response.setBufferSize(32768);
int bufSize = p_response.getBufferSize();
byte[] buffer = new byte[bufSize];
BufferedInputStream bis = new BufferedInputStream(fis,
bufSize);
int bytes;
while ((bytes = bis.read(buffer, 0, bufSize)) >= 0)
out.write(buffer, 0, bytes);
bis.close();
fis.close();
out.flush();
out.close();
}

That all causes the selected file to be downloaded to the client
browser in whatever way the browser chooses to handle downloads.

mike b

unread,
Oct 20, 2010, 9:30:22 AM10/20/10
to Google Web Toolkit
Thank you! Thank you! Thank you!

That worked on the first try!! Much Appreciated!!!

mike b

unread,
Oct 20, 2010, 10:13:25 AM10/20/10
to Google Web Toolkit
I should state for the benefit of others that what really worked in
this case was added the <div id="__gwt_downloadFrame" tabIndex='-1'></
div>) to my HTML page and then adding the Frame to the results of the
the RootPanel.get("__gwt_downloadFrame");. This put my IFRAME on the
base of the page.

So, the key appears to be NOT nesting the IFRAME deeply in the DOM
when adding the URL to it.

This is actually what our pure javascript solution was doing, but I
didn't realize the impact of mistakenly adding my Frame to a panel so
much deeper in the DOM with the GWT solution.

Very helpful!
Thanks again!
Message has been deleted

Velusamy Velu

unread,
Mar 21, 2016, 8:53:45 PM3/21/16
to GWT Users
Thanks for this discussion, I'm able to resolve one of the issues I was running in to.  Now I have 'A' solution if not the most perfect one. 

The use I have is - 
  1. User creates a drawing on HTML5 canvas.
  2. Drawing is converted to SVG on the browser.
  3. User wants to save the drawing as SVG file.
  4. However, I'm not sure a way exists the to save the SVG directly from the browser.
  5. So the string representing SVG is sent to the server.
  6. Server creates a name for the SVG.
  7. And sends the SVG back to the browser.
  8. The browser instantly saves the file with the name assigned by the browser.
That's really good, but I'm sure there has to be a way to save the SVG created by the JS code without making a round trip to server.  Has any one have the know how?

Thanks
Velu

kjordan

unread,
Mar 22, 2016, 10:02:10 AM3/22/16
to GWT Users
It's possible through a data URI with faking a click on a download anchor: http://stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server

Velusamy Velu

unread,
Mar 22, 2016, 11:32:57 AM3/22/16
to GWT Users
Thank you very much kjordan, it works like a charm.  In addition to your suggestion I added this to change the default file name with the extension I wanted.

        link.getElement().setAttribute("download", "drawing.svg");

I appreciate your help.
Reply all
Reply to author
Forward
0 new messages