[异常]java.lang.IllegalStateException: Cannot forward after response has been committed 的完美解决 for nutz

大部分的java.lang.IllegalStateException: Cannot forward after response has been committed

异常都是由于response对象在执行完一次向客户端的写操作后,

response.iscommt()==true

再执行一次写操作就会报这个异常.

 

我这次是在使用nutz时遇到的,

其实在其他环境遇到也一样能解决,

版本是1.b.37-rc.jar

 

-------------------------------异常栈

 
java.lang.IllegalStateException: Cannot forward after response has been committed
 at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:312)
 at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
 at org.nutz.mvc.view.ForwardView.render(ForwardView.java:64)
 at org.nutz.mvc.impl.processor.ViewProcessor.process(ViewProcessor.java:35)
 at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
 at org.nutz.mvc.impl.processor.MethodInvokeProcessor.process(MethodInvokeProcessor.java:23)
 at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
 at org.nutz.mvc.impl.processor.AdaptorProcessor.process(AdaptorProcessor.java:33)
 at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
 at org.nutz.mvc.impl.processor.ActionFiltersProcessor.process(ActionFiltersProcessor.java:42)
 at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
 at org.nutz.mvc.impl.processor.ModuleProcessor.process(ModuleProcessor.java:76)
 at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
 at org.nutz.mvc.impl.processor.EncodingProcessor.process(EncodingProcessor.java:27)
 at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
 at org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor.process(UpdateRequestAttributesProcessor.java:15)
 at org.nutz.mvc.impl.NutActionChain.doChain(NutActionChain.java:36)
 at org.nutz.mvc.impl.ActionInvoker.invoke(ActionInvoker.java:66)
 at org.nutz.mvc.ActionHandler.handle(ActionHandler.java:30)
 at org.nutz.mvc.NutFilter.doFilter(NutFilter.java:66)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at cn.com.fanna.managercontroller.web.filter.XFilter.doFilter(XFilter.java:26)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
 at java.lang.Thread.run(Unknown Source)
log4j: 2011-06-17 15:43:46,671 [http-8080-2] DEBUG org.nutz.mvc.impl.UrlMappingImpl - find mapping [null] for path [/img]

 

-----------------------------------------------------

关键是在调用org.nutz.mvc.impl.processor.*processor的doNext()方法时,

调用了iscommit()为true的response对象造成的,

我们只要在这以环节,

判断下iscommt(),

如==true,什么都不干返回,

否则,进行下个next.process()

 

org.nutz.mvc.impl.processo.

AbstractProcessor.java  

是关键,它是其他processors的超类,

所有就改它就可以了

代码:

关键代码:

 /**
  * 继续执行下一个Processor
  * <p/><b>一般情形下都不应该覆盖这个方法<b>
  * @param ac 执行方法的上下文
  * @throws Throwable
  */
 protected void doNext(ActionContext ac) throws Throwable {
  if(ac!=null&&ac.getResponse()!=null&&(!ac.getResponse().isCommitted())){  //就加这个判断就好了
   if (null != next)
    next.process(ac);
  }
  
 }

全部代码:

 

 

好了,将这个类单独编译出来,放到nutz的jar包中去,就可以了.

 

-------------------------------------------------------------------

Thinking:

之后问了nutz的作者兽哥,它说就不该让doNext有机会执行,

再次查看异常栈,

发现直接可以在

NutFilter.java做文章,

也就是nutz的启动类,

手段是一样的,

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain){}

方法中判断resp的isCommit()状态,做相应修改,应该是这个样子吧

 

 

 

 

 

 

ok ,这样一来,如果response被提交,直接让容器执行其它filter,

离开nutz的范围,与nutz无关了.

 

 

还是要感谢nutz的所有贡献者,让我学到了这个有趣的东西,

尤其是兽哥,每天在qq群里解答大家的各种疑问,

再次膜拜下你们.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值