前言
- 在做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的开发规范,具体细节只能考虑参看源码分析了,后续查询相关资料再来补充