Warum nicht getSession() Rückgabe der gleichen Sitzung, in der die nachfolgenden Anforderungen distanzierte sich in kurzen Zeitabschnitten?

Sende ich ein $.getJSON (HTTP GET) Anfrage zweimal (mit unterschiedlichen Daten), eine nach der anderen (können sagen, wir haben request1 und request2). Ich sehe in den developer tools von FF und Chrome, ich habe das gleiche cookie:JSESSIONID=FD0D502635EEB67E3D36203E26CBB59A - header-Feld.

Auf der server-Seite versuche ich die Sitzung:

HttpSession session = request.getSession();
boolean isSessionNew = session.isNew();
String sessionId = session.getId();
String cookieFromRequestHeader = request.getHeader("cookie");

Wenn ich drucken diese Variablen für die beiden Anfragen, die ich bekomme,
request1:

isSessionNew:true
cookieFromRequestHeader:JSESSIONID=FD0D502635EEB67E3D36203E26CBB59A
Sitzung.getId():9212B14094AB92D0F7F10EE21F593E52

request2:

isSessionNew:true
cookieFromRequestHeader:JSESSIONID=FD0D502635EEB67E3D36203E26CBB59A
Sitzung.getId(): E8734E413FA3D3FEBD4E38A7BF27BA58

Wie Sie sehen können, der server eindeutig eine neue Sitzung erstellt für request2 auf eine request.getSession(). Aber warum tut er dies? Es sollte theoretisch synchronisiert werden und geben Sie der gleichen Sitzung, dass die erste Anforderung (erreicht, dass dieser code first) erstellt. Nun, um sicher zu sein, dass der session-Erzeugung synchronisiert ist habe ich Folgendes:

@Autowired
private ServletContext servletContext;
...
synchronized (servletContext) {
    HttpSession session = request.getSession();
    boolean isSessionNew = session.isNew();
    String sessionId = session.getId();
    String cookieFromRequestHeader = request.getHeader("cookie");
}

und ich bekam die gleichen Ergebnisse.

Wenn ich senden die gleichen Anforderungen später wieder (sagen wir request1 "und request2') bekomme ich,
request1':

isSessionNew:false
cookieFromRequestHeader:JSESSIONID=E8734E413FA3D3FEBD4E38A7BF27BA58
Sitzung.getId():E8734E413FA3D3FEBD4E38A7BF27BA58

request2':

isSessionNew:false
cookieFromRequestHeader:JSESSIONID=E8734E413FA3D3FEBD4E38A7BF27BA58
Sitzung.getId():E8734E413FA3D3FEBD4E38A7BF27BA58

Wenn Sie sehen, dass Sie genau jetzt, die session-id ist die gleiche (request1 "und request2') und der Letzte ist aus der request2. Gibt es eine Möglichkeit, mich immer der gleichen Sitzung, von mehreren nachfolgenden Anforderungen, die der server in sehr kurzer Zeit zu erstellen?

Ich bin nicht mit jedem special-features - ich bin mit Spring out of the box session-Strategie. Auch sieht es so aus das cookie JSESSIONID von den ersten 2 Anfragen (request1 und request2) stammen aus der ersten Zeit Besuche ich die Seite (können sagen, es war ein request0 an den server gesendet, wenn er erzeugt dieses JSESSIONID). Aber es sieht so aus, es sei denn, Sie rufen explizit anfordern.getSession(), backend - /server wird immer erstellen Sie eine neue JSESSIONID für jede Antwort und senden Sie es zurück an den client. Also wenn ein neuer request vom client gesendet, nachdem eine Antwort kommt, sein gehen, um eine neue JSESSIONID. Es sieht aus wie Frühling aus der box auf das session-handling nicht richtig funktioniert.

Freundlichen GRÜßEN,
Despoten

ZUSÄTZLICHE FORSCHUNG:

Ich wollte sehen, ob ich registrieren kann der session-Erzeugung mit einem HttpSessionListner. Auf diese Weise kann ich sehen, Wann die session mit der id FD0D502635EEB67E3D36203E26CBB59A (die das cookie gesendet wird, in request1 und request2) erstellt. Und auch von der Witterung über den Hörer (der SessionProcessor) kann ich das speichern der sessions in eine map-id und später abrufen, indem Sie die id aus dem cookie (so brauche ich nicht zu erstellen, die einer anderen Sitzung).
So hier ist der code:

public interface ISessionProcessor extends ISessionRetriever, ISessionPopulator {
}

public interface ISessionRetriever {

    HttpSession getSession(String sessionId);
}

public interface ISessionPopulator {

    HttpSession setSession(String sessionId, HttpSession session);
}

Der Grund für diese Trennung war, weil ich nur wollte, um dem Zuhörer zu Sitzungen hinzufügen, um die Karte und die Controller nur in der Lage sein, um eine Sitzung zu erstellen, durch Anfrage.getSession() - so ist der listner - sessionCreated-Methode aufgerufen wurde, immer (wie Sie unten sehen werden).

public class SessionProcessor implements ISessionProcessor {

    private Map<String, HttpSession> sessions = new HashMap<String, HttpSession>();

    @Override
    public HttpSession getSession(String sessionId) {
            return sessions.get(sessionId);
    }

    @Override
    public HttpSession setSession(String sessionId, HttpSession session) {
            return sessions.put(sessionId, session);
    }

}

public class SessionRetrieverHttpSessionListener implements HttpSessionListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(SessionRetrieverHttpSessionListener.class);

    @Autowired
    private ISessionPopulator sessionPopulator;

    @Override
    public void sessionCreated(HttpSessionEvent se) {
            HttpSession session = se.getSession();
            LOGGER.debug("Session with id {} created. MaxInactiveInterval: {} session:{}", new Object[]{session.getId(), session.getMaxInactiveInterval(), session});
            sessionPopulator.setSession(session.getId(), session);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
            HttpSession session = se.getSession();
            //session has been invalidated and all session data (except Id) is no longer available
            LOGGER.debug("Session with id {} destroyed. MaxInactiveInterval: {}, LastAccessedTime: {}, session:{}", 
                            new Object[]{session.getId(), session.getMaxInactiveInterval(), session.getLastAccessedTime(), session});
    }
}  

in web.xml:

org.springframework.web.Kontext.ContextLoaderListener

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/my-servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<listener>
    <listener-class>mypackage.listener.SessionRetrieverHttpSessionListener</listener-class>
</listener>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

in my-servlet-context.xml:

<bean class="mypackage.listener.SessionProcessor"/>
<bean class="mypackage.SomeController"/>

in meinem controller:

                    synchronized (servletContext) {
                            String cookieFromRequestHeader = request.getHeader("cookie");
                            LOG.debug("cookieFromRequestHeader:{}", new Object[] {cookieFromRequestHeader});
                            String jsessionIdFromCookieFromRequestHeader = cookieFromRequestHeader.substring(cookieFromRequestHeader.indexOf("=") + 1);
                            LOG.debug("jsessionIdFromCookieFromRequestHeader:{}", new Object[] {jsessionIdFromCookieFromRequestHeader});
                            session = sessionRetriever.getSession(jsessionIdFromCookieFromRequestHeader);
                            LOG.debug("session:{}", new Object[] {session});
                            if (session == null) {
                            LOG.debug("request.isRequestedSessionIdFromCookie():{}, request.isRequestedSessionIdFromURL():{}, WebUtils.getSessionId(request):{}.", new Object[] {request.isRequestedSessionIdFromCookie(), request.isRequestedSessionIdFromURL(), WebUtils.getSessionId(request)});
                            session = request.getSession();
                            boolean isSessionNew = session.isNew();
                            LOG.debug("Is session new? - {}. The session should not be new after the first fingerprint part is received - check if this occured in the logs - if that happend than there is an error!", isSessionNew);
                            LOG.debug("request.isRequestedSessionIdFromCookie():{}, request.isRequestedSessionIdFromURL():{}, WebUtils.getSessionId(request):{}.", new Object[] {request.isRequestedSessionIdFromCookie(), request.isRequestedSessionIdFromURL(), WebUtils.getSessionId(request)});
                            //read https://stackoverflow.com/a/2066883 and think about using ServletContextAware also.
                            LOG.debug("cookieFromRequestHeader:{} session.getId(): {}", new Object[]{cookieFromRequestHeader, session.getId()});
                            }
                    }

Dies gab mir die gleichen Ergebnisse. Es zeigte sich, dass der session-Erzeugung durch andere Mittel als Anfrage.getSession (wenn der Frühling sich aus der box der die session erzeugt hat), war entweder nicht registriert ist, indem Sie den Hörer oder das cookie/jsessionID kam von irgendwo sonst. Suchen Sie die Antwort für mehr.

Anderen Quellen, die mir geholfen haben, gehen Sie durch die HttpSession Themen:
servlet-Kontext injection controller
übersicht über die Parallelität, wenn Sie arbeiten müssen mit HttpSession
mit HttpSession-Objekt-Synchronisation (vermeiden)
die "beste" Art und Weise zu tun, die Synchronisierung bei der Arbeit mit HttpSession
einige Frühling Referenz Sachen:
session-management
session-management in Sicherheit
Diskussionen über how to get session wenn Sie eine sessionId (was ich getan habe, oben):
coderanch Diskussion
stackoverflow
die post, die mir geholfen finalisieren meine Zuhörer autowiring

InformationsquelleAutor despot | 2012-10-22

Schreibe einen Kommentar