2012-04-17 15 views
9

मुझे यकीन नहीं है कि यहां शीर्षक को कैसे वाक्यांशित किया जाए, और इसके कारण मुझे सच में यकीन नहीं है कि उत्तर के बारे में जानने के लिए कैसे जाना है।जावा में कोई अनुरोध संदर्भ है?

मेरे पास एक जावा सर्वलेट इंजन है जो अनुरोधों को संभालता है। कहते हैं कि हम एक doGet अनुरोध किया है:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    //set up user data 

    //do whatever the user requested 
    SomeClass c = new SomeClass(); 
    c.doSomething(); 
} 

अब DoSomething में, मैं का उपयोग करने की है जो उपयोगकर्ता अनुरोध किया सक्षम होना चाहते हैं। अभी मैं यह एक जावा वस्तु बनाने और मैं जहाँ भी जरूरत के लिए यह पारित करके कर रहा हूँ:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    //set up user data 
    MyUserObj userObj = new MyUserObj(); 
    userObj.setId('123'); 

    //do whatever the user requested 
    SomeClass c = new SomeClass(userObj); 
    c.doSomething(); 
} 

ऐसा करने से, मैं MyUserObj के कहने के लिए उपयोग किया है, और यह आगे अगर जरूरत के साथ पारित किया जा सकता।

यह बेवकूफ लगता है। एएसपीएनटी एमवीसी 3 में (मैं वर्तमान में इसे सीख रहा हूं, मैंने जावा सीखना शुरू करने के बाद शुरू किया, लेकिन यह वास्तव में सुविधाजनक पाया गया जिससे मुझे पुनर्विचार कर दिया गया कि मैं जावा में यह कैसे कर रहा था) उदाहरण के लिए, मैं वर्तमान के लिए आइटम स्टोर कर सकता हूं इस तरह धागा: HttpContext.Current.Items.Add("myId", "123")HttpContext तब किसी अन्य ऑब्जेक्ट को पास किए बिना अन्य कार्यों में उपलब्ध है।

क्या जावा में पैरामीटर के माध्यम से ऑब्जेक्ट को पास किए बिना प्रति अनुरोध कुछ चर सेट करने के लिए जावा में कोई तरीका है (या बाद में एक्सेस करने के लिए MyUserObject भी सेट करें)?

यदि यह एक सामान्य पहले से उत्तर दिया गया प्रश्न है तो मुझे सही दिशा में इंगित करने के लिए स्वतंत्र महसूस करें क्योंकि मुझे यकीन नहीं था कि इसे कैसे वाक्यांशित किया जाए।

+0

मैंने आपके शीर्षक को संपादित करने की स्वतंत्रता ली। कृपया सत्यापित करें कि यह एक अच्छा है – Bozho

+0

मैं इसे स्पष्ट रूप से पास कर दूंगा, निहित राज्य और निर्भरता बनाए रखने के लिए खराब हैं। वसंत की तरह ढांचे को स्पष्ट रूप से ऐसा करने के साथ बॉयलरप्लेट और अव्यवस्था में से कुछ को हटाने में मदद करनी चाहिए। – millimoose

+0

यदि आप मेरे प्रश्न को समझते हैं तो मुझे विश्वास है कि आपके शीर्षक संपादन मेरे मूल शीर्षक से बेहतर है :) – Two13

उत्तर

19

सर्वलेट एपीआई में नहीं है, लेकिन आप अपना खुद का सुंदर आसानी से बना सकते हैं। (वसंत-एमवीसी जैसे कुछ ढांचे, स्ट्रेट्स ऐसी कार्यक्षमता प्रदान करते हैं)

ऑब्जेक्ट को स्टोर और पुनर्प्राप्त करने के लिए बस public static ThreadLocal का उपयोग करें। आप HttpServletRequest को थ्रेडलोकल में भी स्टोर कर सकते हैं और setAttribute()/getAttribute() विधियों का उपयोग कर सकते हैं, या आप सर्वलेट एपीआई के अज्ञेयवादी होने के लिए थ्रेडलोकल Map स्टोर कर सकते हैं। एक महत्वपूर्ण नोट यह है कि अनुरोध के बाद आपको थ्रेडलोकल को साफ करना चाहिए (उदाहरण के लिए, फ़िल्टर के साथ)।

यह भी ध्यान रखें कि ऑब्जेक्ट को पैरामीटर के रूप में पास करना बेहतर अभ्यास माना जाता है, क्योंकि आप आमतौर पर इसे वेब परत से सेवा परत तक पास करते हैं, जो HttpContext जैसे वेब-संबंधित ऑब्जेक्ट पर निर्भर नहीं होना चाहिए।

आप तय करते हैं कि यह उन में स्टोर करने के लिए ठीक है, तो एक धागे की स्थानीय, बल्कि उनके आसपास गुजर से:

public class RequestContext { 
    private static ThreadLocal<Map<Object, Object>> attributes = new ThreadLocal<>(); 
    public static void initialize() { 
     attributes.set(new HashMap<Map<Object, Object>>()); 
    } 
    public static void cleanup() { 
     attributes.set(null); 
    } 
    public static <T> T getAttribute(Object key) { 
     return (T) attributes.get().get(key); 
    } 
    public static void setAttribute(Object key, Object value) { 
     attributes.get().put(key, value); 
    } 
} 

और एक आवश्यक फिल्टर:

@WebFilter(urlPatterns="/") 
public class RequestContextFilter implements Filter { 
    public void doFilter(..) { 
     RequestContext.initialize(); 
     try { 
      chain.doFilter(request, response); 
     } finally { 
      RequestContext.cleanup(); 
     } 
    } 
} 
+2

क्या 'ServletRequest.setAttribute' के बारे में? –

+2

आपको तब अनुरोध पास करना होगा। मुझे लगता है कि ओपी क्या चाहता है यह नहीं है। मैंने इसे विकल्प के रूप में जोड़ा, जिसे अभी भी थ्रेडलोकल की आवश्यकता होगी हालांकि – Bozho

+0

आह, अच्छा बिंदु, 'HttpContext.Current' के लिए कोई एनालॉग नहीं है। –

4

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

+0

क्या मुझे ServletRequest ऑब्जेक्ट को पैरामीटर के रूप में पास नहीं करना होगा? – Two13

+0

आप करेंगे। हालांकि, अगर आप शुरू करने के अनुरोध के आसपास गुजर रहे हैं, तो आप अन्य अनुरोध संबंधी वस्तुओं के आसपास गुजरने से बच सकते हैं। – ataylor

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