2011-01-21 13 views
7

क्या पीओजेओ से सत्र पुनर्प्राप्त करने का कोई तरीका है? या अंत में एक पीओजेओ से एक बीन पुनर्प्राप्त करने के लिए।कंटेनर के बाहर POJO में सर्वलेट संदर्भ, सत्र और अनुरोध पुनर्प्राप्त करना

स्पष्ट करने के लिए:

मूल रूप से मैं एक सर्वलेट से एक सेम बनाने रहा हूँ और मैं (एक POJO से) वेब कंटेनर के बाहर से है कि सेम के गुणों का उपयोग करने की जरूरत है। मैं pojo के लिए अनुरोध पास नहीं कर सकता; और सत्र को पुनर्प्राप्त करने के लिए अनुरोध की आवश्यकता है।

अधिक विशेष रूप से मैं एक वेब इंटरफेस से JUnit परीक्षण चलाने के लिए कैक्टस ढांचे का उपयोग करता है एक वेब अनुप्रयोग है। हालांकि जुनीट टेस्ट रनर का आह्वान करने वाला सर्वलेट एक जार में संकलित किया जाता है; मैंने सेटिंग्स को बदलने के लिए मेनू को अतिरिक्त ड्रॉप डाउन जोड़ा, जिसमें से जुनीट टेस्ट अलग-अलग वातावरण (डब्लूएलआई क्लस्टर) के बीच स्विच करने के लिए पढ़ेगा, इसलिए दिया गया कि धावक सर्वलेट पहले ही संकलित है, मैं इसे कई वातावरण से अतिरिक्त पैरामीटर को संभालने के लिए संशोधित नहीं कर सकता। मैंने एक .dat फ़ाइल को लिखने के दृढ़ दृष्टिकोण की कोशिश की है जिसके लिए जुनीट टेस्ट रीडर क्लास के माध्यम से पढ़ेगा; मैंने बीन दृष्टिकोण की भी कोशिश की है जो आखिरकार जुनीट टेस्ट से उपलब्ध नहीं था।

+0

क्या आप अपनी समस्या पर थोड़ा सा विस्तार कर सकते हैं? – Sid

+0

अपनी समस्या का बेहतर वर्णन करें। स्पष्ट रूप से आपके पास एक वेब एप्लिकेशन है जो डेटा में हेरफेर कर रहा है। ऐसा प्रतीत होता है कि आपको इसे स्टोर करने की आवश्यकता है और फिर उसे वेब एप्लिकेशन के बाहरी संदर्भित करना होगा। – DwB

+0

ठीक ऊपर संपादन देखें, धन्यवाद। – TheWolf

उत्तर

11

केवल और केवल यदि आपके POJO HttpServletRequest रूप ही धागा में चल रहा है में चल रहा है, तो आप ThreadLocal<T> की मदद से इस लक्ष्य को हासिल करने में सक्षम होंगे।

निम्नलिखित वर्ग बनाएँ:

public final class YourContext implements AutoCloseable { 

    private static ThreadLocal<YourContext> instance = new ThreadLocal<>(); 

    private HttpServletRequest request; 
    private HttpServletResponse response; 

    private YourContext(HttpServletRequest request, HttpServletResponse response) { 
     this.request = request; 
     this.response = response; 
    } 

    public static YourContext create(HttpServletRequest request, HttpServletResponse response) { 
     YourContext context = new YourContext(request, response); 
     instance.set(context); 
     return context; 
    } 

    public static YourContext getCurrentInstance() { 
     return instance.get(); 
    } 

    @Override  
    public void close() { 
     instance.remove(); 
    } 

    public HttpServletRequest getRequest() { 
     return request; 
    } 

    public HttpSession getSession() { 
     return request.getSession(); 
    } 

    public ServletContext getServletContext() { 
     return request.getServletContext(); 
    } 

    // ... (add if necessary more methods here which return/delegate the request/response).  
} 

लागू javax.servlet.Filter जो doFilter() विधि में निम्नलिखित करता है और ब्याज है, उदा के url-pattern पर मैप किया गया है /* या आपके फ्रंट कंट्रोलर सर्वलेट के servlet-name पर।

@Override 
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException { 
    HttpServletRequest request = (HttpServletRequest) req; 
    HttpServletResponse response = (HttpServletResponse) res; 

    try (YourContext context = YourContext.create(request, response)) { 
     chain.doFilter(request, response); 
    } 
} 

प्रयास-संसाधन-संसाधन विवरण के महत्व पर ध्यान दें। यह गारंटी देता है कि फ़िल्टर ने अपना काम पूरा करने के बाद YourContext#close() कहा जाएगा और ThreadLocal संसाधन साफ़ कर दिया जाएगा। अन्यथा किसी अन्य HTTP अनुरोध के लिए पुनर्नवीनीकरण करते समय थ्रेड अभी भी इसमें शामिल होगा।

और यहाँ कैसे आप POJO में इसका इस्तेमाल कर सकते हैं:

YourContext context = YourContext.getCurrentInstance(); 
HttpSession session = context.getSession(); 

यह सब मूल रूप से भी कैसे औसत MVC ढांचे के Context वस्तुओं काम करता है, JSF के FacesContext और विकेट में से एक की तरह है।

ने कहा कि, क्या आपने CDI पर देखा है? शायद सीडीआई-प्रबंधित कलाकृतियों को बनाना आसान है ताकि आप उन्हें एक-दूसरे में @Inject कर सकें।

+0

धन्यवाद, यह बहुत अच्छा लगता है। टेम्पलेटेड थ्रेडलोकल किस पैकेज से संबंधित है? जेडीके देशी थ्रेडलोकल टेम्पलेट स्वीकार नहीं करता है। – TheWolf

+0

ठीक है, मैंने इसे जेडीके 6 में पाया, मैं डब्लूएलआई 8 का उपयोग कर रहा हूं इसलिए मैं जेडीके 1.4 तक सीमित हूं, क्या गैर टेम्पलेट ऑब्जेक्ट ठीक काम करेगा? – TheWolf

+1

'threadLocal 'मेरे उत्तर में लिंक' java.lang.ThreadLocal 'javadoc को इंगित करता है। मुझे यकीन नहीं है कि "टेम्पलेट्स" के साथ आपका क्या मतलब है, लेकिन यदि आप वास्तव में जेनेरिक टाइप पैरामीटर '' (और पुराने फैशन वाले "POJO" शब्द का अपना लगातार उपयोग लेते हैं) मुझे संदेह है कि आप हैं अभी तक जावा 1.5 पर नहीं है। उस स्थिति में, कोड उदाहरण में '' को छोड़ दें और लागू होने पर '(संदर्भ)' लागू करें। जावाडोक संकेत के रूप में, 'थ्रेडलोकल' 1.2 के बाद से उपलब्ध है। – BalusC

2

ए पोोजो एक सादा पुराना जावा ऑब्जेक्ट है। POJOS के पास सत्रों से कोई लेना देना नहीं है।

https सत्र अनुरोध ऑब्जेक्ट पर उपलब्ध है। इस

http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.6/api/index.html

विशेष रूप से HttpServletRequest इंटरफ़ेस

चेक बाहर, और getSession() विधि।

अपने प्रश्न का 'सेम' भाग के लिए

। एक बीन एक जावा वर्ग है जो 3 मानकों के अनुरूप है।

  1. कोई आर्ग निर्माता
  2. setters और getters निजी क्षेत्रों तक पहुँचने के लिए
  3. serializable लागू करता है।

यदि पीओजेओ उन सम्मेलनों का पालन करता है तो एक बीओओओ एक बीन है।

+0

मेरा मतलब वेब कंटेनर के बाहर एक POJO से वेब सत्र (यानी किसी प्रकार के अनुरोध से) से उत्पन्न वेब सत्र पुनर्प्राप्त करना है। (पाठ्यक्रम पीओजेओ से नहीं आ रहा है)। – TheWolf

+0

@ वेबिन कंटेनर के बाहर @ पीपीजेओ @ किसी भी तरह से, आपको डेटा को जारी रखने की आवश्यकता है, या किसी भी तरह आपको डेटा स्थानांतरित करने की आवश्यकता है –

+0

मैंने पैरामीटर को एक .dat फ़ाइल में लिखकर दृढ़ता दृष्टिकोण की कोशिश की है और मैं एक में भाग गया दौड़ की स्थिति को .dat फ़ाइल तक पहुंचने के समवर्ती अनुरोध दिए गए हैं। – TheWolf

2

यह मानते हुए कि आप सर्वलेट प्रोग्रामिंग करने के लिए बात कर रहे हैं ....

वहाँ सत्र के लिए एक POJO से प्राप्त करने के लिए कोई सीधा रास्ता नहीं है। आपको HttpServletRequest ऑब्जेक्ट से सत्र प्राप्त करने की आवश्यकता है।

2 लोकप्रिय समाधान है कि मैं इस से निपटने के लिए देखा है रहे हैं।

पहले विकल्प किसी प्रकार का है कि सत्र में शामिल है के संदर्भ वस्तु बनाने के लिए है। यह संदर्भ तब आपके व्यापार परत में पारित किया जाता है ताकि यदि आपके पीओजेओ को यह जानकारी मिलती है तो उन्हें यह जानकारी मिल सकती है।

दूसरा विकल्प ThreadLocal भंडारण लाभ उठाने के लिए है। अक्सर एक फ़िल्टर या इंटरसेप्टर द्वारा थ्रेडलोकल स्टोरेज पर सत्र रखा जाता है। फिर आपके सिस्टम में कोई ऑब्जेक्ट इसे थ्रेड से ला सकता है। यह पैटर्न स्प्रिंग और स्ट्रूट्स जैसे कई वेब ढांचे में दिखाई देता है।

+0

जरूरत है मैं संदर्भ वस्तु की जरूरत स्टेटफुल हो सकता है और सत्र की पूरी जीवन भर अपने राज्य को बनाए रखने और भी रिटर्न सेट कर सकते हैं उत्परिवर्तनीय हो, क्या यह संभव है? – TheWolf

+0

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

+0

धन्यवाद, मैंने हाल ही में अपना प्रश्न संपादित कर लिया है, कृपया आप नए संपादन की जांच कर सकते हैं। यदि आवश्यक हो तो मैं आवश्यकताओं को और समझा सकता हूं :) – TheWolf

2

हाँ, वहाँ है।

यदि आप वेब ढांचे का उपयोग कर रहे हैं, उदाहरण के लिए विकेट, वर्तमान एचटीपीशन प्राप्त करने का एक तरीका अक्सर होता है। वहां से, आप स्प्रिंग एप्लिकेशन कॉन्टेक्स्ट प्राप्त कर सकते हैं और यदि आपके पास है, तो आप इससे स्प्रिंग बीन्स प्राप्त कर सकते हैं। यह किसी भी स्थान पर काम करता है, क्योंकि हम केवल स्थिर उपयोगिता विधियों का उपयोग कर रहे हैं।

उदाहरण कोड:

import org.apache.wicket.protocol.http.WebApplication; 
import org.springframework.web.context.support.WebApplicationContextUtils; 
import org.springframework.web.context.WebApplicationContext; 

ServletContext sc = WebApplication.getServletContext(); 
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(sc); 

Object bean = wac.getBean("myBeanId"); 

नोट तथापि स्प्रिंग फ़िल्टर और विकेट फ़िल्टर जगह में हो सकता है और मौजूदा अनुरोध को पूरा करने, अन्यथा उपयोगिता तरीकों से काम नहीं चलेगा चाहिए।

यदि आप स्प्रिंग बीन्स का मतलब नहीं रखते हैं, तो आपको उन्हें HTTP सत्र में स्वयं स्टोर करना होगा। यदि आपके पास वेब ढांचा नहीं है, तो आप ऐसा करना चाहते हैं कि rfeak आपके स्वयं के थ्रेडलोकल का सुझाव दे रहा है और कार्यान्वित कर रहा है।

+0

"ऑब्जेक्ट बीन = wac.getBean (" myBeanId ");" वर्तमान सत्र से बीन पैदा करेगा क्योंकि उसके पास सत्र का दायरा है? – TheWolf

+0

नहीं, एक सत्र बीन नहीं, बल्कि आवेदन संदर्भ से एक वसंत बीन। – mhaller

+0

-1 समाधान में वसंत इंजेक्शन के लिए, इसके बिना सॉफ्टवेयर बनाना अभी भी संभव है। –

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