新需求是在原来的代码上进行优化查询。
优化完成之后导出功能还是需要1~3秒响应时间,毕竟数据量大,业务逻辑也较为复杂。
为了避免用户重复点击“导出”按钮,故写个遮罩层来示意用户当前正在发送下载的请求。
点击导出或下载按钮弹出遮罩层,由于无法判断文件什么时候在后台读取完,遮罩层什么时候消失成了关键.
思路是这样的:
在请求到后台下载的Servlet时,往Session中setAttribute一个值。
前台页面写个定时器,不断请求另外一个Servlet获取Session中set的值,当值为空字符串(当然你也可以自己把握)往页面out.print(Json)发送Json对象。
页面通过返回的json对象隐藏 遮罩层。
$('#submitBtn').on('click',function(){
shadeLayer(); // 弹出遮罩层
window.location.href = 'downServlet?filename=download.jpg&shadeKey=shadeLayer&shadeValue=' + new Date().getTime();
var count = 0;
var timer = setTimeout(function(){
$.post('getShadeKey?shadeKey=shadeLayer', null, function(res){
flag = res && res.shade;
count = res && res.flag === false ? count+1 : 0;
});
if(flag && count < 3){ // 生产环境上集群了服务器,极端情况下读取不到参数,容错处理.
timer = setTimeout(arguments.callee, 1000);
} else {
$('#layer').hide();
}
}, 1000);
});
// Servlet 关键代码。 // session 键集合 Enumeration<String> enumeration = session.getAttributeNames(); boolean flag = false; // 迭代 session 键 while(enumeration.hasMoreElements()){ if(enumeration.nextElement().equalsIgnoreCase(shadeKey)){ flag = true; } } String shade = (String)session.getAttribute(shadeKey); Shade sd = null; if(flag && shade != null && shade.isEmpty()){ sd = new Shade(flag, shade); out.print(GSONUtil.getGsonStr(sd)); request.getSession().removeAttribute(shadeKey); //一轮下载完毕 删除 shadeKey键。 } else { sd = new Shade(flag, String.valueOf(new Date().getTime())); out.print(GSONUtil.getGsonStr(sd)); } out.close();
