एक्शन और एक्शनलिस्ट के बीच अंतर


जवाबों:


583

ActionListener

actionListenerयदि आप चाहते हैं कि वास्तविक व्यवसाय क्रिया निष्पादित होने से पहले आपको हुक का उपयोग करना है , जैसे कि इसे लॉग इन करने के लिए, और / या एक अतिरिक्त संपत्ति (द्वारा <f:setPropertyActionListener>) सेट करने के लिए , और / या उस घटक तक पहुंच हो, जिसने कार्रवाई को लागू किया (जो उपलब्ध है) ActionEventबहस)। इसलिए, वास्तविक व्यावसायिक कार्रवाई से पहले उद्देश्यों को तैयार करने के लिए विशुद्ध रूप से।

actionListenerविधि डिफ़ॉल्ट निम्नलिखित हस्ताक्षर से है:

import javax.faces.event.ActionEvent;
// ...

public void actionListener(ActionEvent event) {
    // ...
}

और इसे बिना किसी विधि कोष्ठक के घोषित किया जाना चाहिए:

<h:commandXxx ... actionListener="#{bean.actionListener}" />

ध्यान दें कि आप EL 2.2 द्वारा अतिरिक्त तर्क नहीं दे सकते । हालाँकि, आप ActionEventकस्टम तर्क को पास और निर्दिष्ट करके तर्क को पूरी तरह से ओवरराइड कर सकते हैं । निम्नलिखित उदाहरण मान्य हैं:

<h:commandXxx ... actionListener="#{bean.methodWithoutArguments()}" />
<h:commandXxx ... actionListener="#{bean.methodWithOneArgument(arg1)}" />
<h:commandXxx ... actionListener="#{bean.methodWithTwoArguments(arg1, arg2)}" />
public void methodWithoutArguments() {}
public void methodWithOneArgument(Object arg1) {}
public void methodWithTwoArguments(Object arg1, Object arg2) {}

तर्कहीन विधि अभिव्यक्ति में कोष्ठकों के महत्व पर ध्यान दें। यदि वे अनुपस्थित थे, तो JSF ActionEventतर्क के साथ एक विधि की उम्मीद करेगा ।

यदि आप ईएल 2.2+ पर हैं, तो आप कई एक्शन श्रोता तरीकों को घोषित कर सकते हैं <f:actionListener binding>

<h:commandXxx ... actionListener="#{bean.actionListener1}">
    <f:actionListener binding="#{bean.actionListener2()}" />
    <f:actionListener binding="#{bean.actionListener3()}" />
</h:commandXxx>
public void actionListener1(ActionEvent event) {}
public void actionListener2() {}
public void actionListener3() {}

bindingविशेषता में कोष्ठकों के महत्व पर ध्यान दें । यदि वे अनुपस्थित थे, तो ईएल भ्रमित रूप से एक फेंक देगा javax.el.PropertyNotFoundException: Property 'actionListener1' not found on type com.example.Bean, क्योंकि bindingविशेषता डिफ़ॉल्ट अभिव्यक्ति द्वारा एक मूल्य अभिव्यक्ति के रूप में है, न कि एक विधि अभिव्यक्ति के रूप में। ईएल 2.2+ स्टाइल कोष्ठक को पारदर्शी रूप से जोड़ने से एक मूल्य अभिव्यक्ति एक विधि अभिव्यक्ति में बदल जाती है। यह भी देखें कि यदि मैं JSF द्वारा समर्थित नहीं है, तो मैं <f: ActionListener> को एक मनमानी विधि से क्यों बांध सकता / सकती हूं?


कार्य

का प्रयोग करें actionयदि आप एक व्यवसाय कार्रवाई और यदि आवश्यक हो तो संभाल नेविगेशन पर अमल करना चाहते हैं। actionविधि (इस प्रकार, नहीं होना चाहिए) एक लौट सकते हैं Stringजो के रूप में नेविगेशन मामले परिणाम (लक्ष्य दृश्य) का उपयोग किया जाएगा। का वापसी मान nullया voidइसे उसी पृष्ठ पर वापस जाने देगा और वर्तमान दृश्य क्षेत्र को जीवित रखेगा। खाली स्ट्रिंग या समान व्यू आईडी का रिटर्न वैल्यू भी उसी पेज पर वापस आ जाएगा, लेकिन व्यू स्कोप को फिर से बनाएँ और इस प्रकार किसी भी सक्रिय स्कॉप्ड बीन्स को नष्ट करें और यदि लागू हो तो उन्हें फिर से बनाएँ।

actionविधि किसी भी मान्य हो सकता है MethodExpression, यह भी लोगों को जो 2.2 तर्क इस तरह के नीचे के रूप में ईएल उपयोग करता है:

<h:commandXxx value="submit" action="#{bean.edit(item)}" />

इस विधि के साथ:

public void edit(Item item) {
    // ...
}

ध्यान दें कि जब आपकी एक्शन विधि पूरी तरह से एक स्ट्रिंग लौटाती है, तो आप केवल उस स्ट्रिंग को actionविशेषता में निर्दिष्ट कर सकते हैं । इस प्रकार, यह पूरी तरह से अनाड़ी है:

<h:commandLink value="Go to next page" action="#{bean.goToNextpage}" />

इस संवेदनहीन विधि के साथ एक हार्डकोड स्ट्रिंग वापस करना:

public String goToNextpage() {
    return "nextpage";
}

इसके बजाय, बस उस हार्डकोड स्ट्रिंग को सीधे विशेषता में रखें:

<h:commandLink value="Go to next page" action="nextpage" />

कृपया ध्यान दें कि यह बदले में एक खराब डिज़ाइन को इंगित करता है: POST द्वारा नेविगेट करना। यह उपयोगकर्ता और न ही एसईओ के अनुकूल नहीं है। यह सब तब बताया गया है जब मुझे h का उपयोग करना चाहिए: outputLink के बजाय h: कमांडलाइंक? और के रूप में हल किया जाना चाहिए है

<h:link value="Go to next page" outcome="nextpage" />

यह भी देखें कि JSF में नेविगेट कैसे करें? URL को वर्तमान पृष्ठ (और पिछले नहीं) को कैसे प्रतिबिंबित किया जाए


एफ: अजाक्स श्रोता

के बाद से JSF 2.x वहाँ एक तीसरा रास्ता है, <f:ajax listener>

<h:commandXxx ...>
    <f:ajax listener="#{bean.ajaxListener}" />
</h:commandXxx>

ajaxListenerविधि डिफ़ॉल्ट निम्नलिखित हस्ताक्षर से है:

import javax.faces.event.AjaxBehaviorEvent;
// ...

public void ajaxListener(AjaxBehaviorEvent event) {
    // ...
}

मोअज़रा में, AjaxBehaviorEventतर्क वैकल्पिक है, नीचे अच्छा काम करता है।

public void ajaxListener() {
    // ...
}

लेकिन MyFaces में, यह एक फेंक देगा MethodNotFoundException। जब आप तर्क को छोड़ना चाहते हैं, तो जेएसएफ कार्यान्वयन में दोनों काम करता है।

<h:commandXxx ...>
    <f:ajax execute="@form" listener="#{bean.ajaxListener()}" render="@form" />
</h:commandXxx>

अजाक्स श्रोताओं वास्तव में कमांड घटकों पर उपयोगी नहीं हैं। वे इनपुट पर अधिक उपयोगी होते हैं और घटकों का चयन करते हैं <h:inputXxx>/ <h:selectXxx>। कमांड घटकों में, स्पष्टता और बेहतर स्व-दस्तावेजीकरण कोड के लिए बस action/ actionListenerऔर चिपकाएँ। इसके अलावा, जैसे actionListener, f:ajax listenerएक नेविगेशन परिणाम लौटने का समर्थन नहीं करता है।

<h:commandXxx ... action="#{bean.action}">
    <f:ajax execute="@form" render="@form" />
</h:commandXxx>

ऑन executeऔर renderएट्रिब्यूट्स के स्पष्टीकरण के लिए , हेड टू अंडरस्टैंडिंग प्राइमफेस प्रोसेस / अपडेट और JSF f: ajax execute / रेंडर विशेषताएँ


मंगलाचरण आदेश

actionListenerरों हमेशा लागू कर रहे हैं इससे पहले किaction के रूप में वे दृश्य में घोषित किया गया हैं और घटक से जुड़ी एक ही क्रम में। f:ajax listenerहमेशा शुरू हो जाती है इससे पहले किसी भी कार्रवाई श्रोता। तो, निम्न उदाहरण:

<h:commandButton value="submit" actionListener="#{bean.actionListener}" action="#{bean.action}">
    <f:actionListener type="com.example.ActionListenerType" />
    <f:actionListener binding="#{bean.actionListenerBinding()}" />
    <f:setPropertyActionListener target="#{bean.property}" value="some" />
    <f:ajax listener="#{bean.ajaxListener}" />
</h:commandButton>

निम्नलिखित क्रम में विधियों का आह्वान करेंगे:

  1. Bean#ajaxListener()
  2. Bean#actionListener()
  3. ActionListenerType#processAction()
  4. Bean#actionListenerBinding()
  5. Bean#setProperty()
  6. Bean#action()

उपवाद सम्भालना

actionListenerएक विशेष अपवाद का समर्थन करता है AbortProcessingException:। यदि इस अपवाद को एक actionListenerविधि से फेंका जाता है, तो JSF किसी भी शेष एक्शन श्रोताओं और एक्शन विधि को छोड़ देगा और सीधे प्रतिक्रिया प्रस्तुत करने के लिए आगे बढ़ेगा। आपको कोई त्रुटि / अपवाद पृष्ठ दिखाई नहीं देगा, लेकिन JSF इसे लॉग करेगा। यह भी निहितार्थ होगा जब भी किसी अन्य अपवाद को एक से फेंका जा रहा हो actionListener। इसलिए, यदि आप एक व्यावसायिक अपवाद के परिणामस्वरूप पृष्ठ को एक त्रुटि पृष्ठ द्वारा अवरुद्ध करने का इरादा रखते हैं, तो आपको निश्चित रूप से actionविधि में काम करना चाहिए ।

यदि उपयोग करने का एकमात्र कारण actionListenerएक voidही पृष्ठ पर लौटने की विधि है, तो यह एक बुरा है। actionतरीकों को पूरी तरह से भी लौट सकते हैं voidक्या कुछ IDEs आप ईएल सत्यापन के माध्यम से मानना है कि यह बताने के लिए, इसके विपरीत। ध्यान दें कि प्राइमफेस शोकेस के उदाहरण इस तरह की actionListenerजगह से अटे पड़े हैं । यह वास्तव में गलत है। यह भी एक बहाने के रूप में उपयोग न करें कि स्वयं करें।

अजाक्स अनुरोधों में, हालांकि, एक विशेष अपवाद हैंडलर की आवश्यकता होती है। इस बात की परवाह किए बिना कि आप listenerविशेषता का उपयोग करते हैं <f:ajax>या नहीं। स्पष्टीकरण और एक उदाहरण के लिए, जेएसएफ एजैक्स अनुरोधों में अपवाद से निपटने के लिए हेड ।


1
आप सही कह रहे हैं कि एक्शन लिस्टरेन में अपवाद डिफ़ॉल्ट रूप से निगले जाते हैं, लेकिन JSF 2.0 में इस व्यवहार को बदला जा सकता है। विवरण के लिए नीचे मेरा उत्तर देखें।
अरजन टिज्म्स

3
@arjan: आप रहे हों तो सही है कि JSF 2.0 आप डिफ़ॉल्ट रूप से फेंक दिया अपवादों में से निपटने के बदलने की अनुमति देता actionListenerहै, लेकिन वह अभी भी यह एक अच्छा बहाना दुरुपयोग नहीं है actionListenerके लिए व्यापार कार्यों।
बालुसक

1
वास्तव में, व्यावसायिक क्रियाएं अनुरोध / प्रतिक्रिया चक्र के मुख्य "प्रवाह" में हैं और केवल उसी से actionमेल खाती हैं। actionListenerद्वितीयक सामान के लिए है। बस यह स्पष्ट करना चाहता था कि actionListenerयदि आवश्यक हो तो एस से अपवादों का प्रचार किया जा सकता है;)
अर्जन टिजम्स

2
@Kawy: विधि का नाम actionListenerविशेषता में उपयोग होने पर पसंद करने के लिए स्वतंत्र है और इसे भी होना है publicprocessActionनाम ही अनिवार्य है जब आप का उपयोग कर रहे है <f:actionListener type>, बस क्योंकि प्रकार लागू करने के लिए है ActionListenerइंटरफ़ेस जो है वही विधि नाम processActiondefinied।
बालूसक

2
@ मुहम्मद: अजाक्स एक्शन श्रोता सभी नियमित एक्शन श्रोताओं के सामने आमंत्रित किया जाता है। ध्यान दें कि उपयोग करते समय भी <f:ajax>, आप कमांड घटकों के मामले में actionव्यावसायिक कार्यों के लिए विशेषता का उपयोग करना पसंद करते हैं । जैसे <h:commandButton action="#{bean.businessAction}"><f:ajax/></h:commandButton>
बालुसक १C

47

जैसा कि BalusC ने संकेत दिया है, actionListenerडिफ़ॉल्ट रूप से अपवादों को निगलता है, लेकिन JSF 2.0 में इससे थोड़ा अधिक है। अर्थात्, यह सिर्फ निगल और लॉग नहीं करता है, लेकिन वास्तव में अपवाद प्रकाशित करता है।

यह इस तरह से एक कॉल के माध्यम से होता है:

context.getApplication().publishEvent(context, ExceptionQueuedEvent.class,                                                          
    new ExceptionQueuedEventContext(context, exception, source, phaseId)
);

इस ईवेंट के लिए डिफ़ॉल्ट श्रोता वह है ExceptionHandlerजो मोआज़रा के लिए सेट है com.sun.faces.context.ExceptionHandlerImpl। यह कार्यान्वयन मूल रूप से किसी अपवाद को हटा देगा, सिवाय इसके कि जब यह एक एबोर्टप्रोसेसिंग अपवाद की चिंता करता है, जो लॉग होता है। ActionListeners क्लाइंट कोड द्वारा ऐसे AbortProcessingException में फेंके गए अपवाद को लपेटता है, जो बताता है कि ये हमेशा लॉग इन क्यों होते हैं।

यह ExceptionHandlerएक कस्टम कार्यान्वयन के साथ चेहरे-config.xml में हालांकि बदला जा सकता है:

<exception-handlerfactory>
   com.foo.myExceptionHandler
</exception-handlerfactory>

विश्व स्तर पर सुनने के बजाय, एक एकल बीन इन घटनाओं को भी सुन सकता है। निम्नलिखित इस अवधारणा का प्रमाण है:

@ManagedBean
@RequestScoped
public class MyBean {

    public void actionMethod(ActionEvent event) {

        FacesContext.getCurrentInstance().getApplication().subscribeToEvent(ExceptionQueuedEvent.class, new SystemEventListener() {

        @Override
        public void processEvent(SystemEvent event) throws AbortProcessingException {
            ExceptionQueuedEventContext content = (ExceptionQueuedEventContext)event.getSource();
            throw new RuntimeException(content.getException());
        }

        @Override
        public boolean isListenerForSource(Object source) {
            return true;
        }
        });

        throw new RuntimeException("test");
    }

}

(ध्यान दें, यह नहीं है कि किसी को सामान्य रूप से श्रोताओं को कैसे कोड करना चाहिए, यह केवल प्रदर्शन उद्देश्यों के लिए है!)

इसे इस तरह से फेसलेट से कॉल करना:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <h:body>
        <h:form>
            <h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
        </h:form>
    </h:body>
</html>

प्रदर्शित होने में एक त्रुटि पृष्ठ होगा।


43

ActionListener पहले प्रतिक्रिया को संशोधित करने के विकल्प के साथ निकाल दिया जाता है, इससे पहले कि कार्रवाई को बुलाया जाता है और अगले पृष्ठ का स्थान निर्धारित करता है।

यदि आपके पास एक ही पृष्ठ पर एक से अधिक बटन हैं, जो एक ही स्थान पर जाने चाहिए, लेकिन थोड़े अलग काम करते हैं, तो आप प्रत्येक बटन के लिए एक ही क्रिया का उपयोग कर सकते हैं, लेकिन थोड़ी भिन्न कार्यक्षमता को संभालने के लिए एक अलग ActionListener का उपयोग करें।

यहाँ एक लिंक है जो रिश्ते का वर्णन करता है:

http://www.java-samples.com/showtutorial.php?tutorialid=605


3
प्लस एक, बोल्ड अक्षर लगभग सब कुछ कहते हैं।
शिरगिल फरहान

0

टीएल; डीआर :

जिस ActionListenerक्रम में वे पहले पंजीकृत थे उस क्रम में कई (निष्पादित) हो सकते हैंaction

लंबे उत्तर :

एक व्यवसाय actionआम तौर पर एक EJB सेवा को आमंत्रित करता है और यदि आवश्यक हो तो अंतिम परिणाम और / या किसी अन्य दृश्य में नेविगेट करता है यदि ऐसा नहीं है जो आप कर रहे हैं actionListenerवह अधिक उपयुक्त है अर्थात जब उपयोगकर्ता घटकों के साथ बातचीत करता है, जैसे कि h:commandButtonया h:linkवे कर सकते हैं actionListenerUI घटक की विशेषता में प्रबंधित बीन विधि के ActionListenerनाम को पास करके या इंटरफ़ेस को लागू करने के लिए और actionListenerUI घटक की विशेषता के कार्यान्वयन वर्ग के नाम को पास करने के द्वारा नियंत्रित किया जाता है ।

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