किसी भी सर्वलेट संबंधित वर्ग में नाम से JSF प्रबंधित बीन प्राप्त करें


101

मैं एक कस्टम सर्वलेट (AJAX / JSON के लिए) लिखने की कोशिश कर रहा हूं जिसमें मैं अपने @ManagedBeansनाम से संदर्भ लेना चाहूंगा । मैं नक्शे की उम्मीद कर रहा हूँ:

http://host/app/myBean/myProperty

सेवा:

@ManagedBean(name="myBean")
public class MyBean {
    public String getMyProperty();
}

क्या एक नियमित सर्वलेट से नाम से बीन लोड करना संभव है? क्या कोई JSF सर्वलेट या हेल्पर है जो मैं इसके लिए उपयोग कर सकता हूं?

मुझे लगता है कि वसंत से खराब हो रहा है जिसमें यह सब बहुत स्पष्ट है।


मुझे यकीन नहीं है कि आप JSF / EL के बाहर इन नए एनोटेशन का उपयोग कर सकते हैं, लेकिन मैं JSR 299 कल्पना को देखकर शुरू करूँगा: jcp.org/en/jsr/detail?id=299
McDowell

इसी तरह के मुद्दों की समस्या वाले अन्य लोग भी bpcatalog.dev.java.net/ajax/jsf-ajax (AJAX और अनुरोध मैपिंग / हैंडलिंग से संबंधित, नाम से सेम नहीं मिल रहा है) की जांच कर सकते हैं
कोनराड ग्रास

जवाबों:


263

सर्वलेट आधारित कलाकृतियों में, जैसे @WebServlet, @WebFilterऔर @WebListener, आप "सादे वेनिला" जेएसएफ @ManagedBean @RequestScopedद्वारा हड़प सकते हैं :

Bean bean = (Bean) request.getAttribute("beanName");

और इसके @ManagedBean @SessionScopedद्वारा:

Bean bean = (Bean) request.getSession().getAttribute("beanName");

और इसके @ManagedBean @ApplicationScopedद्वारा:

Bean bean = (Bean) getServletContext().getAttribute("beanName");

ध्यान दें कि यह पूर्वापेक्षा करता है कि सेम पहले से ही JSF द्वारा पहले से ही निरुपित है। इनसे वापसी होगी null। फिर आपको मैन्युअल रूप से बीन बनाने और उपयोग करने की आवश्यकता होगी setAttribute("beanName", bean)


यदि आप @NamedJSF 2.3 के बाद से CDI का उपयोग करने में सक्षम हैं @ManagedBean, तो यह और भी आसान है, विशेष रूप से क्योंकि आपको अब सेम को मैन्युअल रूप से बनाने की आवश्यकता नहीं है:

@Inject
private Bean bean;

ध्यान दें कि जब आप उपयोग कर रहे हैं तो यह काम नहीं करेगा @Named @ViewScopedक्योंकि बीन को केवल JSF व्यू स्टेट द्वारा पहचाना जा सकता है और यह केवल तब ही उपलब्ध होता है जब FacesServletइसे लागू किया गया हो। तो एक फिल्टर में जो इससे पहले चलता है, एक @Injectएड तक पहुंच @ViewScopedहमेशा फेंक देगा ContextNotActiveException


केवल जब आप अंदर हों @ManagedBean, तब आप उपयोग कर सकते हैं @ManagedProperty:

@ManagedProperty("#{bean}")
private Bean bean;

ध्यान दें कि यह एक के अंदर काम नहीं करता है @Namedया @WebServletया किसी अन्य विरूपण साक्ष्य। यह वास्तव में @ManagedBeanकेवल अंदर काम करता है ।


यदि आप अंदर नहीं हैं @ManagedBean, लेकिन FacesContextआसानी से उपलब्ध है (यानी FacesContext#getCurrentInstance()वापस नहीं आता है null), तो आप भी उपयोग कर सकते हैंApplication#evaluateExpressionGet() :

FacesContext context = FacesContext.getCurrentInstance();
Bean bean = context.getApplication().evaluateExpressionGet(context, "#{beanName}", Bean.class);

जिसे निम्नानुसार अनुभव किया जा सकता है:

@SuppressWarnings("unchecked")
public static <T> T findBean(String beanName) {
    FacesContext context = FacesContext.getCurrentInstance();
    return (T) context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);
}

और निम्नानुसार इस्तेमाल किया जा सकता है:

Bean bean = findBean("bean");

यह सभी देखें:


9
आप बीन को इंजेक्ट करने के बारे में दूसरा सुझाव दे रहे हैं, यह बहुत आश्चर्यजनक था कि मैंने इसे पूरी तरह से अनदेखा कर दिया था। हमेशा की तरह, आपकी प्रतिक्रिया पूरी तरह से बिंदु पर है। एसओ पर यहां आपके काम के लिए बहुत बहुत धन्यवाद।
jnt30

2
इस बीच (JSF 2.2 के रूप में बोलना) ऐसा लगता है कि विधि मूल्यांकनExpressionGet को तीसरे पैरामीटर के साथ बढ़ाया गया था, जो अपेक्षित वर्ग को निर्दिष्ट करने की अनुमति देता है, इसलिए कास्टिंग अब आवश्यक नहीं होगी। PostBean bean = context.getApplication().evaluateExpressionGet(context, "#{beanName}", PostBean.class);
मार्क जुचली

1
@Marc: शुरू से रहा है। क्या मुझे लगता है कि एक नकलची गलती से सिर्फ एक बचा था। उत्तर सही कर दिया गया है। अधिसूचित करने के लिए धन्यवाद।
बालुसक

FacesContextभले ही staticउपयोगिता विधि findBean()एक सादे जावा वर्ग के अंदर परिभाषित हो। यह एक सादे जावा वर्ग में कैसे उपलब्ध है जिसे JSF द्वारा प्रबंधित नहीं किया गया है?
टिनी

1
@ छोटे: यह बदले में एक ही धागे के भीतर एक जेएसएफ विरूपण साक्ष्य द्वारा बुलाया जाता है।
बालुसक

11

मैं निम्नलिखित विधि का उपयोग करता हूं:

public static <T> T getBean(final String beanName, final Class<T> clazz) {
    ELContext elContext = FacesContext.getCurrentInstance().getELContext();
    return (T) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, beanName);
}

इससे मुझे टाइप की गई वस्तु वापस मिल सकती है।


3
यह पहले से ही वर्तमान में स्वीकृत उत्तर और यहां तक ​​कि अधिक सुविधाजनक तरीके से कवर किया गया है ( Classतर्क इस निर्माण में अनावश्यक है)।
बालुसक

3

क्या आपने इस लिंक पर दृष्टिकोण की कोशिश की है? मुझे यकीन नहीं है कि अगर createValueBinding()अभी भी उपलब्ध है, लेकिन इस तरह का कोड एक सादे पुराने सर्वलेट से सुलभ होना चाहिए। यह बीन पहले से मौजूद है।

http://www.coderanch.com/t/211706/JSF/java/access-managed-bean-JSF-from

 FacesContext context = FacesContext.getCurrentInstance();  
 Application app = context.getApplication();
 // May be deprecated
 ValueBinding binding = app.createValueBinding("#{" + expr + "}"); 
 Object value = binding.getValue(context);

यह शायद एक नियमित सर्वलेट में काम नहीं करेगा। FacesContext JSF जीवनचक्र (आमतौर पर FacesServlet) द्वारा स्थापित प्रति-अनुरोध थ्रेड-लोकल आर्टिफैक्ट है।
मैकडॉवेल

7
4 साल पहले JSF 1.2 से वैल्यूबाइंडिंग को हटा दिया गया है।
बालुसक

@ बाल्सक: यह दिखाता है कि मैं आज तक कैसे योग्य हूं। एक खोज पर, अनुसंधान तकनीकों के लिए एक खोज इंजन का उपयोग करके सभी पुरानी जानकारी के साथ उल्टा हो रहा है। @ मैकडॉवेल: यह वास्तव में समझ में आता है। मैं सिर्फ एक परीक्षण करता हूं कि क्या होता है।
जेम्स पी।

3

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

public static Object getBean(String beanName){
    Object bean = null;
    FacesContext fc = FacesContext.getCurrentInstance();
    if(fc!=null){
         ELContext elContext = fc.getELContext();
         bean = elContext.getELResolver().getValue(elContext, null, beanName);
    }

    return bean;
}

मैं एक सर्वलेट से यह करने की कोशिश करता हूं, लेकिन यह काम नहीं करता है।
फर्नांडो पाई

0

मेरी एक ही आवश्यकता थी।

मैंने इसे प्राप्त करने के लिए नीचे दिए गए तरीके का उपयोग किया है।

मैं सत्र scoped बीन था।

@ManagedBean(name="mb")
@SessionScopedpublic 
class ManagedBean {
     --------
}

मैंने नीचे दिए गए कोड का उपयोग अपने सर्वलेट doPost () विधि में किया है।

ManagedBean mb = (ManagedBean) request.getSession().getAttribute("mb");

इसने मेरी समस्या हल कर दी।


आप किस तरह के सर्वलेट का उपयोग करते हैं? मेट
फर्नांडो पाई

1
यह HttpServlet है।
अनिल

-1

मैं इसका उपयोग करता हूं:

public static <T> T getBean(Class<T> clazz) {
    try {
        String beanName = getBeanName(clazz);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        return facesContext.getApplication().evaluateExpressionGet(facesContext, "#{" + beanName + "}", clazz);
    //return facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, nomeBean);
    } catch (Exception ex) {
        return null;
    }
}

public static <T> String getBeanName(Class<T> clazz) {
    ManagedBean managedBean = clazz.getAnnotation(ManagedBean.class);
    String beanName = managedBean.name();

    if (StringHelper.isNullOrEmpty(beanName)) {
        beanName = clazz.getSimpleName();
        beanName = Character.toLowerCase(beanName.charAt(0)) + beanName.substring(1);
    }

    return beanName;
}

और फिर कॉल करें:

MyManageBean bean = getBean(MyManageBean.class);

इस तरह आप अपने कोड को रिफलेक्टर कर सकते हैं और बिना किसी समस्या के उपयोग को ट्रैक कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.