背景
事情发生在发包前的前两天
功能是这样的 有一个导出数据的按钮 带两个参数 pglx pgjgidAndZfids
之前是只能选中一页的数据 然后导出是没问题的
现在需求提出翻页能记住之前选中的数据 也就是说能导出多页数据
前台 :
window.location.href ="/jy-wxpg/export/exportExcel.xlsx?pglx="+pglx+"&pgjgidAndZfids="+pgjgidAndZfids;
后台:
@RequestMapping(value = "/exportExcel.xlsx",method = RequestMethod.GET)
@ResponseBody
public void jqButtonexportOnClickServer(@RequestParam("pglx")String pglx,@RequestParam("pgjgidAndZfids")String pgjgidAndZfids,HttpServletRequest request,HttpServletResponse response ) {
String[] pgjgidAndZfidStrings = pgjgidAndZfids.split(";");
try {
String fileName = ExcelUtils.exportInspectionRecordSurface(request, response, map,pglx);
ExcelUtils.writeExcel(response,fileName);
} catch (IOException e) {
//e.printStackTrace();
logger.error("文件下载异常", e);
} catch (Exception e) {
//e.printStackTrace();
logger.error("文件下载异常", e);
}
}else {//多个文件下载,需要压缩
//导出文件路径
String filePath = System.getProperty("catalina.base") + File.separator + "tmp\\"+getCurrentUser().getLoginId()+"\\";
//创建此路径
ZipUtil.makeDirs(filePath);
//得到此路径下文件
File fileDir = new File(filePath);
File[] fileDirs = fileDir.listFiles();
//删除此目录下文件
for (int i = 0; i < fileDirs.length; i++) {
File tmp = fileDirs[i];
if (!tmp.delete()){
logger.error("删除失败");
}
}
zipFilePath = filePath + File.separator + zipname + ".zip";
File zip = new File(zipFilePath);//创建压缩文件
//保存文件名
//String fileName = "";
//FileOutputStream os = null;
for (int i = 0; i < pgbgBeans.size(); i++) {
PgbgBean pgbgBean = pgbgBeans.get(i);
Map<String, Object> map = new HashMap<String, Object>();
map.put("pgjgzs", pgbgBean);
try {
String fileNametemp = "("+String.valueOf(i+1)+")"+ExcelUtils.exportInspectionRecordSurface(request, response, map,pglx);
ExcelUtils.writeExcelTolocal(fileNametemp+".xls", filePath);
fullFilePath = filePath+fileNametemp+".xls";
fileNameforexcel.add(fullFilePath);
} catch (IOException e) {
//e.printStackTrace();
logger.error("批量文件下载异常", e);
} catch (Exception e) {
//e.printStackTrace();
logger.error("批量文件下载异常", e);
}
}
//将excel文件生成压缩文件
File srcfile[] = new File[fileNameforexcel.size()];
for (int j = 0, n1 = fileNameforexcel.size(); j < n1; j++) {
srcfile[j] = new File(fileNameforexcel.get(j));
}
try {
ZipUtil.ZipFiles(srcfile, zip);
} catch (IOException e) {
//e.printStackTrace();
logger.error("生成压缩文件异常", e);
}
File file = new File(zipFilePath);
try {
ZipUtil.downloadZipFile(file, response, true);
} catch (IOException e) {
//e.printStackTrace();
logger.error("压缩文件下载异常", e);
}
}
}
然后测试提出一页10条数据 选择20页后 页面空白
拿到这个bug 我选择了前两页导出是完好的 在选择前三页导出的时候发生后台报错:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
解决方案
这是什么鬼 之前没遇到这种情况下。。 百度了一下说是Tomcat链接超时 改了一下Tomcat设置 也不对呀。。
一开始我以为生成的压缩包太大 写文件出现问题。。后来我改了一下还是不行。。
后来一想是不是参数太长了呢。。pgjgidAndZfids是一个两个16位的uuid用短横线隔开 选择多个后再后面追加。。
那改成post请求试试吧:
重点来了:
前端:
var form = $('<form method="POST" action="/jy-wxpg/export/exportExcel.xlsx">');
form.append($('<input type="hidden" name="pglx" value="'+ pglx +'">'));
form.append($('<input type="hidden" name="pgjgidAndZfids" value="'+ pgjgidAndZfids +'">'));
$('body').append(form);
form.submit();
后台:
@RequestMapping(value = "/exportExcel.xlsx",method = RequestMethod.POST)
@ResponseBody
public void jqButtonexportOnClickServer(HttpServletRequest request,HttpServletResponse response ) throws Exception {
String pglx = request.getParameter("pglx");
String pgjgidAndZfids = request.getParameter("pgjgidAndZfids");
....
}
改好了 没问题啊。。提测!
测试反映IE8点了没反应。。。
发现ie8不支持这个表单提交啊。。。
那就把前端改成这样:
//这种方式兼容ie8
var turnForm = document.createElement("form");
//一定要加入到body中!!
document.body.appendChild(turnForm);
turnForm.method = 'post';
turnForm.action = Artery.getContextPath()+'/export/exportExcel.xlsx';
// turnForm.target = '_blank';
var newElement = document.createElement("input");
newElement.setAttribute("name","pgjgidAndZfids");
newElement.setAttribute("type","hidden");
newElement.setAttribute("value",pgjgidAndZfids);
var newElement2 = document.createElement("input");
newElement2.setAttribute("name","pglx");
newElement2.setAttribute("type","hidden");
newElement2.setAttribute("value",pglx);
turnForm.appendChild(newElement);
turnForm.appendChild(newElement2);
turnForm.submit();
总结:
出现这个bug的原因就是get请求携带参数太长 浏览器对get请求参数长度有限制 IE浏览器对URL的最大限制为2083个字符,如果超过这个数字,提交按钮没有任何反应。 而post请求对参数长度没限制 解决方案就是创建一个form表单 改成post请求
题外话:
这个bug困扰了我很长时间 又临近发包。。回复了测试好几次都没有fix掉。。问题的本质就在于需求变更。。(总之 雨我无瓜。。)我也没想到改一个功能点竟会导致这么多问题。。后续问题还有 导出按钮重复提交 Excel 创建太多createCellStyle导致报错。。