这里的场景:我正在使用Struts2处理应用程序的新功能,并添加了一个新操作来生成CSV文件。使用Tomcat在我的测试系统上一切正常,但在使用Websphere服务器的Quality系统上,文件还可以,但最后还有一行,包括
Error 500: java.lang.IllegalStateException: Response already committed.
所以问题是,生成文件并且一切都很完美,但是Tomcat没有附加错误,Websphere会附加错误。
那我怎么能避免这个呢? 这里是主要过程(重要的行):
1-该操作扩展了执行转发的org.apache.struts2.s1.Struts1Action:
ActionForward forward = action.execute(mapping, actionForm, request, response);
2-执行操作中的方法,并使用以下行生成响应:
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=\"report_"
+ Calendar.getInstance().get(Calendar.YEAR) + ".csv\"");
OutputStream outputStream = response.getOutputStream();
outputStream.write(result.toString().getBytes());
outputStream.flush();
outputStream.close();
3-父动作完成了这件事。在某些时候,我得到了这个例外,但它从来没有让我们担心(我们已经生成了其他类型的Excel报告(xls),但是从来没有通过websphere将此错误附加到响应中):
java.lang.IllegalStateException:getOutputStream() has already been called for this response
所以真正让我感到奇怪的是如何避免websphere将错误附加到csv文件......当然解决方案应该是避免错误,但问题是这个应用程序已经运行了10年而我不应该改变已经有效的东西,但欢迎任何解决这个错误的方法!!
非常感谢你们!
--- ---编辑
我真正想知道的是,我怎样才能生成带有文本文件的响应,并且之后仍然可以执行所有转发和操作。
有什么想法吗?
答案 0 :(得分:1)
试图给你一些想法......希望以下内容有意义......
首先,根据此source java.lang.IllegalStateException:getOutputStream()
的原因是
简而言之,当您调用include()或forward()时会出现此错误 提交响应或调用后的方法 响应对象上的getOutputStream()
Here是struts1下载实现的一个例子(据我所知,你正在为struts2使用struts1插件)。我们看到execute
方法以return null;
所以,可能是,在您从帖子中省略的代码中,有一些转发正在进行,这会导致异常。
答案 1 :(得分:0)
嗯,我实际上找到了问题的解决方案,可能不是解决方案本身,而是解决方法。
所以问题是websphere附加了错误,因为Response
内容只是一个字符串。
所以我所做的是将响应生成为ByteArray而不是String,这样websphere就不能将任何内容作为简单文本附加,而且ByteStream是封闭且安全的。
byte[] data = result.toString().getBytes();
ByteArrayOutputStream outStream = new ByteArrayOutputStream(data.length);
outStream.write(data, 0, data.length);
response.setContentType("text/csv" + "; charset=UTF-8");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
response.setHeader("Content-Disposition", "attachment; filename=\"report_"
+ Calendar.getInstance().get(Calendar.YEAR) + ".csv\"");
response.setContentLength(outStream.size());
ServletOutputStream responseOutStream = response.getOutputStream();
outStream.writeTo(responseOutStream);
outStream.flush();
outStream.close();
responseOutStream.flush();
responseOutStream.close();
如果我没有充分解释,欢迎任何编辑,建议或解释!