Reputation: 14373
In my struts application, a user can download a file from the server.
I want to show a spinner during the time between the button click (to initiate the download) and file is ready to download. Is there an event which is triggered when the file starts to download? I assume it would be some sort of page load event.
This is the section from my struts xml:
<action name="getFile" method="getFile" class="foo.pack.TAction">
<result name="success" type="stream">
<param name="contentType">application/pdf</param>
<param name="contentDisposition">attachment;filename=${fileName}</param>
</result>
<result name="login" type="redirect">/login</result>
<result name="error" type="tiles">showError</result>
</action>
On button click, I set window.location = localhost:8080/getFile.action
The file is downloaded next (after n seconds)
What would be a way to show the spinner during the time for which the file is being fetched from the server?
Upvotes: 2
Views: 4876
Reputation: 1109635
For this answer, I'll assume "plain" JSP/Servlet/HTML/JS as I don't use Struts. For an advanced Struts (and jQuery) user it should however be trivial enough to port it to Struts (and jQuery).
To the point, you could set a cookie on the response of the download request and have JavaScript to poll for that cookie. Once the download is ready to be served, the cookie will be available in JavaScript. To ensure working across various browser windows/tabs in the same session, best is to generate an unique download token and pass it back as request parameter so that the server side can set it as a cookie value. Don't forget to expire the cookie afterwards to prevent cookie pollution.
Basically (you could substitute the <span>
with an <img>
pointing to some spinner gif):
<input type="button" value="Download" onclick="download()" />
<span id="wait" style="display:none">Please wait while we prepare the download...</span>
With this JavaScript (when using jQuery, the jquery-cookie plugin may be helpful):
function download() {
var token = new Date().getTime();
var wait = document.getElementById("wait");
wait.style.display = "block";
var pollDownload = setInterval(function() {
if (document.cookie.indexOf("download=" + token) > -1) {
document.cookie = "download=" + token + "; expires=" + new Date(0).toGMTString() + "; path=/";
wait.style.display = "none";
clearInterval(pollDownload);
}
}, 500);
window.location = "download?token=" + token;
}
And in the servlet (or Struts action if applicable):
// Prepare download here.
// ...
// Once finished, set cookie and stream download to response.
Cookie cookie = new Cookie("download", request.getParameter("token"));
cookie.setPath("/");
response.addCookie(cookie);
// ...
Upvotes: 2
Reputation: 4829
You can't do that using just client script, because there is no event for when the download completes.
Use struts2-jquery
and give an Ajax call to getFile.action
, same time u will have to use following tag-lib in order to make an Ajax call :
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
Add following line insider your head tag, also the hidden image tag.
<head>
<sj:head locale="de" jqueryui="true" defaultIndicator="myDefaultIndicator"/>
</head>
<body>
..............
<img id="myDefaultIndicator" src="images/ajax-loader.gif" alt="Loading..." style="display:none"/>
...............
</body>
Upvotes: 0
Reputation: 2278
If you have an intermediate html view, then you can add some deferred javascript action to display a spinner, while view call localhost:8080/getFile.action in the background. Anyway, i don't know how to hide the spinner once download complete.
Upvotes: 0