Java 使用deferredResult时提交响应后无法转发
为了实现长轮询,我尝试了不同的解决方案,但没有得到任何好的结果 所以我决定研究异步方法和延迟结果。 在这里,我实现了Java 使用deferredResult时提交响应后无法转发,java,spring-mvc,Java,Spring Mvc,为了实现长轮询,我尝试了不同的解决方案,但没有得到任何好的结果 所以我决定研究异步方法和延迟结果。 在这里,我实现了RESTconstroller @Controller("sessionStateRest") @RequestMapping("ui") public class SessionStateRest extends BaseRestResource { private final Queue<DeferredResult<ModelAndView>>
REST
constroller
@Controller("sessionStateRest")
@RequestMapping("ui")
public class SessionStateRest extends BaseRestResource {
private final Queue<DeferredResult<ModelAndView>> mavQueue = new ConcurrentLinkedQueue<>();
/**
* Rest to check session state.
*
* @return string with session state
*/
@RequestMapping(value = "/session")
public @ResponseBody DeferredResult<ModelAndView> sessionState() {
final DeferredResult<ModelAndView> stateResult = new DeferredResult<>();
this.mavQueue.add(stateResult);
return stateResult;
}
@Scheduled(fixedDelay = 5000)
public void processQueue() {
for(DeferredResult<ModelAndView> result: mavQueue) {
if (null == SecurityHelper.getUserLogin()) {
result.setResult(createSuccessResponse("Invalidated session"));
mavQueue.remove(result);
}
}
}
}
但过了一段时间,我有一个例外
java.lang.IllegalStateException: Cannot forward after response has been committed
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:349) ~[tomcat-embed-core-7.0.
39.jar:7.0.39]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339) ~[tomcat-embed-core-7.0.39
.jar:7.0.39]
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:467) [tomcat-embed-core-7.0.39.jar:7.0.3
9]
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:338) [tomcat-embed-core-7.0.39.jar:7.0.3
9]
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:428) [tomcat-embed-core-7.0.39.jar:7.
0.39]
at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:417) [tomcat-embed-core-7.0.39.jar:
7.0.39]
at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:294) [tomcat-embed-core-7.0.39.jar:7
.0.39]
at org.apache.coyote.http11.AbstractHttp11Processor.asyncDispatch(AbstractHttp11Processor.java:1567) [tomcat-embed-c
ore-7.0.39.jar:7.0.39]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:583) [tomcat-embed-cor
e-7.0.39.jar:7.0.39]
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) [tomcat-embed-core-7.0.39.jar:7.
0.39]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_67]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_67]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_67]
有什么问题吗?我是否应该设置延迟结果的超时时间?我认为问题来自
@ResponseBody
注释。它告诉Spring控制器方法将直接返回响应体。但它没有,因为它返回一个ModelAndView
。因此Spring尝试将方法的返回直接发送到客户端(并且应该发送并提交一个空响应),然后ModelAndView处理程序尝试转发到一个已经提交了响应的视图,从而导致错误
您至少应该删除@ResponseBody
注释,因为它不是同步等价物
但这还不是全部:
- 您编写的
最终延迟结果没有任何更改。我还发现它似乎不符合
。至少在debug中,它没有进入该方法。processQueue
configuration出现问题您应该首先让它在没有xml
的情况下工作,然后再尝试添加它。我不明白这段代码能做什么。。。我不确定斯普林是否能理解其中哪一个更糟糕;-)@SergeBallesta我无法通过异步调用找到解决方案,我的意思是首先让它工作synchonously@SergeBallesta,但这很简单-毕竟我只需要做一些基本的事情,比如在我所有的控制器中-获取DeferredResult
并查看。我甚至在一些控制器中检查SecurityHelper
是否为null,并返回一些与login
用户对应的响应。您可能知道上面的同步工作版本是什么,但我不知道。我看到的是,您有一个null
注释,并且您使用的@ResponseBody
类型结果似乎不一致。但是我猜不出哪个是对的,同步版本应该返回什么。。。model和view
java.lang.IllegalStateException: Cannot forward after response has been committed at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:349) ~[tomcat-embed-core-7.0. 39.jar:7.0.39] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339) ~[tomcat-embed-core-7.0.39 .jar:7.0.39] at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:467) [tomcat-embed-core-7.0.39.jar:7.0.3 9] at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:338) [tomcat-embed-core-7.0.39.jar:7.0.3 9] at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:428) [tomcat-embed-core-7.0.39.jar:7. 0.39] at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:417) [tomcat-embed-core-7.0.39.jar: 7.0.39] at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:294) [tomcat-embed-core-7.0.39.jar:7 .0.39] at org.apache.coyote.http11.AbstractHttp11Processor.asyncDispatch(AbstractHttp11Processor.java:1567) [tomcat-embed-c ore-7.0.39.jar:7.0.39] at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:583) [tomcat-embed-cor e-7.0.39.jar:7.0.39] at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) [tomcat-embed-core-7.0.39.jar:7. 0.39] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_67] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_67] at java.lang.Thread.run(Thread.java:745) [na:1.7.0_67]