CAS No flow execution could be found with key 'e2s1' 问题
在使用jasig-cas
构建的单点登录系统中,遇到一个错误,表象是提交登录表单时,前端表现为刷新一次页面,实际是后端提交POST
请求时,发生了一个错误:
org.springframework.webflow.execution.repository.NoSuchFlowExecutionException: No flow execution could be found with key 'e2s1' -- perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.
at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getConversation(AbstractFlowExecutionRepository.java:172)
at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getLock(AbstractFlowExecutionRepository.java:125)
at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:167)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter2.handle(FlowHandlerAdapter2.java:186)
at org.jasig.cas.web.flow.SelectiveFlowHandlerAdapter2.handle(SelectiveFlowHandlerAdapter2.java:69)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:933)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:867)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.jasig.cas.web.init.SafeDispatcherServlet.service_aroundBody2(SafeDispatcherServlet.java:125)
at org.jasig.cas.web.init.SafeDispatcherServlet.service_aroundBody3$advice(SafeDispatcherServlet.java:54)
at org.jasig.cas.web.init.SafeDispatcherServlet.service(SafeDispatcherServlet.java:1)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1496)
at org.jasig.cas.security.RequestParameterPolicyEnforcementFilter.doFilter(RequestParameterPolicyEnforcementFilter.java:296)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1484)
at com.github.inspektr.common.web.ClientInfoThreadLocalFilter.doFilter(ClientInfoThreadLocalFilter.java:63)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1484)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1476)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '2' -- perhaps this conversation has ended?
at org.springframework.webflow.conversation.impl.ConversationContainer.getConversation(ConversationContainer.java:134)
at org.springframework.webflow.conversation.impl.SessionBindingConversationManager.getConversation(SessionBindingConversationManager.java:116)
at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getConversation(AbstractFlowExecutionRepository.java:183)
at org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository.getConversation(AbstractFlowExecutionRepository.java:170)
... 49 more
由于是偶然出现,时灵时不灵的,跟踪难度很大,通过研究相应代码:
// org.springframework.webflow.mvc.servlet.FlowHandlerAdapter
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
FlowHandler flowHandler = (FlowHandler) handler;
checkAndPrepare(request, response, false);
// 从请求参数中获取`execution`参数值
String flowExecutionKey = flowUrlHandler.getFlowExecutionKey(request);
if (flowExecutionKey != null) {
try {
ServletExternalContext context = createServletExternalContext(request, response);
// 恢复`execution`值(NULL),报错点
FlowExecutionResult result = flowExecutor.resumeExecution(flowExecutionKey, context);
handleFlowExecutionResult(result, context, request, response, flowHandler);
} catch (FlowException e) {
e.printStackTrace();
handleFlowException(e, request, response, flowHandler);
}
} else {
try {
String flowId = getFlowId(flowHandler, request);
MutableAttributeMap input = getInputMap(flowHandler, request);
ServletExternalContext context = createServletExternalContext(request, response);
// 创建execution[e1s1]
FlowExecutionResult result = flowExecutor.launchExecution(flowId, input, context);
handleFlowExecutionResult(result, context, request, response, flowHandler);
} catch (FlowException e) {
handleFlowException(e, request, response, flowHandler);
}
}
return null;
}
跟踪内部代码找到相应代码
// org.springframework.webflow.execution.repository.support.AbstractFlowExecutionRepository
public FlowExecutionResult resumeExecution(String flowExecutionKey, ExternalContext context) throws FlowException {
try {
if (logger.isDebugEnabled()) {
logger.debug("Resuming flow execution with key '" + flowExecutionKey);
}
ExternalContextHolder.setExternalContext(context);
FlowExecutionKey key = executionRepository.parseFlowExecutionKey(flowExecutionKey);
// 问题点,这里涉及到`Conversation`生命周期(个人感觉巨复杂,没能继续深入了)
FlowExecutionLock lock = executionRepository.getLock(key);
lock.lock();
try {
FlowExecution flowExecution = executionRepository.getFlowExecution(key);
flowExecution.resume(context);
if (!flowExecution.hasEnded()) {
executionRepository.putFlowExecution(flowExecution);
return createPausedResult(flowExecution);
} else {
executionRepository.removeFlowExecution(flowExecution);
return createEndResult(flowExecution);
}
} finally {
lock.unlock();
}
} finally {
ExternalContextHolder.setExternalContext(null);
}
}
涉及到Conversation
生命周期(个人感觉巨复杂,没能继续深入了),这里偷个懒,发贴请教一下有经验的小伙伴们 ~
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论