2009-09-30 24 views
25

मेरे पास एक सर्वलेट है जो एक मल्टीपार्ट फॉर्म पोस्ट को संभालता है। पोस्ट वास्तव में पृष्ठ में एम्बेडेड एक फ्लैश फ़ाइल अपलोड घटक द्वारा किया जा रहा है। कुछ ब्राउज़रों में, फ्लैश-जेनरेट किए गए POST में JSESSIONID शामिल नहीं है जो पोस्ट के दौरान सत्र से कुछ जानकारी लोड करना असंभव बना रहा है।JSESSIONID का उपयोग करके मैन्युअल रूप से जावा सत्र कैसे लोड कर सकता हूं?

फ्लैश अपलोड घटक में एक विशेष फॉर्म फ़ील्ड के भीतर कुकी और सत्र जानकारी शामिल है। इस फॉर्म फ़ील्ड का उपयोग करके, मैं वास्तव में JSESSIONID मान पुनर्प्राप्त कर सकता हूं। समस्या यह है कि, मुझे नहीं पता कि इस विशिष्ट सत्र को मैन्युअल रूप से लोड करने के लिए इस JSESSIONID मान का उपयोग कैसे करें।

@Override 
    public void sessionCreated(final HttpSessionEvent se) { 
     final HttpSession session = se.getSession(); 
     final ServletContext context = session.getServletContext(); 
     context.setAttribute(session.getId(), session); 
    } 

    @Override 
    public void sessionDestroyed(final HttpSessionEvent se) { 
     final HttpSession session = se.getSession(); 
     final ServletContext context = session.getServletContext(); 
     context.removeAttribute(session.getId()); 
    } 

कौन सा उनके अद्वितीय आईडी द्वारा मैप विशेषताओं के रूप में ServletContext के सभी सत्रों कहते हैं: -

संपादित ChssPly76 के समाधान के आधार पर, मैं निम्नलिखित HttpSessionListener कार्यान्वयन बनाया। मैं इसके बजाय संदर्भ में सत्र का मानचित्र डाल सकता हूं, लेकिन यह अनावश्यक लगता है। कृपया इस फैसले पर कोई विचार पोस्ट करें। इसके बाद, मैं आईडी द्वारा सत्र को हल करने के लिए अपने सर्वलेट को निम्नलिखित पद्धति जोड़ें:

private HttpSession getSession(final String sessionId) { 
     final ServletContext context = getServletContext(); 
     final HttpSession session = (HttpSession) context.getAttribute(sessionId); 
     return session; 
    } 
+0

+1 .. बहुत अच्छा सवाल – peakit

उत्तर

21

आईडी द्वारा सत्र पुनर्प्राप्त करने के लिए कोई एपीआई नहीं है।

हालांकि, आप अपने वेब एप्लिकेशन में session listener लागू कर सकते हैं और मैन्युअल रूप से आईडी द्वारा की गई सत्रों का नक्शा बनाए रख सकते हैं (सत्र आईडी session.getId() के माध्यम से पुनर्प्राप्त करने योग्य है)। फिर आप अपने इच्छित सत्र को पुनः प्राप्त करने में सक्षम होंगे (जैसा कि अन्य सुझावों के साथ आपके वर्तमान सत्र को बदलने के लिए कंटेनर को ट्रिक करने के विपरीत)

+0

यह चालाक है। –

+1

इसके साथ मेरी एकमात्र चिंता मानव त्रुटि भाग है जहां आप डेवलपर को सत्र आईडी के मानचित्र का उपयोग करने के बजाय request.getSession() का उपयोग करके कुछ कोड पेश करेंगे। मेरा मानना ​​है कि "सरल" समाधान यूआरएल को उचित रूप से बनाना है। –

+0

दो तरीकों से मैं सत्र मानचित्र के लिए श्रोता से पूछने वाले सर्वलेट की कल्पना कर सकता हूं: श्रोता एक सिंगलटन है, या नक्शा को ServletContext – rcampbell

1

सर्वलेट कल्पना के भीतर कोई तरीका नहीं है, लेकिन आप की कोशिश कर सकते:

  • मैन्युअल रूप में कुकी सेट फ्लैश

  • या टेलर एल के रूप में करने के अनुरोध से सुझाव दिया गया है कि मैं टाइप कर रहा हूं और यूएसआई के पथ को jsessionid पैरामीटर जोड़ रहा हूं।

दोनों विधियां आपके ऐप को एक सर्वलेट कंटेनर पर चलने के लिए जोड़ती हैं जो टोमकैट की तरह व्यवहार करती है; मुझे लगता है कि उनमें से ज्यादातर करते हैं। दोनों को आपके फ्लैश एप्लेट को इसकी कुकीज़ के लिए पेज पूछने की भी आवश्यकता होगी, जो एक जावास्क्रिप्ट निर्भरता लगा सकता है।

0

यह वास्तव में एक अच्छी पोस्ट है। संदर्भ में सत्र जोड़ने के लिए सत्र श्रोता का उपयोग करने के साथ एक संभावित समस्या यह है कि आपके समवर्ती सत्रों की संख्या के आधार पर यह काफी वसा प्राप्त कर सकता है। और फिर श्रोता के लिए वेब सर्वर कॉन्फ़िगरेशन के लिए सभी अतिरिक्त कार्य।

तो इसके बारे में एक बहुत ही सरल समाधान के लिए कैसे। मैंने इसे कार्यान्वित किया और यह काफी अच्छा काम करता है। तो उस पृष्ठ पर जो फ्लैश अपलोड ऑब्जेक्ट लोड करता है, सत्र ऑब्जेक्ट में सत्र और सत्रिड को एक कुंजी-मूल्य जोड़ी के रूप में संग्रहीत करें, फिर उस सत्र आईडी को अपलोड पेज पर पोस्ट पैरामीटर के रूप में पास करें। अपलोड पेज पर, देखें कि क्या सत्रिका पहले से ही एप्लिकेशन में है, तो उस सत्र का उपयोग करें, अन्यथा, अनुरोध से एक प्राप्त करें। साथ ही, आगे बढ़ें और सबकुछ साफ रखने के लिए एप्लिकेशन से उस कुंजी को हटा दें।

swf पृष्ठ पर:

application.setAttribute(session.getId(), session); 

फिर अपलोड पृष्ठ पर:

बहुत अच्छा समाधान दोस्तों। इसके लिए धन्यवाद।

+5

"काफी वसा"? क्या आपने इसे माप लिया है? क्या आप जावा से परिचित हैं? यह सिर्फ एक संदर्भ है, मूल्य की प्रति नहीं ... – BalusC

+0

ओह, आप सही हैं। ऐसा नहीं सोचा था। फिर भी, मूल सुझाव को लागू करना आसान है। इसके अलावा, चूंकि मैंने अब इस कोड का पूरी तरह से परीक्षण किया है, इसलिए मुझे निम्नलिखित मिल गया है। यदि मूल पोस्टर विशेष रूप से SWFUpload को संदर्भित कर रहा था, तो जब आप एक से अधिक फ़ाइल अपलोड करते हैं, तो SWFUpload प्रत्येक फ़ाइल को व्यक्तिगत रूप से पोस्ट करेगा, सभी एक ही पोस्ट में नहीं। तो पहले अपलोड के बाद सत्र ऑब्जेक्ट को एप्लिकेशन ऑब्जेक्ट को हटाकर, अन्य सभी विफल हो गए। FYI करें। – Garfield

2

ऐसा करने का एक सुरक्षित तरीका कुकी में jsession आईडी सेट करना है - यह यूआरएल में इसे सेट करने से कहीं अधिक सुरक्षित है।

यह एक कुकी के रूप में स्थापित हो जाने के बाद, तो आप सत्र

request.getSession(); 

method.setRequestHeader("Cookie", "JSESSIONID=88640D6279B80F3E34B9A529D9494E09"); 
0

का उपयोग कर आप बिलाव उपयोग कर रहे हैं सामान्य तरीके से प्राप्त कर सकते हैं, तो आप बिल्ला सीधे पूछना (लेकिन यह बदसूरत है)। मैं शर्त लगाता हूं कि अन्य वेब सर्वरों के लिए अन्य हैकी समाधान भी हैं।

यह सत्र प्रबंधित करने के लिए "प्रबंधक" इंटरफ़ेस का एक उदाहरण उपयोग करता है। यह बदसूरत बनाता है कि मुझे हुक करने में सक्षम होने के लिए एक अच्छा सार्वजनिक इंटरफ़ेस नहीं मिला है, इसलिए हमें प्रबंधक प्राप्त करने के लिए प्रतिबिंब का उपयोग करना होगा।

नीचे एक संदर्भ श्रोता है जो संदर्भ स्टार्टअप पर उस प्रबंधक को पकड़ता है, और उसके बाद टॉमकैट सत्र प्राप्त करने के लिए उपयोग किया जा सकता है।

public class SessionManagerShim implements ServletContextListener { 
    static Manager manager; 

    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
     try { 
      manager = getManagerFromServletContextEvent(sce); 
     } catch (NoSuchFieldException | IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent sce) { 
     manager = null; 
    } 

    private static Manager getManagerFromServletContextEvent(ServletContextEvent sce) throws NoSuchFieldException, IllegalAccessException { 
     // Step one - get the ApplicationContextFacade (Tomcat loves facades) 
     ApplicationContextFacade contextFacade = (ApplicationContextFacade)sce.getSource(); 

     // Step two - get the ApplicationContext the facade wraps 
     Field appContextField = ApplicationContextFacade.class.getDeclaredField("context"); 
     appContextField.setAccessible(true); 
     ApplicationContext applicationContext = (ApplicationContext) 
       appContextField.get(contextFacade); 

     // Step three - get the Context (a tomcat context class) from the facade 
     Field contextField = ApplicationContext.class.getDeclaredField("context"); 
     contextField.setAccessible(true); 
     Context context = (Context) contextField.get(applicationContext); 

     // Step four - get the Manager. This is the class Tomcat uses to manage sessions 
     return context.getManager(); 
    } 

    public static Session getSession(String sessionID) throws IOException { 
     return manager.findSession(sessionID); 
    } 
} 

आप इसे अपने web.xml में श्रोता के रूप में जोड़ सकते हैं और इसे काम करना चाहिए।

फिर आप सत्र प्राप्त करने के लिए ऐसा कर सकते हैं।

संबंधित मुद्दे

 संबंधित मुद्दे