错误信息
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:678)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:194)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:126)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)
at org.apache.jsp.export_jsp._jspService(export_jsp.java:566)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
分析问题
其实就是JSP 和Servlet 的输出response.getOutputStream().write,调用两次。首先在页面请求URL时进入控制层程序时,你使用了 response.getOutputStream().write()输出方法,
然后在执行完程序时,你在控制层程序中又一次执行了返回值,那么一个请求方法同时使用了两次response.getOutputStream().write()输出方法。
其实就是因为 JSP 中同时用了 response.getOutputStream() 以及 JSP 内置对象 out.write().因为Serlvet 规范中不能同时使用这两个。只能选其中一个。
所以解决方案
第一种解决方案,在前端重置请求,输出缓存清空一下
<%
// 同时 reset response 和 清空 out
response.reset();
out.clear();
out = pageContext.pushBody();
%>
第二钟方式
@RequestMapping(value="/download",method=RequestMethod.GET)
public String downloadFile() throws IOException{
return "url";
}
把上面的代码改成返回值为空,那么在方法代码块中执行的response.getOutputStream() 就只有一次。就不会报相关异常了
@RequestMapping(value="/download",method=RequestMethod.GET)
public void downloadFile() throws IOException{
执行代码块
}
说得不是很好,需要很好理解的话,请去看相关源码