文章目录

  • 异常日志
  • 源码位置
  • 异常原因
  • 异常前代码
  • 调整后代码

异常日志

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相关推荐

  1. 解决getOutputStream() has already been called for this response[java io流]

    getOutputStream() has already been called for this response 以上异常出现的原因和解决方法: jsp中出现此错误一般都是在jsp中使用了输出流 ...

  2. 解决java.lang.IllegalStateException: getOutputStream() has already been called for this response

    简单的说:用了流之后关掉即可. 下面详细说明: 出现了java.lang.IllegalStateException: getOutputStream() has already been calle ...

  3. getOutputStream() has already been called for this response

    错误日志里偶尔会有getOutputStream() has already been called for this response这个错误 最近发现了高概率复现条件,所以顺手解决了一下: 首先根 ...

  4. getOutputStream() has already been called for this response异常的原因和解决方法

    今天在调试一个小web项目时,验证码不显示了,而且后台报错 getOutputStream() has already been called for this response 经过查找得知: 在t ...

  5. java.lang.IllegalStateException: getOutputStream() has already been called for this response

    在做报表导出的时,导出报表后服务器提示: java.lang.IllegalStateException: getOutputStream() has already been called for ...

  6. tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法...

    tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 [标  题]:tomcat5下js ...

  7. springboot中getOutputStream() has already been called for this response和java.io.FileNotFoundException

    这个异常挺多人遇到的,不过我看了一下,跟我们的情况都不一样. 1.    流没关闭. 2.    未设置响应头. 3.    jsp页面需要清空流. 说一下我们遇到的情况.就是一个简单的sprinbo ...

  8. getOutputStream() has already been called for this response异常的原因和解决方法[转]

    1.在tomcat6.0下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 在tomcat6.0下j ...

  9. getOutputStream() has already been called for this response解释以及解决方法

    getOutputStream() has already been called for this response解释以及解决方法 参考文章: (1)getOutputStream() has a ...

最新文章

  1. codeforces 293E Close Vertices 点分治+滑窗+treap
  2. C语言经典算法 11-20
  3. AudioManager播放音乐
  4. Google:推荐几款好用的Chrome浏览器插件
  5. c语言怎么输入3个数输出最大值
  6. MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))[MySQL插入内容超过4M]
  7. PRML笔记 第一章 Introduction
  8. 单例设计模式共享数据分析、解决,call_once
  9. picker.js源码
  10. PowerShell 学习笔记——文件系统
  11. PHP服务缓存加速软件
  12. Java的主流加密方式——简介
  13. Win7免费升级Win10
  14. 聚合物/硅胶色谱填粒径1.7μm到50μm
  15. c语言劝学,11劝学.doc
  16. 深入table之collapse
  17. Linux XAMP is currently only availably as 32 bit application.
  18. html5 ie7兼容性问题,解决浏览器IE6,IE7兼容性的总结
  19. 淘宝私域流量有哪些?怎么获取淘宝私域流量?
  20. 北京WIFI密码,很强大

热门文章

  1. 循环机换变速箱油教程_变速箱油用循环机换还是重力换更好?一次讲清楚,新手司机学学...
  2. 英雄联盟服务器维护3月17,英雄联盟将于3月17日凌晨2点开始进行全区停机维护...
  3. HTML字体小于12谷歌不兼容,Chrome谷歌浏览器下不支持css字体小于12px的解决办法...
  4. Python中的+=
  5. lex和yacc环境配置
  6. 【保存】maven的pom.xml标签的xsi:schemaLocation处报错
  7. INFINI GATEWAY 极限网关初体验 ElasticSearch 两个集群数据同步
  8. 场景模型驱动自动化测试在盒马的探索及实践
  9. 基于Topic消息路由的M2M设备间通信Node JS SDK 示例
  10. 如何抢占云栖大会C位?史上最强强强攻略来了