@[TOC]( [已解决]getWriter() has already been called for this response] with root cause)
【已解决】使用easy-poi实现导入excel功能,报错 getWriter() has already been called for this response] with root cause,影响导出excel
在项目中,需要导出查询数据为excel,在本地使用idea测试没有问题。但在测试环境,相同代码,报错“getWriter() has already been called for this response] with root cause”,影响下载功能。
另外,报错 “getWriter() has already been called for this response] with root cause” 的问题已经找到原因,并解决,请看文章最后一段。
报错截图
分析报错
通过对报错信息的分析,关键就是流信息重复开
解决方法
原来代码
private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws Exception {
OutputStream outputStream=null;
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
//response.flushBuffer();
outputStream = response.getOutputStream();
workbook.write(outputStream);
} catch (IOException e) {
throw new ServiceException(ResponseEnum.EXCEPTION_FILE_IO);
}finally {
try {
if(outputStream!=null){
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
修改后的代码
private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws Exception {
OutputStream outputStream=null;
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
//-------------重点------------
response.flushBuffer();
//--------------重点----------
outputStream = response.getOutputStream();
workbook.write(outputStream);
} catch (IOException e) {
throw new ServiceException(ResponseEnum.EXCEPTION_FILE_IO);
}finally {
try {
if(outputStream!=null){
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
请看注释"-----重点--------"部分
报错问题已解决
原因
log.info("### Request Args : {}", JacksonUtil.marshallToString(joinPoint.getArgs()));
在controller入参前和出参,都有做日志的打印,但是,是使用JacksonUtil.marshallToString,来解析的,再此解析过程中,会有报错“getWriter() has already been called for this response”产生
解决方案
通过判断,如果是导出或导入,则不做日志的拦截打印。