我有一个富客户端应用程序,它使用Apache Cayenne远程对象持久性框架来访问和存储数据。到目前为止,我一直无法找到一种优雅的方法来检测和处理连接超时。在会话超时后尝试执行操作时,客户端和服务器上都会抛出MissingSessionException
,但在客户端,会捕获此异常并将堆栈跟踪打印到控制台,而不会传播给调用者:
Apr 07, 2016 2:48:48 PM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: --- Message 6: Query
Apr 07, 2016 2:48:48 PM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: *** Message error for 6: Query - took 16 ms.
org.apache.cayenne.remote.service.MissingSessionException: [v.4.0.M2 Feb 26 2015 08:16:32] [v.4.0.M2 Feb 26 2015 08:16:32] No session associated with request.
at org.apache.cayenne.remote.service.BaseRemoteService.processMessage(BaseRemoteService.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:180)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:109)
at com.caucho.hessian.server.HessianServlet.service(HessianServlet.java:396)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
是否有一种简单的方法可以检测到连接是否已死,以便我可以提示用户重新连接?
在相关的说明中,如果能够重新建立连接,那么正在使用的现有客户端ObjectContext
对象会发生什么?先前在这些上下文中创建的未提交的PersistentObject
是否会永远丢失?
修改:这与Apache Cayenne ROP Server "No session associated with request." on Tomcat 7
不同Edit2:我能想到的唯一(hacky)解决方案是实际运行保持活动线程,定期向Cayenne发送低延迟查询,以保持ROP会话处于活动状态并单独跟踪应用程序活动并提示用户如果在没有活动的情况下经过了一段时间,请输入密码。我用这种方法看到的问题是,有很多方法可以忽略活动,应用程序没有真正超时,它实际上没有解决会话需要超时的根本问题一个原因。
Edit3:我还将此问题提交给了Cayenne用户列表。您可以查看讨论here。