项目中会经常遇到下载明细,或者报表等功能,服务器如果使用nginx可能会因为下载明细过多,例如50000左右,导致下载超时。
如下:
504 Gateway Time-out
--------------------------------------------------------------------------------
nginx/0.7.67
解决方案,可以可以采用Ajax页面提交后台请求进行下载,在后台的action中response隔断时间返回消息,防止nginx判断服务器不响应此连接,进而断掉此次请求,类似于AJAX的长连接模式。
具体demo如下:
一、页面主要代码
function formSubmit(){
var transactionListForm = document.forms['transactionListForm'];
transactionListForm.action = 'downTrades';
parent.showWait();//显示等待信息,遮罩
//transactionListForm.submit();
ajaxSubmit(transactionListForm,function(data, textStatus){
if(textStatus=='success'){
transactionListForm.action = 'transactionList';
parent.hideWait();//取消遮罩
location.href=data.replace(/(^\s*)|(\s*$)/g, "");//trim掉之前服务端防止超时写入的空格
}
});
}
//将form转为AJAX提交
function ajaxSubmit(frm, fn) {
var dataPara = getFormJson(frm);
$.ajax({
url: frm.action,
type: frm.method,
data: dataPara,
success: fn
});
}
//将form中的值转换为键值对。
function getFormJson(frm) {
var o = {};
var a = $(frm).serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
二、服务器端
生成EXCEL报表的方法
Date downloadDate = new Date();
def filename = 'Excel-' + new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(downloadDate) + '.xls'
if(log.infoEnabled)
log.info new StringBuffer().append("交易明细下载开始,时间:").append(downloadDate).append("文件名称:").append(filename).append("交易笔数:").append(res.totalCount==null?'0':res.totalCount.toString());
File file = new File(new StringBuffer().append(request.getRealPath("/")).append(FarmConstants.downloadTradeDetailsfolder).append("/").append(filename).toString())
response.setCharacterEncoding("UTF-8")
for(int i=0;i<list.size();i++){
if(i%100==0){
//保持长连接,防止超时--返回客户端消息,此处为空格
response.getWriter().write(" ");
response.flushBuffer();
}
}
//写入临时文件--wb为poi创建的excel对象
wb.write(new FileOutputStream(file))
//给页面返回文件路径,使用页面回调方法下载文件
response.getWriter().write(new StringBuffer().append(request.getScheme()).append("://").append(request.getServerName()).append(":").append(request.getServerPort()).append(request.getContextPath()).append("/").append(FarmConstants.downloadTradeDetailsfolder).append("/").append(filename).toString());
response.flushBuffer();
if(log.infoEnabled)
log.info new StringBuffer().append("交易明细下载结束,时间:").append(new Date()).append("文件名称:").append(filename).append("交易笔数:").append(res.totalCount==null?'0':res.totalCount.toString()).append("用时:").append((new Date().getTime()-downloadDate.getTime())/1000).append("秒");