जवाबों:
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>
निम्नलिखित क्रम में विधियों का आह्वान करेंगे:
Bean#ajaxListener()
Bean#actionListener()
ActionListenerType#processAction()
Bean#actionListenerBinding()
Bean#setProperty()
Bean#action()
actionListener
एक विशेष अपवाद का समर्थन करता है AbortProcessingException
:। यदि इस अपवाद को एक actionListener
विधि से फेंका जाता है, तो JSF किसी भी शेष एक्शन श्रोताओं और एक्शन विधि को छोड़ देगा और सीधे प्रतिक्रिया प्रस्तुत करने के लिए आगे बढ़ेगा। आपको कोई त्रुटि / अपवाद पृष्ठ दिखाई नहीं देगा, लेकिन JSF इसे लॉग करेगा। यह भी निहितार्थ होगा जब भी किसी अन्य अपवाद को एक से फेंका जा रहा हो actionListener
। इसलिए, यदि आप एक व्यावसायिक अपवाद के परिणामस्वरूप पृष्ठ को एक त्रुटि पृष्ठ द्वारा अवरुद्ध करने का इरादा रखते हैं, तो आपको निश्चित रूप से action
विधि में काम करना चाहिए ।
यदि उपयोग करने का एकमात्र कारण actionListener
एक void
ही पृष्ठ पर लौटने की विधि है, तो यह एक बुरा है। action
तरीकों को पूरी तरह से भी लौट सकते हैं void
क्या कुछ IDEs आप ईएल सत्यापन के माध्यम से मानना है कि यह बताने के लिए, इसके विपरीत। ध्यान दें कि प्राइमफेस शोकेस के उदाहरण इस तरह की actionListener
जगह से अटे पड़े हैं । यह वास्तव में गलत है। यह भी एक बहाने के रूप में उपयोग न करें कि स्वयं करें।
अजाक्स अनुरोधों में, हालांकि, एक विशेष अपवाद हैंडलर की आवश्यकता होती है। इस बात की परवाह किए बिना कि आप listener
विशेषता का उपयोग करते हैं <f:ajax>
या नहीं। स्पष्टीकरण और एक उदाहरण के लिए, जेएसएफ एजैक्स अनुरोधों में अपवाद से निपटने के लिए हेड ।
actionListener
है, लेकिन वह अभी भी यह एक अच्छा बहाना दुरुपयोग नहीं है actionListener
के लिए व्यापार कार्यों।
action
मेल खाती हैं। actionListener
द्वितीयक सामान के लिए है। बस यह स्पष्ट करना चाहता था कि actionListener
यदि आवश्यक हो तो एस से अपवादों का प्रचार किया जा सकता है;)
actionListener
विशेषता में उपयोग होने पर पसंद करने के लिए स्वतंत्र है और इसे भी होना है public
। processAction
नाम ही अनिवार्य है जब आप का उपयोग कर रहे है <f:actionListener type>
, बस क्योंकि प्रकार लागू करने के लिए है ActionListener
इंटरफ़ेस जो है वही विधि नाम processAction
definied।
<f:ajax>
, आप कमांड घटकों के मामले में action
व्यावसायिक कार्यों के लिए विशेषता का उपयोग करना पसंद करते हैं । जैसे <h:commandButton action="#{bean.businessAction}"><f:ajax/></h:commandButton>
।
जैसा कि 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>
प्रदर्शित होने में एक त्रुटि पृष्ठ होगा।
ActionListener पहले प्रतिक्रिया को संशोधित करने के विकल्प के साथ निकाल दिया जाता है, इससे पहले कि कार्रवाई को बुलाया जाता है और अगले पृष्ठ का स्थान निर्धारित करता है।
यदि आपके पास एक ही पृष्ठ पर एक से अधिक बटन हैं, जो एक ही स्थान पर जाने चाहिए, लेकिन थोड़े अलग काम करते हैं, तो आप प्रत्येक बटन के लिए एक ही क्रिया का उपयोग कर सकते हैं, लेकिन थोड़ी भिन्न कार्यक्षमता को संभालने के लिए एक अलग ActionListener का उपयोग करें।
यहाँ एक लिंक है जो रिश्ते का वर्णन करता है:
टीएल; डीआर :
जिस ActionListener
क्रम में वे पहले पंजीकृत थे उस क्रम में कई (निष्पादित) हो सकते हैंaction
लंबे उत्तर :
एक व्यवसाय action
आम तौर पर एक EJB सेवा को आमंत्रित करता है और यदि आवश्यक हो तो अंतिम परिणाम और / या किसी अन्य दृश्य में नेविगेट करता है यदि ऐसा नहीं है जो आप कर रहे हैं actionListener
वह अधिक उपयुक्त है अर्थात जब उपयोगकर्ता घटकों के साथ बातचीत करता है, जैसे कि h:commandButton
या h:link
वे कर सकते हैं actionListener
UI घटक की विशेषता में प्रबंधित बीन विधि के ActionListener
नाम को पास करके या इंटरफ़ेस को लागू करने के लिए और actionListener
UI घटक की विशेषता के कार्यान्वयन वर्ग के नाम को पास करने के द्वारा नियंत्रित किया जाता है ।