Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么不是';t getSession()是否在短时间间隔内的后续请求中返回相同的会话?_Java_Jquery_Spring_Http Get_Httpsession - Fatal编程技术网

Java 为什么不是';t getSession()是否在短时间间隔内的后续请求中返回相同的会话?

Java 为什么不是';t getSession()是否在短时间间隔内的后续请求中返回相同的会话?,java,jquery,spring,http-get,httpsession,Java,Jquery,Spring,Http Get,Httpsession,我正在发送一个$.getJSON(httpget)请求两次(使用不同的数据),一个接一个(假设我们有request1和request2)。我可以在FF和Chrome的开发者工具中看到,我有相同的cookie:JSESSIONID=FD0D502635EEB67E3D36203E26CBB59A标题字段 在服务器端,我尝试获取会话: HttpSession session = request.getSession(); boolean isSessionNew = session.isNew();

我正在发送一个
$.getJSON
(httpget)请求两次(使用不同的数据),一个接一个(假设我们有request1和request2)。我可以在FF和Chrome的开发者工具中看到,我有相同的
cookie:JSESSIONID=FD0D502635EEB67E3D36203E26CBB59A
标题字段

在服务器端,我尝试获取会话:

HttpSession session = request.getSession();
boolean isSessionNew = session.isNew();
String sessionId = session.getId();
String cookieFromRequestHeader = request.getHeader("cookie");
如果我为收到的两个请求打印这些变量,
请求1:

isSessionNew:正确
cookieFromRequestHeader:JSESSIONID=FD0D502635EEB67E3D36203E26CBB59A
session.getId():9212B14094AB92D0F7F10EE21F593E52

请求2:

isSessionNew:正确
cookieFromRequestHeader:JSESSIONID=FD0D502635EEB67E3D36203E26CBB59A
session.getId():e8734e413fa3febd4e38a7bf27ba58

如您所见,服务器在
request.getSession()
上为request2创建了一个新会话。但为什么会这样呢?理论上,它应该是同步的,并提供与第一个请求(首先到达此代码)创建的会话相同的会话。
现在,为了确保会话创建是同步的,我执行了以下操作:

@Autowired
private ServletContext servletContext;
...
synchronized (servletContext) {
    HttpSession session = request.getSession();
    boolean isSessionNew = session.isNew();
    String sessionId = session.getId();
    String cookieFromRequestHeader = request.getHeader("cookie");
}
我也得到了同样的结果

如果我稍后再次发送相同的请求(比如request1'和request2'),我得到,
请求1':

isSessionNew:false
cookieFromRequestHeader:JSESSIONID=E8734E413FA3D3FEBD4E38A7BF27BA58 session.getId():e8734e413fa3febd4e38a7bf27ba58

请求2':

isSessionNew:false
cookieFromRequestHeader:JSESSIONID=E8734E413FA3D3FEBD4E38A7BF27BA58
session.getId():e8734e413fa3febd4e38a7bf27ba58

如果现在仔细看,会话id是相同的(在request1'和request2'中),并且是从request2创建的最后一个会话id。有没有办法在很短的时间内从服务器收到的多个后续请求中获得相同的会话?

我没有使用任何特殊功能——我使用的是Spring的开箱即用会话策略。另外,第一个2个请求(request1和request2)中的cookie JSESSIONID似乎来自我第一次访问页面时(假设在创建此JSESSIONID时有一个request0发送到服务器)。但是,除非显式调用request.getSession(),否则后端/服务器将始终为每个响应创建一个新的JSSessionID,并将其发送回客户端。因此,当响应到来后从客户端发送新请求时,它将有一个新的JSESSIONID。看起来Spring开箱即用会话处理无法正常工作

亲切的问候,
暴君

其他研究

我想看看是否可以用HttpSessionListner注册会话创建。通过这种方式,我可以看到id为FD0D502635EEB67E3D36203E26CBB59A(在request1和request2中发送的cookie)的会话何时创建。此外,使用侦听器(SessionProcessor),我可以按id将会话存储在映射中,然后再从cookie中按id检索会话(因此我不需要创建另一个会话)。
下面是代码:

public interface ISessionProcessor extends ISessionRetriever, ISessionPopulator {
}

public interface ISessionRetriever {

    HttpSession getSession(String sessionId);
}

public interface ISessionPopulator {

    HttpSession setSession(String sessionId, HttpSession session);
}
之所以将它们分开,是因为我只想让侦听器将会话添加到映射中,而控制器只能通过request.getSession()创建会话-因此listner的sessionCreated方法始终被调用(如下所示)

这给了我同样的结果。除了request.getSession(当spring自己开箱即用创建会话时)之外,会话创建似乎没有被侦听器注册,或者cookie/JSSessionID来自其他地方。寻找更多的答案

帮助我解决HttpSession问题的其他来源:




一些spring参考资料:


讨论当您有sessionId时如何获得会话(我在上面所做的):


它看起来像来自前2个请求的CookieJSessionID (request1和request2)来自我第一次访问页面 (假设在服务器创建此文件时,有一个request0发送到服务器 JSESSIONID)

事实并非如此。我有两个应用程序部署在同一服务器上的同一个域下。因此,当我调用服务器时,它为app1创建了一个id为FD0D502635EEB67E3D36203E26CBB59A的会话,并将这个JSESSIONID以cookie的形式发送给客户端。客户端将cookie保存在mydomain.com下,第二次执行时,客户端浏览器从请求头中的cookie发送JSESSIONID。我在服务器上收到它,但这不是另一个app2中的会话

这解释了当我发送另外两个请求(request1'和request2')时,它们在相应的应用程序上创建了一个sessionID

请在此查看更多信息:

至于我的问题的具体答案,似乎需要同步第一个请求,以便始终确保在以下请求中具有相同的会话id。第一个请求之后的以下请求可以是异步的。

只需将您的cookie(使用JESSIONID)存储在客户端,当您将后续请求发送到服务器时,将存储的cookie放入您的请求头字段并发送,然后您将在服务器端获得相同的会话

客户端(IOS)存储来自以下响应的cookie:

    NSHTTPURLResponse* httpURLReqponse = (NSHTTPURLResponse*) response;
    NSDictionary* allHeaders = [httpURLReqponse allHeaderFields];
    NSLog(@"Response Headers : %@ ", allHeaders);
    NSString* cookie = [allHeaders objectForKey: @"Set-Cookie"];
    DATA.cookies = cookie;      // Store the cookie
// Put the stored cookie in your request header
[(NSMutableURLRequest*)request addValue: DATA.cookies forHTTPHeaderField:@"cookie"];
[NSURLConnection sendAsynchronousRequest: request queue:[NSOperationQueue mainQueue] completionHandler:nil];
// Get the session, print its hashCode. You will find out that it's same as previous.
HttpSession session = ServletActionContext.getRequest().getSession();
客户端(IOS)使用cookie发送后续请求:

    NSHTTPURLResponse* httpURLReqponse = (NSHTTPURLResponse*) response;
    NSDictionary* allHeaders = [httpURLReqponse allHeaderFields];
    NSLog(@"Response Headers : %@ ", allHeaders);
    NSString* cookie = [allHeaders objectForKey: @"Set-Cookie"];
    DATA.cookies = cookie;      // Store the cookie
// Put the stored cookie in your request header
[(NSMutableURLRequest*)request addValue: DATA.cookies forHTTPHeaderField:@"cookie"];
[NSURLConnection sendAsynchronousRequest: request queue:[NSOperationQueue mainQueue] completionHandler:nil];
// Get the session, print its hashCode. You will find out that it's same as previous.
HttpSession session = ServletActionContext.getRequest().getSession();
不仅适用于IOS客户端。然后,在服务器端,您将获得相同的会话:

服务器(JavaEE)获取HttpSession:

    NSHTTPURLResponse* httpURLReqponse = (NSHTTPURLResponse*) response;
    NSDictionary* allHeaders = [httpURLReqponse allHeaderFields];
    NSLog(@"Response Headers : %@ ", allHeaders);
    NSString* cookie = [allHeaders objectForKey: @"Set-Cookie"];
    DATA.cookies = cookie;      // Store the cookie
// Put the stored cookie in your request header
[(NSMutableURLRequest*)request addValue: DATA.cookies forHTTPHeaderField:@"cookie"];
[NSURLConnection sendAsynchronousRequest: request queue:[NSOperationQueue mainQueue] completionHandler:nil];
// Get the session, print its hashCode. You will find out that it's same as previous.
HttpSession session = ServletActionContext.getRequest().getSession();

我注意到在
…web.xml
文件中禁用cookie时会发生这种情况:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">

    <context-root>/some-app</context-root>

    <class-loader delegate="true"/>

    <jsp-config>
        <property name="keepgenerated" value="true">
            <description>Keep a copy of the generated servlet class' java code.</description>
        </property>
    </jsp-config>

    <session-config>
        <session-properties>
            <property name="timeoutSeconds" value="600"/>
            <property name="enableCookies" value="false"/> 
        </session-properties>
    </session-config>

</glassfish-web-app>

/一些应用程序
保留生成的servlet类的java代码的副本。