मैं $.getJSON
(HTTP GET) अनुरोध दो बार (अलग-अलग डेटा के साथ) अनुरोध कर रहा हूं, एक के बाद एक (मान लें कि हमारे पास request1 और request2 है)। मैं एफएफ और क्रोम से डेवलपर टूल्स में देख सकता हूं कि मेरे पास cookie:JSESSIONID=FD0D502635EEB67E3D36203E26CBB59A
हेडर फ़ील्ड है।क्यों नहीं मिलता है सत्र() कम समय अवधि में दूर किए गए अनुरोधों में उसी सत्र को वापस कर रहा है?
सर्वर साइड मैं सत्र प्राप्त करने की कोशिश में:
HttpSession session = request.getSession();
boolean isSessionNew = session.isNew();
String sessionId = session.getId();
String cookieFromRequestHeader = request.getHeader("cookie");
अगर मैं दोनों अनुरोधों मैं के लिए इन चरों प्रिंट,
request1:
isSessionNew: सच
cookieFromRequestHeader: JSESSIONID = FD0D502635EEB67E3D36203E26CBB59A
session.getId(): 9212B14094AB92D0F7F10EE21F593E52
request2:
isSessionNew: सच
cookieFromRequestHeader: jsessionid = FD0D502635EEB67E3D36203E26CBB59A
session.getId(): E8734E413FA3D3FEBD4E38A7BF27BA58
आप देख सकते हैं, सर्वर स्पष्ट रूप से बनाए गए एक नए सत्र 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' कहते हैं) मैं मिलता है,
request1 ':
isSessionNew: झूठी
cookieFromRequestHeader: jsessionid = E8734E413FA3D3FEBD4E38A7BF27BA58 session.getId (): E8734E413FA3D3FEBD4E38A7BF27BA58
request2 ':
isSessionNew: झूठी
cookieFromRequestHeader: jsessionid = E8734E413FA3D3FEBD4E38A7BF27BA58
session.getId(): E8734E413FA3D3FEBD4E38A7BF27BA58
तुम करीब से अब देखते हैं, तो सत्र id ही (request1 में 'और request2') और है अनुरोध 2 से बनाया गया अंतिम। क्या मुझे बहुत ही कम समय के अनुरोधों में सर्वर पर आने वाले कई बाद के अनुरोधों से एक ही सत्र प्राप्त करने का कोई तरीका है?
मैं किसी विशेष विशेषताओं का उपयोग नहीं कर रहा हूं - मैं बॉक्स सत्र रणनीति के बाहर स्प्रिंग का उपयोग कर रहा हूं।साथ ही, यह फ्रिस्ट 2 अनुरोध (अनुरोध 1 और अनुरोध 2) से कुकी JSESSIONID की तरह दिखता है जब मैं पृष्ठ पर पहली बार जाता हूं (मान लें कि सर्वर पर यह अनुरोध भेजा गया था जब यह JSESSIONID बनाया गया था)। लेकिन यह तब भी दिखता है जब तक कि आप स्पष्ट रूप से request.getSession() को कॉल नहीं करते हैं, बैकएंड/सर्वर हमेशा प्रत्येक प्रतिक्रिया के लिए एक नया JSESSIONID बना देगा और उसे क्लाइंट को वापस भेज देगा। तो जब प्रतिक्रिया के बाद ग्राहक से नया अनुरोध भेजा जाता है, तो उसके पास एक नया JSESSIONID होगा। ऐसा लगता है कि बॉक्स सत्र हैंडलिंग से बाहर वसंत उचित रूप से काम नहीं कर रहा है।
सधन्यवाद,
तानाशाह
अतिरिक्त अनुसंधान:
मैं अगर मैं एक HttpSessionListner साथ सत्र निर्माण रजिस्टर कर सकते हैं देखना चाहती थी। इस तरह मैं देख सकता हूं कि आईडी FD0D502635EEB67E3D36203E26CBB59A वाला सत्र (अनुरोध 1 और अनुरोध 2 में भेजा जा रहा कुकी) बनाया गया है। और, श्रोता (सत्रप्रोसेसर) का उपयोग करने का मौसम मैं आईडी द्वारा मानचित्र में सत्रों को स्टोर कर सकता हूं और बाद में उन्हें कुकी से आईडी द्वारा पुनर्प्राप्त कर सकता हूं (इसलिए मुझे एक और सत्र बनाने की आवश्यकता नहीं है)।
public interface ISessionProcessor extends ISessionRetriever, ISessionPopulator {
}
public interface ISessionRetriever {
HttpSession getSession(String sessionId);
}
public interface ISessionPopulator {
HttpSession setSession(String sessionId, HttpSession session);
}
अलग इन था, क्योंकि मैं केवल श्रोता नक्शा करने के लिए सत्र को जोड़ने की अनुमति चाहते थे, और नियंत्रकों केवल अनुरोध के माध्यम से एक सत्र बनाने के लिए सक्षम होना करने के लिए कारण:
तो यहाँ कोड है। getSession() - तो श्रोता का सत्र हमेशा तैयार की गई विधि को लागू किया गया था (जैसा कि आप नीचे देखेंगे)।
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});
}
}
web.xml में
: org.springframework.web.context.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>
मेरी-सर्वलेट-context.xml में
:
<bean class="mypackage.listener.SessionProcessor"/>
<bean class="mypackage.SomeController"/>
मेरी नियंत्रक में
:
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()});
}
}
इससे मुझे एक ही परिणाम मिला। ऐसा प्रतीत होता है कि अनुरोध के अलावा अन्य तरीकों से सत्र निर्माण .getSession (जब वसंत स्वयं बॉक्स से बाहर वसंत करता है), या तो श्रोता द्वारा पंजीकृत नहीं किया गया था या कुकी/jsessionID कहीं और से आया था। अधिक के लिए उत्तर देखें।
अन्य सूत्रों कि मुझे HttpSession मुद्दों के माध्यम से जाने में मदद की:
servlet context injection in controller
overview of concurrency when you have to work with HttpSession
using HttpSession object to do synchronization (avoid this)
the "best" way to do synchronization when working with HttpSession
कुछ वसंत संदर्भ सामान: कैसे सत्र पाने के लिए पर
session management
session management in security
विचार विमर्श जब आपके पास सत्र आईडी (डब्ल्यू टोपी मैंने ऊपर किया था):
coderanch discussion
stackoverflow
the post that helped me finalize my listener autowiring