防止poi等上载报表文件等过大,nginx超时
防止poi等下载报表文件等过大,nginx超时
项目中会经常遇到下载明细,或者报表等功能,服务器如果使用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("秒");