如何修复“getOutputStream() 已为此响应调用”
Posted
技术标签:
【中文标题】如何修复“getOutputStream() 已为此响应调用”【英文标题】:how to fix "getOutputStream() has already been called for this response" 【发布时间】:2019-10-10 01:58:42 【问题描述】:当我想将数据从数据库导出到 Excel 文件时,我收到以下异常“java.lang.IllegalStateException:getOutputStream() 已为此响应调用”。
/**** 服务****/
@Component("articleExporter")
public class ArticleExporter implements FileExporter
@Autowired
private IArticleService articleService;
private static final String FILE_NAME="Liste des articles";
@Override
public boolean exportDataToExcel(HttpServletResponse response, String filename, String encodage)
if(org.apache.commons.lang3.StringUtils.isEmpty(filename))
filename=FILE_NAME;
if(StringUtils.isEmpty(encodage))
encodage=ApplicationConstants.DEFAULT_ENCODAGE;
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename="+ filename +".xls");
WorkbookSettings workbookSettings = new WorkbookSettings();
workbookSettings.setEncoding("ISO-8859-1");
try
WritableWorkbook workbook = Workbook.createWorkbook(response.getOutputStream(), workbookSettings);
WritableSheet sheet = workbook.createSheet(filename, 0);
/**
* Header of the table
* */
Label labelRubrique = new Label(0, 0, ApplicationConstants.RUBRIQUE);
labelRubrique.setCellFeatures(new WritableCellFeatures());
labelRubrique.getCellFeatures().setComment("");
sheet.addCell(labelRubrique);
Label labelFournisseur = new Label(1, 0, ApplicationConstants.FOURNISSEUR);
labelFournisseur.setCellFeatures(new WritableCellFeatures());
labelFournisseur.getCellFeatures().setComment("");
sheet.addCell(labelFournisseur);
Label labelcode = new Label(2, 0, ApplicationConstants.CODE);
labelcode.setCellFeatures(new WritableCellFeatures());
labelcode.getCellFeatures().setComment("");
sheet.addCell(labelcode);
Label labelReference = new Label(3, 0, ApplicationConstants.REFRENCE);
labelReference.setCellFeatures(new WritableCellFeatures());
labelReference.getCellFeatures().setComment("");
sheet.addCell(labelReference);
Label labelReferenceProtronic = new Label(4, 0, ApplicationConstants.REFERENCE_PROTRONIC);
labelReferenceProtronic.setCellFeatures(new WritableCellFeatures());
labelReferenceProtronic.getCellFeatures().setComment("");
sheet.addCell(labelReferenceProtronic);
Label labelDesignationL = new Label(5, 0, ApplicationConstants.DESIGNATION_L);
labelDesignationL.setCellFeatures(new WritableCellFeatures());
labelDesignationL.getCellFeatures().setComment("");
sheet.addCell(labelDesignationL);
Label labelDesignationC = new Label(6, 0, ApplicationConstants.DESIGNATION_C);
labelDesignationC.setCellFeatures(new WritableCellFeatures());
labelDesignationC.getCellFeatures().setComment("");
sheet.addCell(labelDesignationC);
Label labelPrixUnitaireHT = new Label(7, 0, ApplicationConstants.PRIX_UNIT_HT);
labelPrixUnitaireHT.setCellFeatures(new WritableCellFeatures());
labelPrixUnitaireHT.getCellFeatures().setComment("");
sheet.addCell(labelPrixUnitaireHT);
Label labelQuantite = new Label(8, 0, ApplicationConstants.QUANTITE);
labelQuantite.setCellFeatures(new WritableCellFeatures());
labelQuantite.getCellFeatures().setComment("");
sheet.addCell(labelQuantite);
Label labelPrixUnitaireTTC = new Label(9, 0, ApplicationConstants.PRIX_UNIT_TTC);
labelPrixUnitaireTTC.setCellFeatures(new WritableCellFeatures());
labelPrixUnitaireTTC.getCellFeatures().setComment("");
sheet.addCell(labelPrixUnitaireTTC);
Label labelTauxTVA = new Label(10, 0, ApplicationConstants.TAUX_TVA);
labelTauxTVA.setCellFeatures(new WritableCellFeatures());
labelTauxTVA.getCellFeatures().setComment("");
sheet.addCell(labelTauxTVA);
int currentRow =1;
List<Article> listArticles = articleService.selectAll();
if(/*listArticles !=null &*/ !listArticles.isEmpty())
/**
* Writing in the sheet
*/
for (Article article : listArticles)
sheet.addCell(new Label(0,currentRow,article.getRubrique().getDesignation()));
sheet.addCell(new Label(1,currentRow,article.getFournisseur().getNomFournisseur()));
sheet.addCell(new Label(2,currentRow,article.getCodeArt()));
sheet.addCell(new Label(3,currentRow,article.getRefArt()));
sheet.addCell(new Label(4,currentRow,article.getRefArtPro()));
sheet.addCell(new Label(5,currentRow,article.getDesignationL()));
sheet.addCell(new Label(6,currentRow,article.getDesignationC()));
sheet.addCell(new Label(7,currentRow,article.getPrixUnitaireHT().toString()));
sheet.addCell(new Label(8,currentRow,article.getQuantite().toString()));
sheet.addCell(new Label(9,currentRow,article.getPrixUnitaireTTC().toString()));
sheet.addCell(new Label(10,currentRow,article.getTauxTva().toString()));
currentRow++;
CellView cellView= new CellView();
cellView.setAutosize(true);
//cellView.setSize(600);
sheet.setColumnView(0, cellView);
sheet.setColumnView(1, cellView);
sheet.setColumnView(2, cellView);
sheet.setColumnView(3, cellView);
sheet.setColumnView(4, cellView);
sheet.setColumnView(5, cellView);
sheet.setColumnView(6, cellView);
sheet.setColumnView(7, cellView);
sheet.setColumnView(8, cellView);
sheet.setColumnView(9, cellView);
sheet.setColumnView(10, cellView);
/**
* Write to excel sheet
*/
workbook.write();
/**
* Closing the workbook
*/
workbook.close();
response.getOutputStream().flush();
response.getOutputStream().close();
return true;
catch(Exception e)
e.printStackTrace();
return false;
/* the controller */
@RequestMapping(value="/export/")
public String ExportArticles(HttpServletResponse response)
exporter.exportDataToExcel(response, null, null);
return "article/article";
/* 错误 */
java.lang.IllegalStateException: "getOutputStream()" 似曾相识 在 org.apache.catalina.connector.Response.getWriter(Response.java:582) 在 org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:227) 在 org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:115) 在 org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:108) 在 org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:179) 在 org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:120) 在 org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75) 在 org.apache.jsp.WEB_002dINF.views.article.article_jsp._jspService(article_jsp.java:406) 在 org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:741) 在 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476) 在 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385) 在 org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:741) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) 在 org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459) 在 org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384) 在 org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) 在 org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238) 在 org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262) 在 org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1180) 在 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:950) 在 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 在 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 在 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:634) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:741) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) 在 org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) 在 org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) 在 org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 在 org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) 在 org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(Unknown Source)
【问题讨论】:
【参考方案1】:当你打电话给workbook.write(); workbook.close();
时,它已经在做
response.getOutputStream().flush();
response.getOutputStream().close();
所以抛出异常,去掉那几行就OK了。
【讨论】:
我试图删除那两行,但问题仍然存在,抛出异常。【参考方案2】:似乎错误是从 Catalina (Tomcat) 内部引发的。我假设 Catalina 尝试刷新并关闭响应的输出流本身,但您已经关闭了它。
如果您删除了 response.getOutputStream().close();
调用和 workbook.close;
调用,那么它是否可以工作,从而让输出流打开以便 catalina 刷新和关闭?
【讨论】:
我也试过了,但还是抛出了异常。以上是关于如何修复“getOutputStream() 已为此响应调用”的主要内容,如果未能解决你的问题,请参考以下文章