Easyexcel异常处理:getOutputStream() has already been called for this response
文章目录
- 异常日志
- 源码位置
- 异常原因
- 异常前代码
- 调整后代码
异常日志
java.lang.IllegalStateException: getOutputStream() has already been called for this responseat org.apache.catalina.connector.Response.getWriter(Response.java:582) ~[tomcat-embed-core-9.0.17.jar!/:9.0.17]at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:227) ~[tomcat-embed-core-9.0.17.jar!/:9.0.17]at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:152) ~[javax.servlet-api-3.1.0.jar!/:3.1.0]
源码位置
看起来是,output流使用标志生效导致异常。
异常原因
一句话总结:同一个请求中:调用了两次response.getOutputStream()方法。或者先进行了respose的头等信息设置后调用response.getOutputStream()
异常前代码
控制层:
@RequestMapping(value ="/detailExport" ,method = RequestMethod.POST)@BusiResponseBodypublic void detailExport(@RequestBody IdReqBO queryBO, HttpServletRequest request,HttpServletResponse response ) {//获取导出的元数据(转换器、格式控制器、导出内容等)ExcelExportContent excelExportContent = excelExportStrategy.exportDetailExcelContent(request.getRequestURI(), queryBO);EasyExcelUtils.ExportResponse(excelExportContent,response);}
工具类:
public class EasyExcelUtils {public static void ExportResponse(ExcelExportContent excelExportContent,HttpServletResponse response){try {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");String fileName = URLEncoder.encode(excelExportContent.getFileName(), "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");//这里先设置的response的头、编码等信息,导致response.getOutputStream()时异常ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(response.getOutputStream(), excelExportContent.getAccountDataClass()).registerConverter(new BigDecimalStringConverter()).registerConverter(new DateStringConverter());List<WriteHandler> writeHandler = excelExportContent.getWriteHandler();for (WriteHandler handler : writeHandler) {excelWriterBuilder.registerWriteHandler(handler);}excelWriterBuilder.sheet(excelExportContent.getSheetName()).doWrite(excelExportContent.getAccountData());} catch (Exception e){e.printStackTrace();throw new ZTBusinessException(e.getMessage());}}
}
调整后代码
控制层不变:
@RequestMapping(value ="/detailExport" ,method = RequestMethod.POST)@BusiResponseBodypublic void detailExport(@RequestBody IdReqBO queryBO, HttpServletRequest request,HttpServletResponse response ) {//获取导出的元数据(转换器、格式控制器、导出内容等),可忽略ExcelExportContent excelExportContent = excelExportStrategy.exportDetailExcelContent(request.getRequestURI(), queryBO);EasyExcelUtils.ExportResponse(excelExportContent,response);}
工具类:
这里格式化response的动作只能在response.getOutputStream()之后,在EasyExcel的doWrite之前。
在response.getOutputStream()之前会出现getOutputStream() has already been called for this response异常。在EasyExcel的doWrite之后,流已经被写回了,格式化response不会生效,写回的内容是txt格式。
public class EasyExcelUtils {protected static Logger logger = LoggerFactory.getLogger(EasyExcelUtils.class);public static void ExportResponse(ExcelExportContent excelExportContent, HttpServletResponse response) {try {ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(response.getOutputStream());//这里格式化response内容只能在这个位置FormatResponse(response, excelExportContent.getFileName());ExcelWriterSheetBuilder(excelWriterBuilder, excelExportContent).doWrite(excelExportContent.getDetailData());} catch (Exception e) {e.printStackTrace();throw new ZTBusinessException("ExportResponse exception:" + e.getMessage());}}public static void FormatResponse(HttpServletResponse response, String fileName) {try {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");String exportFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + exportFileName + ".xlsx");} catch (UnsupportedEncodingException e) {e.printStackTrace();throw new ZTBusinessException("FormatResponse exception:" + e.getMessage());}}private static ExcelWriterSheetBuilder ExcelWriterSheetBuilder(ExcelWriterBuilder excelWriterBuilder, ExcelExportContent excelExportContent) {List<Converter> converterList = Optional.ofNullable(excelExportContent.getConverter()).orElseGet(ArrayList::new);for (Converter converter : converterList) {excelWriterBuilder.registerConverter(converter);}List<WriteHandler> writeHandlerList = Optional.ofNullable(excelExportContent.getWriteHandler()).orElseGet(ArrayList::new);for (WriteHandler writeHandler : writeHandlerList) {excelWriterBuilder.registerWriteHandler(writeHandler);}ExcelWriterSheetBuilder excelWriterSheetBuilder = excelWriterBuilder.sheet(excelExportContent.getSheetName());return excelWriterSheetBuilder;}}
Easyexcel异常处理:getOutputStream() has already been called for this response相关推荐
- 解决getOutputStream() has already been called for this response[java io流]
getOutputStream() has already been called for this response 以上异常出现的原因和解决方法: jsp中出现此错误一般都是在jsp中使用了输出流 ...
- 解决java.lang.IllegalStateException: getOutputStream() has already been called for this response
简单的说:用了流之后关掉即可. 下面详细说明: 出现了java.lang.IllegalStateException: getOutputStream() has already been calle ...
- getOutputStream() has already been called for this response
错误日志里偶尔会有getOutputStream() has already been called for this response这个错误 最近发现了高概率复现条件,所以顺手解决了一下: 首先根 ...
- getOutputStream() has already been called for this response异常的原因和解决方法
今天在调试一个小web项目时,验证码不显示了,而且后台报错 getOutputStream() has already been called for this response 经过查找得知: 在t ...
- java.lang.IllegalStateException: getOutputStream() has already been called for this response
在做报表导出的时,导出报表后服务器提示: java.lang.IllegalStateException: getOutputStream() has already been called for ...
- tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法...
tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 [标 题]:tomcat5下js ...
- springboot中getOutputStream() has already been called for this response和java.io.FileNotFoundException
这个异常挺多人遇到的,不过我看了一下,跟我们的情况都不一样. 1. 流没关闭. 2. 未设置响应头. 3. jsp页面需要清空流. 说一下我们遇到的情况.就是一个简单的sprinbo ...
- getOutputStream() has already been called for this response异常的原因和解决方法[转]
1.在tomcat6.0下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 在tomcat6.0下j ...
- getOutputStream() has already been called for this response解释以及解决方法
getOutputStream() has already been called for this response解释以及解决方法 参考文章: (1)getOutputStream() has a ...
最新文章
- codeforces 293E Close Vertices 点分治+滑窗+treap
- C语言经典算法 11-20
- AudioManager播放音乐
- Google:推荐几款好用的Chrome浏览器插件
- c语言怎么输入3个数输出最大值
- MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))[MySQL插入内容超过4M]
- PRML笔记 第一章 Introduction
- 单例设计模式共享数据分析、解决,call_once
- picker.js源码
- PowerShell 学习笔记——文件系统
- PHP服务缓存加速软件
- Java的主流加密方式——简介
- Win7免费升级Win10
- 聚合物/硅胶色谱填粒径1.7μm到50μm
- c语言劝学,11劝学.doc
- 深入table之collapse
- Linux XAMP is currently only availably as 32 bit application.
- html5 ie7兼容性问题,解决浏览器IE6,IE7兼容性的总结
- 淘宝私域流量有哪些?怎么获取淘宝私域流量?
- 北京WIFI密码,很强大
热门文章
- 循环机换变速箱油教程_变速箱油用循环机换还是重力换更好?一次讲清楚,新手司机学学...
- 英雄联盟服务器维护3月17,英雄联盟将于3月17日凌晨2点开始进行全区停机维护...
- HTML字体小于12谷歌不兼容,Chrome谷歌浏览器下不支持css字体小于12px的解决办法...
- Python中的+=
- lex和yacc环境配置
- 【保存】maven的pom.xml标签的xsi:schemaLocation处报错
- INFINI GATEWAY 极限网关初体验 ElasticSearch 两个集群数据同步
- 场景模型驱动自动化测试在盒马的探索及实践
- 基于Topic消息路由的M2M设备间通信Node JS SDK 示例
- 如何抢占云栖大会C位?史上最强强强攻略来了