[异常]java.lang.IllegalStateException: Cannot forward after response has been committed 的完美解决 for nutz
2011-06-17 16:38
597 查看
大部分的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群里解答大家的各种疑问,
再次膜拜下你们.
异常都是由于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);
}
}
全部代码:
package org.nutz.mvc.impl.processor; import org.nutz.mvc.ActionContext; import org.nutz.mvc.ActionInfo; import org.nutz.mvc.NutConfig; import org.nutz.mvc.ObjectInfo; import org.nutz.mvc.Processor; import org.nutz.mvc.impl.Loadings; /** * 抽象的Processor实现. 任何Processor实现都应该继承这个类,以获取正确的执行逻辑. * <p/> * @author zozoh(zozohtnt@gmail.com) * @author wendal(wendal1985@gmail.com) * */ public abstract class AbstractProcessor implements Processor { private Processor next; /** * 建议覆盖这个方法,以便从NutConfig/ActionInfo获取需要的信息 */ public void init(NutConfig config, ActionInfo ai) throws Throwable { } /** * 设置下一个Processor * <p/><b>一般情形下都不应该覆盖这个方法<b> * @param next 下一个Processor,一般不为null */ public void setNext(Processor next) { this.next = next; } /** * 继续执行下一个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); } } protected static <T> T evalObj(NutConfig config, ObjectInfo<T> info) { return null == info ? null : Loadings.evalObj(config, info.getType(), info.getArgs()); } }
好了,将这个类单独编译出来,放到nutz的jar包中去,就可以了.
-------------------------------------------------------------------
Thinking:
之后问了nutz的作者兽哥,它说就不该让doNext有机会执行,
再次查看异常栈,
发现直接可以在
NutFilter.java做文章,
也就是nutz的启动类,
手段是一样的,
在
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain){}
方法中判断resp的isCommit()状态,做相应修改,应该是这个样子吧
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { if (!skipMode&&(!resp.isCommitted())) { RequestPath path = Mvcs.getRequestPathObject((HttpServletRequest) req); if (null == ignorePtn || !ignorePtn.matcher(path.getUrl()).find()) { if (handler.handle((HttpServletRequest) req, (HttpServletResponse) resp)) return; } } // 如果已经找到对应的action,而且正确处理,并且不是donext模式,那么不会走到这里 //更新 Request 必要的属性 Mvcs.updateRequestAttributes((HttpServletRequest) req); // 本过滤器没有找到入口函数,继续其他的过滤器 chain.doFilter(req, resp); }
ok ,这样一来,如果response被提交,直接让容器执行其它filter,
离开nutz的范围,与nutz无关了.
还是要感谢nutz的所有贡献者,让我学到了这个有趣的东西,
尤其是兽哥,每天在qq群里解答大家的各种疑问,
再次膜拜下你们.
相关文章推荐
- java.lang.IllegalStateException: Cannot forward after response has been committed异常
- java.lang.IllegalStateException: Cannot forward after response has been committed问题的解决
- java.lang.IllegalStateException: Cannot forward after response has been committed几个解决方法
- java.lang.IllegalStateException: Cannot forward after response has been committed的一个情况解决方法
- 异常——(2)java.lang.IllegalStateException: Cannot forward after response has been committed
- Servlet异常:java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been comm 解决办法
- java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed错误问题
- java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed
- Java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed
- java.lang.IllegalStateException: Cannot forward after response has been committed
- nested exception is java.lang.IllegalStateException: Cannot forward after response has been committed