मैं सच में करना चाहते हैं क्या लोग इन क्या ajax अनुरोध के लिए वास्तव में है। इस तरह के रूप में विधि का नाम ajax (उदाहरण के लिए "findAddress" इस कॉल में: <p:ajax process="contactDetails" update="@form" listener="#{aboutYouController.findAddress}" ....
) द्वारा बुलाया जा रहा है
यह जानकारी JSF घटक पेड़ में ही उपलब्ध है। जेएसएफ घटक पेड़ केवल निर्माण समय देखने के बाद उपलब्ध है। एक दृश्य केवल तभी बनाया जाता है जब अनुरोध FacesServlet
द्वारा किया गया हो। इस प्रकार, एक सर्वलेट फ़िल्टर बहुत जल्दी है क्योंकि यह किसी भी सर्वलेट से पहले चलता है।
आप पोस्टबैक के पुनर्स्थापना दृश्य चरण के बाद कोड को बेहतर ढंग से चलाएंगे। जेएसएफ घटक पेड़ उस पल के दौरान उपलब्ध होने की गारंटी है। वर्तमान अनुरोध एक पोस्टबैक है या नहीं, यह देखने के लिए आप FacesContext#isPostback()
का उपयोग कर सकते हैं। यह जांचने के लिए कि वर्तमान अनुरोध अजाक्स अनुरोध है या नहीं, आप PartialViewContext#isAjaxRequest()
का उपयोग कर सकते हैं। AJAX अनुरोध के स्रोत घटक की क्लाइंट आईडी प्राप्त करने के लिए आप पूर्वनिर्धारित javax.faces.source
अनुरोध पैरामीटर का उपयोग कर सकते हैं। आप AJAX ईवेंट नाम प्राप्त करने के लिए पूर्वनिर्धारित javax.faces.behavior.event
अनुरोध पैरामीटर का उपयोग कर सकते हैं (उदा। change
, click
, action
, आदि)।
संबंधित व्यवहार श्रोताओं को प्राप्त करना बदले में एक कहानी अलग है। यह ActionSource2
घटकों (उदा। <h|p:commandButton action="#{...}">
) पर आसान है क्योंकि MethodExpression
केवल ActionSource2#getActionExpression()
द्वारा उपलब्ध है। हालांकि, BehaviorBase
टैगहैंडर्स (उदा। <f|p:ajax listener="#{...}">
) पर यह आसान नहीं है क्योंकि इस एपीआई में getBehaviorListeners()
जैसी कोई विधि नहीं है। उन्हें जोड़ने और हटाने के लिए केवल विधियां हैं, लेकिन उनमें से एक सूची प्राप्त नहीं करने के लिए। तो उन श्रोताओं के साथ private
फ़ील्ड तक पहुंचने के लिए कुछ बुरा प्रतिबिंब चालना आवश्यक है जिसका नाम जेएसएफ कार्यान्वयन विशिष्ट है। Mojarra में यह listeners
है और MyFaces में यह _behaviorListeners
है। दोनों सौभाग्य से List
से असाइन किए जा सकते हैं और यह उस प्रकार का एकमात्र क्षेत्र है, इसलिए हम इसकी जांच कर सकते हैं। एक बार BehaviorListener
उदाहरण का हाथ रखने के बाद, आप अभी भी को उस उदाहरण के MethodExpression
फ़ील्ड को प्राप्त करने के लिए एक और प्रतिबिंब चालबाजी करने की आवश्यकता है। छी।
कुल मिलाकर, यहाँ प्रवंचना एक PhaseListener
का स्वाद RESTORE_VIEW
की afterPhase
पर सुनने में की तरह लग रहे तरीका देखें:
public class AjaxActionLoggerPhaseListener implements PhaseListener {
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
@Override
public void beforePhase(PhaseEvent event) {
// NOOP.
}
@Override
public void afterPhase(PhaseEvent event) {
FacesContext context = event.getFacesContext();
if (!(context.isPostback() && context.getPartialViewContext().isAjaxRequest())) {
return; // Not an ajax postback.
}
Map<String, String> params = context.getExternalContext().getRequestParameterMap();
String sourceClientId = params.get("javax.faces.source");
String behaviorEvent = params.get("javax.faces.behavior.event");
UIComponent source = context.getViewRoot().findComponent(sourceClientId);
List<String> methodExpressions = new ArrayList<>();
if (source instanceof ClientBehaviorHolder && behaviorEvent != null) {
for (ClientBehavior behavior : ((ClientBehaviorHolder) source).getClientBehaviors().get(behaviorEvent)) {
List<BehaviorListener> listeners = getField(BehaviorBase.class, List.class, behavior);
if (listeners != null) {
for (BehaviorListener listener : listeners) {
MethodExpression methodExpression = getField(listener.getClass(), MethodExpression.class, listener);
if (methodExpression != null) {
methodExpressions.add(methodExpression.getExpressionString());
}
}
}
}
}
if (source instanceof ActionSource2) {
MethodExpression methodExpression = ((ActionSource2) source).getActionExpression();
if (methodExpression != null) {
methodExpressions.add(methodExpression.getExpressionString());
}
}
System.out.println(methodExpressions); // Do your thing with it.
}
private static <C, F> F getField(Class<? extends C> classType, Class<F> fieldType, C instance) {
try {
for (Field field : classType.getDeclaredFields()) {
if (field.getType().isAssignableFrom(fieldType)) {
field.setAccessible(true);
return (F) field.get(instance);
}
}
} catch (Exception e) {
// Handle?
}
return null;
}
}
ताकि इसे चलाने रजिस्टर faces-config.xml
में नीचे के रूप में करने के लिए प्राप्त करने के लिए:
<lifecycle>
<phase-listener>com.example.AjaxActionLoggerPhaseListener</phase-listener>
</lifecycle>
ऊपर मोजोजरा और प्राइमफेस के साथ परीक्षण और संगत है और सैद्धांतिक रूप से माईफेस के साथ भी संगत है।
अद्यतन: मामले में आप JSF उपयोगिता पुस्तकालय OmniFaces उपयोग कर रहे हैं, या के लिए खुले हैं, संस्करण 2.4 के बाद से आप नए Components#getCurrentActionSource()
उपयोगिता विधि का उपयोग कर सकते हैं वर्तमान कार्रवाई स्रोत घटक पता लगाने के लिए और Components#getActionExpressionsAndListeners()
पाने के लिए किसी दिए गए घटक पर पंजीकृत सभी क्रिया विधियों और श्रोताओं की एक सूची। यह नियमित (गैर-AJAX) अनुरोधों पर भी प्रयोग योग्य है। इसी के साथ, ऊपर PhaseListener
उदाहरण के रूप में नीचे कम किया जा सकता:
public class FacesActionLoggerPhaseListener implements PhaseListener {
@Override
public PhaseId getPhaseId() {
return PhaseId.PROCESS_VALIDATIONS;
}
@Override
public void beforePhase(PhaseEvent event) {
// NOOP.
}
@Override
public void afterPhase(PhaseEvent event) {
if (!event.getFacesContext().isPostback())) {
return;
}
UIComponent source = Components.getCurrentActionSource();
List<String> methodExpressions = Components.getActionExpressionsAndListeners(source);
System.out.println(methodExpressions); // Do your thing with it.
}
}
विशेष रूप से श्रोता विधि नाम, कहानी यहाँ पर कृपया एक नज़र के बारे में: http://stackoverflow.com/questions/11860550/jsf-get-current -क्शन-इन-प्रबंधित-बीन –
@tt_dev दिलचस्प। मैं संभावित रूप से इसका उपयोग कर सकता हूं, हालांकि चेहरे का चयन मेरे फ़िल्टर में उपलब्ध नहीं है क्योंकि यह एक बीन नहीं है। मुझे विश्वास है कि मैं चेहरों को मानक अनुरोध/सत्र के भीतर कहीं से पकड़ लिया जा सकता है, लेकिन मुझे याद नहीं है। मेरे पास कोई ऐप नहीं होने के लिए डीबग खोज में मेरा ऐप है। –
इस प्रश्न को कम करने के लिए कोई कारण नहीं है। – Tiny