最近在项目中遇到这样一个奇怪的问题:
在页面上输入数据,点击submit按钮,程序跑到后台,然后什么都不做,直接返回到本画面。
画面上根据先前输入的数据生成自定义Tag。Tag会做一些业务判断,然后自动跳转到其他画面。
现在的问题是,在往其他画面跳的时候,老是报Cannot Forward a Response that is Already Committed
这个异常。
最后测试发现,几乎所有的服务器都有这个问题。就是在JSP页面上,当输出的字节数
超过8K(tomcate)/12K(weblogic)的时候,response.isCommitted()就变成了true,这个时侯就没法再
跳转了。
现在我想知道的是,这种限制是JSP页面特意的限制吗?谁能给一个正式的解释。
[b]问题补充:[/b]
谢谢各位的帮助,现在已经基本上知道深层的原因了。
主要是JSP页面在编译为HTML时,服务器不是直接往客户端浏览器写出,而是首先生成一个缓冲区。这个缓冲区的大小根据服务器的不同而不同,tomcate为8KB。当生成的HTML太大,超过缓冲区大小的时候,服务器就会向客户端写出,这个时候response的状态就会变为committed,就不能再往其他画面跳转了。因此,如果想实现在JSP页面上进行跳转,有两种途径:
1.在默认缓冲区写满之前跳转
2.修改缓冲区大小,使跳转动作发生在缓冲区写满之前
对于第二种途径,只要在进入JSP页面之后,立刻调用response.setBufferSize(int size)就可以了。保险起见,可将大小设为JSP编译后生成的HTML的大小。
TO:gembler
我们这个画面是一个测试工具画面,主要用来测试项目的自定义Tag。其中一个Tag有页面跳转逻辑,所以才会出这种问题。至于为什么跳转逻辑要放到Tag中,就不太清楚了。
这个是因为缓冲区大小的限制吧,setBufferSize()可以设置缓冲区大小,这个大小默认应该是8192,至于weblogic可能自己在实现web容器的时候,扩大了一些。
从规范角度来说, 输出后就不允许跳转的。 不然, 用户接收到数据, 你说他怎么处理好, 是显示好呢, 还是跳转好?
感觉使用有误,与业务有关的东西放到页面上来判断?干嘛不在action/servlet里做呢?
这个问题的根本原因由于响应本次请求的Response对象的状态是已提交状态造成的,它不允许响应提交多次。
如果已经提交了响应,你仍然试图再次进行页面跳转,即再次提交响应,就可能出现问题.