Websphere 将错误附加到响应
Websphere appending error to response
此处场景:我正在使用 Struts2 在应用程序上开发新功能,并且我添加了一个新操作来生成 CSV 文件。在我的 Tomcat 测试系统上一切正常,但在带有 Websphere 服务器的质量系统上,文件没问题,但最后,有一个额外的行,包括
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 年了,我不应该改变已经有效的东西,但是欢迎任何解决这个错误的方法!!
非常感谢你们!!
---编辑---
我真正想知道的是,我怎样才能用文本文件生成响应,并且之后仍然能够进行所有转发和其他操作。
有什么想法吗?
只是想给你一些想法...希望以下内容有意义...
首先根据这个sourcejava.lang.IllegalStateException:getOutputStream()
的原因是
In short, this error comes when you call the include() or forward()
method after committing the response or by calling the
getOutputStream() on the response object
Here 是 struts1 下载实现的示例(据我了解,您正在为 struts2 使用 struts1 插件)。我们看到 execute
方法以 return null;
结尾
所以,可能是,在您从 post 中省略的代码中,正在进行一些转发,这会导致您出现异常。
好吧,我实际上找到了解决问题的方法,也许不是解决方法本身,而是一种变通方法。
所以问题是 websphere 附加了错误,因为 Response
内容只是一个字符串。
所以我所做的是将响应生成为 ByteArray,而不是字符串,这样 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();
如果我解释得不够好,欢迎任何编辑、建议或解释!!
此处场景:我正在使用 Struts2 在应用程序上开发新功能,并且我添加了一个新操作来生成 CSV 文件。在我的 Tomcat 测试系统上一切正常,但在带有 Websphere 服务器的质量系统上,文件没问题,但最后,有一个额外的行,包括
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 年了,我不应该改变已经有效的东西,但是欢迎任何解决这个错误的方法!!
非常感谢你们!!
---编辑---
我真正想知道的是,我怎样才能用文本文件生成响应,并且之后仍然能够进行所有转发和其他操作。
有什么想法吗?
只是想给你一些想法...希望以下内容有意义...
首先根据这个sourcejava.lang.IllegalStateException:getOutputStream()
的原因是
In short, this error comes when you call the include() or forward() method after committing the response or by calling the getOutputStream() on the response object
Here 是 struts1 下载实现的示例(据我了解,您正在为 struts2 使用 struts1 插件)。我们看到 execute
方法以 return null;
所以,可能是,在您从 post 中省略的代码中,正在进行一些转发,这会导致您出现异常。
好吧,我实际上找到了解决问题的方法,也许不是解决方法本身,而是一种变通方法。
所以问题是 websphere 附加了错误,因为 Response
内容只是一个字符串。
所以我所做的是将响应生成为 ByteArray,而不是字符串,这样 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();
如果我解释得不够好,欢迎任何编辑、建议或解释!!