我开发了一个带有 java 富客户端和远程对象持久性服务器的 cayenne 项目。如果我有钱的 cient 连接到部署在本地主机上同一台机器上的 Cayenne-ROP-Server(在 Jetty 上来自 maven 目标,如在 cayenne rop 教程中解释的那样),一切都很好:
ClientConnection clientConnection = new HessianConnection("http://localhost:8080/rop.server /cayenne-service",
"cayenne-user", "secret", SHARED_CAYENNE_SESSION_NAME);
DataChannel channel = new ClientChannel(clientConnection);
ObjectContext context = new CayenneContext(channel);
List<Object> someEntities = context.performQuery(allMovies);
如果我将第一行中要连接的 url 更改为非本地主机(ubuntu 上的 Tomcat7),那么一切正常,直到第 4 行:
List<Object> someEntities = context.performQuery(allMovies);
然后我收到错误“没有与请求关联的会话”
这是客户端的完整输出:
Running de.pss.hdlist.client.dataservice.MovieDataServiceCayenneImplTest
Sep 07, 2012 10:21:37 AM org.apache.cayenne.remote.hessian.HessianConnection connect
INFO: Connecting to [cayenne-user:*******@http://comunity-server.hopto.org:8080 /rop.server-3.0.2/cayenne-service] - shared session 'global-cayenne-session'
Sep 07, 2012 10:21:40 AM org.apache.cayenne.remote.hessian.HessianConnection connect
INFO: === Connected, session: org.apache.cayenne.remote.RemoteSession@12241e[sessionId=C47DD36ACE2A043401C8D0C44D5BD8C3,n ame=global-cayenne-session] - took 3182 ms.
Sep 07, 2012 10:21:53 AM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: --- Message 0: Bootstrap
Sep 07, 2012 10:21:53 AM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: === Message 0: Bootstrap done - took 406 ms.
Sep 07, 2012 10:21:53 AM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: --- Message 1: Query
Sep 07, 2012 10:21:53 AM org.apache.cayenne.remote.BaseConnection sendMessage
INFO: *** Message error for 1: Query - took 187 ms.
这是 Apache Tomcat 日志的服务器端输出:
WARNING: org.apache.cayenne.remote.service.MissingSessionException: [v.3.0.2 Jun 19 2011 09:29:50] No session associated with request.
org.apache.cayenne.remote.service.MissingSessionException: [v.3.0.2 Jun 19 2011 09:29:50] No session associated with request.
at org.apache.cayenne.remote.service.BaseRemoteService.processMessage(BaseRemoteService.java:148)
at sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
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.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
我使用 Apache Cayenne 3.0.2、Apache-Tomcat 7.0.29 和 Java 7 sdk
每个帮助都提前 THX
PS。也许本地 Jetty 服务器以另一种方式处理事情,就像远程 unix 机器上的 Tomcat 服务器一样。
编辑:在 Andrus 在下面的答案中给出提示之后,我添加了一个看起来像这样的 SessionListern:
public class HttpSessionListenerLogImpl implements HttpSessionListener {
private final static Logger LOGGER = Logger.getLogger(HttpSessionListenerLogImpl.class.getName());
@Override
public void sessionCreated(HttpSessionEvent hse) {
LOGGER.log(Level.SEVERE,
"!__Session created with ID: " + hse.getSession().getId());
LOGGER.log(Level.SEVERE, "!__Session created by: " + hse.getSource());
LOGGER.log(Level.SEVERE, "!__Session Attributes: " + hse.getSession().getAttributeNames());
LOGGER.log(Level.SEVERE, "!__Session max inactivity: " + hse.getSession().getMaxInactiveInterval());
LOGGER.log(Level.SEVERE, "!__Session context: " + hse.getSession().getServletContext().getServletContextName());
}
@Override
public void sessionDestroyed(HttpSessionEvent hse) {
LOGGER.log(Level.SEVERE, "!__Session killed with ID: " + hse.getSession().getId());
LOGGER.log(Level.SEVERE, "!__Session killed by: " + hse.getSource());
LOGGER.log(Level.SEVERE, "!__Session Attributes: " + hse.getSession().getAttributeNames());
LOGGER.log(Level.SEVERE, "!__Session max inactivity: " + hse.getSession().getMaxInactiveInterval());
LOGGER.log(Level.SEVERE, "!__Session context: " + hse.getSession().getServletContext().getServletContextName());
}
因此,在执行此问题之上的 4 行代码状态时,此侦听器为我提供了以下输出:
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session created with ID: B07648A2A5F0005AF6DF0741D7EF2D21
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session created by: org.apache.catalina.session.StandardSessionFacade@515f9553
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session Attributes: java.util.Collections$2@5a44a5e1
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session max inactivity: 216000
Sep 11, 2012 11:06:27 AM de.pss.hdlist.HttpSessionListenerLogImpl sessionCreated
SEVERE: !__Session context: Cayenne Tutorial
Sep 11, 2012 11:06:27 AM com.caucho.hessian.server.HessianSkeleton invoke
WARNING: org.apache.cayenne.remote.service.MissingSessionException: [v.3.0.2 Jun 19 2011 09:29:50] No session associated with request.
org.apache.cayenne.remote.service.MissingSessionException: [v.3.0.2 Jun 19 2011 09:29:50] No session associated with request.
at org.apache.cayenne.remote.service.BaseRemoteService.processMessage(BaseRemoteService.java:148)
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:616)
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.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
在这里你可以看到有一个会话被创建并且没有会话被杀死。那么为什么我的代码行中的 ObjectContext
List<Object> someEntities = context.performQuery(allMovies);
确实忽略了会话。在进行查询之前我是否必须明确设置它?客户端访问远程部署的 cayenne 服务器的标准初始化代码是什么。它与 cayenne rop 教程中给出的不同吗?
提前谢谢。
编辑:我升级到 cayenne 3.1B1 希望摆脱这个错误,但同样的情况:“没有会话......”尝试发送查询时。
我还在 localhost 上设置了一个 tomcat 并将其配置为与远程相同。尝试发送查询时出现相同的问题“无会话...”。
因此,localhost 上的 Jetty 是唯一一个从上面获取 4 行初始化代码并为每个后续查询保存会话的码头。所以这是我的问题。这个星球上是否有人曾尝试在 tomcat 上部署 cayenne rop 服务器并成功了?
对于每一个小提示,请提前 THX。
编辑:所以我在本地 tomcat7 上做了一点服务器端调试。
1.Client从上面执行第2行代码:
DataChannel channel = new ClientChannel(clientConnection);
在服务器端,我的会话侦听器被触发并告诉我一个会话已创建,ID 为:B6565298F222294F601B76333DBE4911
2.Client从上面执行第3行:
ObjectContext context = new CayenneContext(channel);
在服务器端,类 org.apache.cayenne.remote.service.HttpRemoteSession 的方法被调用:
/**
* Returns a ServerSession object that represents Cayenne-related state associated
* with the current session. If ServerSession hasn't been previously saved, returns
* null.
*/
@Override
protected ServerSession getServerSession() {
HttpSession httpSession = getSession(true);
return (ServerSession) httpSession.getAttribute(SESSION_ATTRIBUTE);
}
此方法的第一行创建了一个新会话。其 ID 为:ECC4A81D6240A1D04DA0A646200C4CE6。这个新会话只包含一个属性:键是“org.apache.cayenne.remote.service.HttpRemoteService.ServerSession”,值是(谁猜到了?)之前在步骤 1 中创建的会话让我感到奇怪的是,我的尽管创建了新会话,但不会触发 serveltListener。
3.Client从上面执行第4行
List<Object> someEntities = context.performQuery(allMovies);
现在在服务器端再次调用 getServerSession() 方法。这次还创建了一个新会话(为什么?)。并且此会话不包含任何属性。所以这行“return (ServerSession) httpSession.getAttribute(SESSION_ATTRIBUTE);” 在方法 getServerSession() 内部返回 null ,这恰好触发了异常“No Session associated with request”。
那么,为什么 cayenne 服务器端会创建 e ne 会话而不使用之前创建的旧会话呢?我是否必须在查询中明确发送会话?
编辑:我在运行上面的四行代码时从 netbeans http-monitor 截屏: