getOutputStream() has already been called for this response的理解

2/22/2017来源:ASP.NET技巧人气:2183

前言
在做Excel导出的时候,使用到了response.getOutputStream(),然后在sPRingmvc的方法中return了一个jsp视图路径出去,导致这个错误。 getOutputStream()是以字节流的方式写出数据 浏览器得有对应的编码表来把字节流解析为字符 而如果又实用getWriter()来以字符的形式写出, 编码变冲突。。所有规范两者不能同时使用
分析
我们都知道jsp的内置对象有一个out,它是通过PageContext.getOut()来获取的,而在j2ee的开发api文档中写有 Calling flush() on the ServletOutputStream commits the response. Either this method or getWriter() may be called to write the body, not both. 调用flush()方法会提交response流,getWriter()和getOutPutStream()两者只能被调用一个
原因
两个流使用的是同一个缓冲区,当缓冲区满后 才会被写出(或手动调用flush写出) 在编译后的jsp类中,有一句: if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);} 释放时会调用response.getWriter()

如果流没有关闭 tomcat会自动关闭,但也提倡手动关闭流,遵循j2ee的开发规范,具体细节只能考虑参看源码分析了,后续查询相关资料再来补充