2009-08-15 18 views
21

में सत्र में डेटा सहेजना मैं जे (2) ईई और वेब ऐप विकास की दुनिया में नया हूं लेकिन मैं इसके आस-पास अपना रास्ता तलाश रहा हूं और बहुत कुछ सीख रहा हूं। हर दिन मेरे लिए नई खोज का एक शानदार यात्रा है।जेएसएफ

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

ऐसे समय होते हैं जब मुझे अनुरोधों के बीच कुछ वस्तुओं को सहेजने की आवश्यकता होती है (उदाहरण के लिए MyObject कहें)। और जो मैंने अभी तक पढ़ और समझ लिया है, मुझे इन ऑब्जेक्ट्स को अलग-अलग अनुरोधों के बीच सहेजने के लिए सत्रों का उपयोग करने की आवश्यकता है। अब तक सब ठीक है।

बिल्कुल यह कैसे करना है जहां मेरी चिंता झूठ है। मुझे पता है कि जेएसपी में आप session.setAttribute("myObj", myObject) का उपयोग कर सकते हैं जो ऑब्जेक्ट को कुकीज़ या यूआरएल रीराइट्स या छुपा फॉर्म वैरिएबल का उपयोग करके क्लाइंट साइड पर सहेज लेगा।

दूसरी तरफ, जेएसएफ में मैं सत्र स्कोप्ड बीन्स का उपयोग करता हूं, उदाहरण के लिए सत्रबीन 1 कहता हूं, और सत्र बीन 1 गुणों के रूप में वस्तुओं को सहेजता हूं (उदा। SessionBean1.setSomeOjb(myObj))। क्या इस के बारे में जाने का यह सही तरीका है?

मुझे लगता है कि इस तरह से ऐसा करने से सर्वर के अंत में स्मृति उपयोग में वृद्धि होगी क्योंकि प्रत्येक अनुरोध सत्र स्कीप्ड बीन, सत्र बीन 1 और सत्र बीन 1 में सहेजे गए myObject उदाहरणों द्वारा उपयोग की गई स्मृति का एक नया उदाहरण तैयार करेगा।

मैंने पढ़ा है कि आप FacesContext.getExternalContext().getSession/getSessionMap() का उपयोग कर सकते हैं जो क्लाइंट साइड पर सत्र चर को सहेज लेगा।

तो आप किस विधि का सुझाव देंगे कि मैं सत्र का अनुरोध करने के लिए ऑब्जेक्ट्स को सहेजने के लिए सत्र स्कैन बीन या सत्रमैप का उपयोग करता हूं?

धन्यवाद।

+1

"प्रत्येक अनुरोध सत्र स्कोप्ड बीन का एक नया उदाहरण तैयार करेगा" यह पूरी तरह से गलत है –

उत्तर

21

सामान्य जावा ईई वेब ऐप्स में सत्र डेटा क्लाइंट पक्ष को सहेजने की अपेक्षा नहीं की जाती है। आप सर्वर पक्ष पर सत्र ब्लोट के बारे में चिंतित होने का अधिकार रखते हैं, एक सामान्य समस्या यह है कि विशाल सत्र पैरों के निशान हैं जो महत्वपूर्ण संसाधन और प्रदर्शन के मुद्दों का कारण बन सकते हैं, और विशेष रूप से क्लस्टर वातावरण में हो सकते हैं।

मैं चाहूँगा पता करने के लिए तुम कहाँ देखना

मैंने पढ़ा है कि आप FacesContext.getExternalContext()। GetSession/getSessionMap() का उपयोग कर सकते है जो ग्राहक के पक्ष में सत्र चर की बचत होगी।

मेरा मानना ​​है कि (इस मुद्दे पर मुझे सही करें) है कि इस बस HttpSession वस्तु, जिस पर आप तो एक ही

session.setAttribute("myObj", myObject) 

उपयोग कर सकते हैं इस अपने आप में वस्तु को वापस भेज करता है करने के लिए पहुँच देता है क्लाइंट, यह सर्वर में आयोजित होता है और कुछ सत्र पहचानकर्ता द्वारा की जाती है, आमतौर पर एक कुकी में पारित होती है।

अब दो अन्य तकनीकों हैं: आप स्पष्ट रूप से अपने स्वयं के निर्माण की एक कुकी में डेटा डाल करने के लिए चुन सकते हैं - सर्वलेट API शामिल हैं JSF या JSP से उपयोग कर सकते हैं, आप ऐसा कर दिया जाएगा या आप पर छिपा क्षेत्रों का उपयोग कर सकते हैं आपके फॉर्म, और इसलिए ऑरंड सत्र डेटा पास करें।

लेकिन इस पर विचार करें। मेरे द्वारा उपयोग किए जाने वाले ऐप सर्वर पर अंगूठे का नियम यह है कि 1k-4k के क्रम का Http सत्र एक समस्या नहीं है। उससे बड़ा (और मैंने मेगाबाइट्स में मापा गया सत्र देखा है) बुनियादी ढांचे पर दबाव डालें।यदि आप उस आकार के सत्रों के बारे में चिंतित थे, तो क्या आप कुकी या छिपे हुए क्षेत्र में डेटा के मेगाबाइट्स को प्रत्येक अनुरोध पर ब्राउजर पर वापस भेजने की उम्मीद करेंगे? यहां तक ​​कि 1k-2k शायद थोड़ा बड़ा है।

तो सिफारिशें:

  1. यह सरल रखें। सत्र API, या उसके जेएसएफ अभिव्यक्ति का प्रयोग करें।

  2. सत्र में डेटा की मात्रा नियंत्रण में रखें।

जोड़ा जवाब में क्लस्टरिंग के बारे में सवाल करने के लिए:

आमतौर पर, संकुल वातावरण में हम सत्र संबंध है, ताकि अनुरोध एक ही क्लस्टर सदस्य के लिए वापस भेज दिया जाता है। हालांकि अनुरोध को एक अलग सर्वर पर जाने पर हमें अभी भी मामले पर विचार करने की आवश्यकता है (शायद क्लस्टर सदस्य विफल हो जाते हैं)।

कुछ ऐप सर्वर विक्रेता प्रत्यक्ष इंटर-सर्वर संचार के माध्यम से या सत्र में सत्र को जारी रखते हुए सत्र प्रतिकृति प्रदान करते हैं - जाहिर है, यहां पर ओवरहेड हैं, इसलिए कभी-कभी, कम मूल्य सत्रों के लिए हम केवल सत्र में सत्र के नुकसान को स्वीकार करते हैं विफलता की

एक तर्क है कि यदि सत्र डेटा का उच्च मूल्य है तो इसे आवेदन द्वारा जारी रखा जाना चाहिए, यह वास्तव में व्यवसाय डेटा है और इसे इस तरह माना जाना चाहिए। तेजी से, क्लाउडेंट या मोंगो डीबी जैसे एनओएसक्यूएल डेटाबेस इस के लिए उपयोग किए जाते हैं। इस मामले में हम HTTP सत्र को कैश के रूप में सोच सकते हैं, इस ज्ञान में कि सत्र डेटा को त्रुटि की स्थिति में पुनर्प्राप्त किया जा सकता है।

तो मैं तर्क दूंगा कि एक शॉपिंग कार्ट के व्यापार के लिए काफी मूल्य हो सकता है; यह ग्राहकों को उन चीज़ों के विचारशील संचय का प्रतिनिधित्व करता है जिन पर वे पैसे खर्च करना चाहते हैं। इसलिए इसे जारी रखा जाना चाहिए, बल्कि सत्र में रखा जाना चाहिए। एक बार जब हम इसे जारी रखने का फैसला करते हैं, तो हम पाते हैं कि यह कई क्लाइंट उपकरणों जैसे समेकित अनुभव जैसे अन्य रोचक परिदृश्यों की ओर जाता है। ग्राहक डेस्कटॉप पीसी पर घर पर खरीदारी शुरू करता है, लेकिन ऑनलाइन खरीदारी पूरी करता है।

तो एक और सिद्धांत:

3)। HTTP सत्र का अधिक उपयोग न करें क्योंकि यह वहां है। डेटा के व्यावसायिक मूल्य पर विचार करें और क्या इसे जारी रखा जाना चाहिए।

+0

आप सही हैं। मैंने गलती से समझा था कि पूरे सत्र वस्तुओं को सत्र मानचित्र में सहेजा जा रहा है और सत्र मानचित्र को क्लाइंट को भेजा जा रहा है जहां इसे कुकीज़ या छिपे हुए क्षेत्र के रूप में संग्रहीत किया जाता है। इसके बजाय यह सत्र आईडी है जिसे क्लाइंट को भेजा जा रहा है। अगर मैं सही ढंग से समझता हूं, तो इस सत्र आईडी का उपयोग उस विशेष वेब सत्र के लिए सभी विशेषताओं को संग्रहीत करने वाले HttpSession के उदाहरण को पुनर्प्राप्त करने के लिए किया जा सकता है, है ना? मेरी गलतफहमी को इंगित करने के लिए धन्यवाद। – SibzTer

+0

हाय, मुझे पता है कि आपके पास लंबे समय से सवाल है कि आपने सवाल का जवाब दिया लेकिन आपने क्लस्टर पर्यावरण के बारे में कुछ दिलचस्प कहा। यदि सत्र में अनुरोध सर्वर का सहेजा गया है तो सत्र को इस प्रकार के आर्किटेक्चर में कैसे रखा जा सकता है? – kavain

+1

@ कवेन: अच्छा जावा-ईई सर्वर फेलओवर के लिए क्लस्टर में सत्र प्रतिकृति को अनुकूलित करने का विकल्प प्रदान करता है। वे सर्वरों को समूहों में कॉन्फ़िगर करने की अनुमति देते हैं, इसलिए सभी सर्वरों को सभी सत्र जानकारी नहीं मिलती है। केवल वही समूह जो हैं। प्रतिकृति में और स्मृति उपयोग में प्रदर्शन के लिए बेहतर है। तो उदा। 100 सर्वरों पर 100k के सत्र आकार के साथ 1.000.000 उपयोगकर्ता होने का मतलब यह नहीं होगा कि प्रत्येक सर्वर को 100GB की स्मृति की आवश्यकता होगी। 3 के समूहों में विघटित, प्रत्येक सर्वर के लिए केवल 3 जीबी की आवश्यकता होगी। और 100k का सत्र आकार बड़ा है ... – Kukeltje

2

तो जो विधि आप सुझाव है कि मैं का उपयोग करें - सत्र सेम या sessionmap एक सत्र के लिए अनुरोधों के बीच पहुँच के लिए वस्तुओं को बचाने के लिए scoped?

ये दो चीजें एक ही स्थान पर डेटा स्टोर करती हैं।

<managed-bean> 
    <managed-bean-class>foo.Bar</managed-bean-class> 
    <managed-bean-name>bar</managed-bean-name> 
    <managed-bean-scope>session</managed-bean-scope> 
</managed-bean> 

एक बार एक अभिव्यक्ति में संदर्भित, आप "बार" external context के माध्यम से प्रोग्राम के रूप में देखने के कर सकते हैं।

FYI करें: JSF2 में, घोषणा से हटाया जा सकता है और प्रतिस्थापित एनोटेशन के साथ:

@ManagedBean(name="bar") @SessionScoped 
public class Bar { 
... 
+0

मुझे जेएसएफ को छुआ जाने के बाद लगभग 3 साल स्वीकार करना होगा। उसके बाद मैं बस एक सत्र स्कोप्ड प्रबंधित बीन का उपयोग करता हूं, जैसा कि आप दिखाते हैं उतना ही। मैंने उस समय किसी भी वैकल्पिकता पर विचार नहीं किया था। मुझे लगता है कि एक मुद्दा यह सुनिश्चित करने के लिए हो सकता है कि हम यह साफ रखें, धीरे-धीरे सत्र-स्कोप्ड प्रबंधित बीन्स को बहुत से नहीं करना चाहते हैं। सावधानीपूर्वक बीन नामों को चुनने के लिए यह नीचे हो सकता है। – djna

14

मैं अपने सहयोगियों के साथ विश्वविद्यालय की एक परियोजना पर काम कर रहा हूँ, GoogleImage लेबलर की तरह एक वेब है। ठीक है, तो हमारे पास एक उपयोगकर्ता नियंत्रक है, इसकी विधियों लॉगिन, लॉगआउट, आदि के साथ ...और हम गुंजाइश इस तरह सत्र:

@ManagedBean(name = "userController") 
@SessionScoped 

ठीक है, यह है कि क्या NetBeans के जादूगर आपके लिए बनाई गई है।

बनाने और सत्र के प्रबंधन की हमारी तरीका है:

रजिस्टर विधि (जिसमें हम XHTML में फार्म की विशेषताओं का उपयोग ...) हम डीबी और उसके बाद में उपयोगकर्ता जारी रहती है पर हम सत्र में मान जोड़ते हैं:

FacesContext context = FacesContext.getCurrentInstance(); 
context.getExternalContext().getSessionMap().put("user", current); 

जहां "वर्तमान" उपयोगकर्ता है (लॉग इन उपयोगकर्ता, ज़ाहिर है)। हमारे पास लॉगिन विधि पर समान है।

FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); 

मुझे आशा है कि इस मदद करता है:

लॉगआउट विधि हम पर

+2

यह बेकार है। बस 'Current' को' UserController 'की संपत्ति के रूप में असाइन करें (जैसा कि यह * पहले से ही * सत्र स्कोप में है!) और लॉगआउट पर इसे' शून्य 'पर सेट करें (या बेहतर,' बाहरी कॉन्टेक्स्ट # अमान्य सत्र() '। Http: //stackoverflow.com/questions/3841361/jsf-http-session-login/3842060#3842060 – BalusC

+0

मैंने अपने कोड को एक @alusC के साथ बदलने के लिए पोस्ट संपादित किया है। मैंने 'FacesContext संदर्भ = FacesContext.getCurrentInstance (); context.getExternalContext()। GetSessionMap()। हटाएं ("उपयोगकर्ता"); 'FacesContext.getCurrentInstance() के लिए। GetExternalContext()। अवैध करें सत्र();' –