说明:<jsp:include page="a.jsp">标签,只能嵌套一个实体页面,不能嵌套一个Servlet请求;如果嵌套一个Servlet请求,可能后台报Stream closed错误。
如果该标签引用一个Servlet请求,如<jsp:include page="aAction.do?method=test" />时,后台报错如下:
java.io.IOException: Stream closed
at org.apache.jasper.runtime.JspWriterImpl.ensureOpen(JspWriterImpl.java:204)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:115)
at org.apache.jasper.runtime.JspWriterImpl.flush(JspWriterImpl.java:173)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:956)
at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:621)
..
这是因为jsp在提交第一次请求时,已将流关闭,再次发送请求时,导致该错误。
如果在<jsp:include>标签中指定 flush="true" 属性时,报错如下:java.lang.IllegalStateException: Response already committed,同理,当指定flush="true"时,当JSPWriter对象执行flush缓存的时候,不是同一个response对象,抛出该异常。
如果页面需要include一个Servlet请求时,可以使用JSTL标签中的<C:import src="aAciton.do?method=test"/>替换。
注:我在项目当中,遇到该问题,查看tomcat work下该jsp页面对应转换后的java文件源码,发现在执行该include请求时,抛出异常,在catch异常中,对out流执行必要操作时,抛出该异常。调试代码时,发现JspRuntimeLibrary执行include方法时,入参out中的closed参数值为true,抛出异常,一直纠结:为什么开始out对象中的closed=true呢,而只有在out关闭流时才将closed属性值从false修改为true。在百度时,极大部分是问题描述和部分不清楚的解答。考虑到问题易出现,而答案不易搜索,特写此文,防止大家出现雷同错误。