我正在构建一个Spring MVC应用程序,点击链接,我希望在我的控制器中完成一些处理。 Controller将根据处理生成Excel工作表,并将此Excel工作表发送回相同的JSP。
但是由于控制器处理和下载文件需要一些时间,比如大约30秒,我想显示一个"正在进行中"窗口或用户的某种信息,以便他们清楚地意识到正在进行下载并且用户应该等待。我尝试下面的代码显示了该消息,但没有下载该文件:
function validateMyValues(value1, value2)
{
dialog = openWin("Please wait while downloading is in progress....");
document.myform.action="getDbData";
var data = 'value1='
+value1+'&value2='
+value2;
alert("Action1: " + document.myform.action);
$.ajax({
type: "POST",
url: document.myform.action,
data: data,
success: closeWin
});
}
var myWindow;
function openWin(message) {
var w = 200;
var h = 200;
var left = Number((screen.width/2)-(w/2));
var top = Number((screen.height/2)-(h/2));
myWindow = window.open("", "myWindow", 'width='+w+', height='+h+', top='+top+', left='+left);
myWindow.document.write(message);
}
function closeWin() {
myWindow.close();
}
以下是我的JSP链接:
<a class="myClass1" href="javascript:validateMyValues('<%=value1%>','<%=value2%>')"><img src="./images/btn_valid.png" border="0" /></a>
我的下载控制器代码是:
//flushing now the file to web page
FileInputStream fileIn = new FileInputStream(outputFile);
ServletOutputStream out = response.getOutputStream();
response.setContentType ("application/download");
response.setHeader ("Content-Disposition", "attachment; filename=\""+filename+"\"");
response.setHeader("Set-Cookie", "fileDownload=true; path=/");
byte[] outputByte = new byte[4096];
//copy binary content to output stream
while(fileIn.read(outputByte, 0, 4096) != -1)
{
out.write(outputByte, 0, 4096);
}
fileIn.close();
out.flush();
out.close();
return null;
我唯一需要的是显示正在进行的&#34;&#34;向用户发送消息,直到下载完成。
答案 0 :(得分:0)
如果处理需要一段时间,您的选择是将结果传回客户端。这意味着在数据仍在输出流中写入时发回数据。
为此,您可以使用JDK 7 PipedOutputStream。例如:
PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream(out);
executor.execute(new Runnable() {
@Override
public void run() {
while(fileIn.read(outputByte, 0, 4096) != -1){
out.write(outputByte, 0, 4096);
}
}
});
IOUtils.copy(in, response.getOutputStream());
请注意,强烈建议在不同的线程中进行写入,因此请确保您拥有某个执行程序的实例。
管道输出流可以连接到管道输入流 创建一个通信管道。管道输出流是发送 管道的尽头。通常,数据被写入PipedOutputStream 对象由一个线程和数据从连接中读取 PipedInputStream由其他一些线程组成。试图使用这两个对象 建议不要使用单个线程,因为它可能使线程死锁。 如果正在读取数据字节的线程,则称管道已损坏 来自连接的管道输入流不再存在。
所以这里发生的是你的线程A将数据写入管道输出流,线程B(它是一个servlet)从中读取并以块的形式将其发送回客户端。通过这种方式,您的客户端将在浏览器中看到自己的进度,如果工作时间很长,您将永远不会超时。
希望这有帮助。