2012-01-03 10 views
6

यहाँ क्षेत्र है:JSF कनवर्टर का कारण बनता है सत्यापनकर्ता (रों) ध्यान नहीं दिया जा करने के लिए

<h:inputText id="mobilePhoneNo" 
      value="#{newPatientBean.phoneNo}" 
      required="true" 
      requiredMessage="Required" 
      validator="#{mobilePhoneNumberValidator}" 
      validatorMessage="Not valid (validator)" 
      converter="#{mobilePhoneNumberConverter}" 
      converterMessage="Not valid (converter)" 
      styleClass="newPatientFormField"/> 

और सत्यापनकर्ता:

@Named 
@ApplicationScoped 
public class MobilePhoneNumberValidator implements Validator, Serializable 
{ 
    @Override 
    public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException 
    { 
     // This will appear in the log if/when this method is called. 
     System.out.println("mobilePhoneNumberValidator.validate()"); 

     UIInput in = (UIInput) uic; 
     String value = in.getSubmittedValue() != null ? in.getSubmittedValue().toString().replace("-", "").replace(" ", "") : ""; 

     if (!value.matches("04\\d{8}")) 
     { 
      throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please enter a valid mobile phone number.", null)); 
     } 
    } 
} 

जब मैं प्रपत्र के भीतर आदेश बटन दबाएं, मैं निम्नलिखित व्यवहार मिलता है :

  • जब फ़ील्ड खाली है, तो संदेश "मान्य नहीं है (कनवर्टर)"।
  • जब फ़ील्ड में वैध प्रविष्टि है, तो संदेश "वैध (वैधकर्ता नहीं)" है।
  • जब फ़ील्ड में एक अवैध प्रविष्टि है, तो संदेश "मान्य नहीं है (कनवर्टर)"।

सभी तीन मामलों में, MobilePhoneNumberConverter.getAsObject() कहा जाता है। MobilePhoneNumberValidator.validate()कभी कहा जाता है। और जब फ़ील्ड रिक्त होता है, तो यह required="true" विशेषता को अनदेखा करता है और सीधे रूपांतरण में आता है।

मैं सोचा होगा उचित व्यवहार होगा:

  • जब क्षेत्र को खाली है, संदेश "आवश्यक" होना चाहिए।
  • जब फ़ील्ड में वैध प्रविष्टि है, तो कोई संदेश नहीं होना चाहिए।
  • जब फ़ील्ड में एक अवैध प्रविष्टि है, तो संदेश "मान्य (वैधकर्ता नहीं) होना चाहिए"।
  • यदि, किसी मौके से, रूपांतरण द्वारा पारित सत्यापन नहीं किया गया था, तो संदेश "मान्य नहीं है (कनवर्टर)" होना चाहिए।

नोट: बैकिंग बीन अनुरोधित है, इसलिए यहां कोई फैंसी AJAX व्यवसाय नहीं चल रहा है।

अद्यतन:

यह javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL के साथ कुछ true करने के लिए सेट किया जा रहा हो सकता है?

उत्तर

12

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

@Override 
public Object getAsObject(FacesContext context, UIComponent component, String value) { 
    if (value == null || value.trim().isEmpty()) { 
     return null; 
    } 

    // ... 
} 

असंबंधित ठोस समस्या के लिए, अपने सत्यापनकर्ता एक दोष है। आपको घटक से सबमिट किए गए मान को निकालना नहीं चाहिए। यह कनवर्टर द्वारा लौटाए गए वही मान है। सही सबमिट और परिवर्तित मूल्य पहले से ही तीसरे विधि तर्क के रूप में उपलब्ध है।

@Override 
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { 
    if (value == null) { 
     return; // This should normally not be hit when required="true" is set. 
    } 

    String phoneNumber = (String) value; // You need to cast it to the same type as returned by Converter, if any. 

    if (!phoneNumber.matches("04\\d{8}")) { 
     throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please enter a valid mobile phone number.", null)); 
    } 
} 
+0

धन्यवाद @ बाल्लूसी। बहुत बाद में आने के बावजूद और मूल रूप से βнɛƨн Ǥʋяʋиɢ के उत्तर (जिसे मैंने स्वीकार किया था) से जुड़ी लंबी बातचीत को संक्षेप में सारांशित करने के बावजूद, मैं इस सवाल पर आने वाले अन्य लोगों के लाभ के लिए स्वीकार्य रूप से सबसे उपयोगी उत्तर होगा। क्षमा करें βнɛƨн Ǥʋяʋиɢ :( –

+0

आपका स्वागत है। कृपया ध्यान दें कि मैंने आपके सत्यापनकर्ता कार्यान्वयन पर नज़र डालने के बाद उत्तर को अपडेट किया है जो अनिवार्य रूप से गलत भी है। – BalusC

+0

@ बालससी: मुझे सही करने के लिए धन्यवाद। चूंकि, पूरी तरह से भ्रामक मैं संपादन कर रहा हूं मेरा उत्तर –

3

बलुस की टिप्पणी पढ़ने के बाद मैं इस पोस्ट को फिर से अपडेट कर रहा हूं।

मैंने एक छोटा डेमो एप्लिकेशन बनाया और चरणों को देखने के लिए और जब रूपांतरण और सत्यापन होता है।

दृश्य:

<h:form> 
    <h:inputText value="#{demoBean.field}"> 
     <f:converter converterId="demoConverter"/> 
     <f:validator validatorId="demoValidator"/> 
    </h:inputText> 
    <h:commandButton value="Submit" action="#{demoBean.demoAxn()}"/> 
</h:form> 

प्रबंधित सेम:

@ManagedBean 
@SessionScoped 
public class DemoBean implements Serializable { 
    private String field; 

    public DemoBean() { 
     System.out.println(Thread.currentThread().getStackTrace()[1]); 
    } 

    public String getField() { 
     System.out.println(Thread.currentThread().getStackTrace()[1]); 
     return field; 
    } 

    public void setField(String field) { 
     System.out.println(Thread.currentThread().getStackTrace()[1]); 
     this.field = field; 
    } 

    public String demoAxn() { 
     System.out.println(Thread.currentThread().getStackTrace()[1]); 
     return null; 
    } 
} 

कनवर्टर:

@FacesConverter(value="demoConverter") 
public class DemoConverter implements Converter { 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, String value) { 
     System.out.println(Thread.currentThread().getStackTrace()[1]);    
     return value; 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent component, Object value) { 
     System.out.println(Thread.currentThread().getStackTrace()[1]); 
     return (String) value; 
    }  
} 

सत्यापनकर्ता:

@FacesValidator(value="demoValidator") 
public class DemoValidator implements Validator { 

    @Override 
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { 
     System.out.println(Thread.currentThread().getStackTrace()[1]); 
    } 

} 

चरण श्रोता:

public class DemoPhaseListener implements PhaseListener { 
    @Override 
    public void afterPhase(PhaseEvent event) { 
     System.out.println(Thread.currentThread().getStackTrace()[1]); 
     System.out.println("PhaseId: " + event.getPhaseId() + " ===============================\n\n");   
    } 

    @Override 
    public void beforePhase(PhaseEvent event) { 
     System.out.println("\n\nPhaseId: " + event.getPhaseId() + " ==============================="); 
     System.out.println(Thread.currentThread().getStackTrace()[1]);   
    } 

    @Override 
    public PhaseId getPhaseId() { 
     return PhaseId.ANY_PHASE; 
    }  
} 

चरण श्रोता पंजीकरण दिनांक: उस सेटिंग के साथ

<lifecycle> 
    <phase-listener>pkg.DemoPhaseListener</phase-listener> 
</lifecycle> 

जब "भेजें" बटन क्लिक किया जाता है, उत्पादन होता है:

 
INFO: PhaseId: RESTORE_VIEW 1 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: RESTORE_VIEW 1 =============================== 

INFO: PhaseId: APPLY_REQUEST_VALUES 2 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: APPLY_REQUEST_VALUES 2 =============================== 

INFO: PhaseId: PROCESS_VALIDATIONS 3 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoConverter.getAsObject(DemoConverter.java:13) 
INFO: pkg.DemoValidator.validate(DemoValidator.java:14) 
INFO: pkg.DemoBean.getField(DemoBean.java:17) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: PROCESS_VALIDATIONS 3 =============================== 

INFO: PhaseId: UPDATE_MODEL_VALUES 4 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoBean.setField(DemoBean.java:22) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: UPDATE_MODEL_VALUES 4 =============================== 

INFO: PhaseId: INVOKE_APPLICATION 5 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoBean.demoAxn(DemoBean.java:27) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: INVOKE_APPLICATION 5 =============================== 

INFO: PhaseId: RENDER_RESPONSE 6 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoBean.getField(DemoBean.java:17) 
INFO: pkg.DemoConverter.getAsString(DemoConverter.java:20) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: RENDER_RESPONSE 6 =============================== 

लेकिन जब मेकअप परिवर्तन निम्नानुसार कनवर्टर में एनपीई फेंकने के लिए:

@Override 
public Object getAsObject(FacesContext context, UIComponent component, String value) { 
    System.out.println(Thread.currentThread().getStackTrace()[1]);    
    throw new NullPointerException(); 
} 

उत्पादन होता है:

 
INFO: PhaseId: RESTORE_VIEW 1 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: RESTORE_VIEW 1 =============================== 

INFO: PhaseId: APPLY_REQUEST_VALUES 2 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: APPLY_REQUEST_VALUES 2 =============================== 

INFO: PhaseId: PROCESS_VALIDATIONS 3 =============================== 
INFO: pkg.DemoPhaseListener.beforePhase(DemoPhaseListener.java:17) 
INFO: pkg.DemoConverter.getAsObject(DemoConverter.java:13) 
INFO: pkg.DemoPhaseListener.afterPhase(DemoPhaseListener.java:10) 
INFO: PhaseId: PROCESS_VALIDATIONS 3 =============================== 

INFO: pkg.DemoBean.getField(DemoBean.java:17) 

लेकिन स्टैकट्रेस जिसके परिणामस्वरूप दृश्य पर प्रदर्शित होता है।

+0

मुझे नहीं पता कि यहां क्या हो रहा है ... मैंने कन्वर्टर्स और वैधकर्ताओं को जेएसएफ 2.0 तरीके से एनोटेट करने के लिए बदल दिया। बहुत समय पहले ऐसा नहीं हुआ जब इसने बिल्कुल कोई फर्क नहीं पड़ता। शायद ग्लासफ़िश 3.1.1 मेरे साथ खराब हो रहा है। वैसे भी, "सही" एनोटेशन के साथ 'आवश्यक' विशेषता अभी भी काम नहीं कर रही है, बल्कि सीधे रूपांतरण पर जा रही है। असल में, अब बिल्कुल कोई परिदृश्य नहीं है जिसमें सत्यापन होता है। क्या मुझे इसका मतलब यह समझना चाहिए कि कनवर्टर्स को सत्यापन को छोड़ दिया जाना चाहिए? –

+0

"क्या मुझे इसका मतलब यह समझना चाहिए कि कन्वर्टर्स सत्यापन को छोड़ने का कारण बनता है?" नहीं। वे अलग-अलग असंबद्ध सामान करते हैं, और हम उन्हें एक साथ चलाने में सक्षम होना चाहिए। लेकिन, विफलता के मामले में जेएसएफ अनुरोध प्रसंस्करण बंद कर देता है और अन्य चरण छोड़ देता है और प्रतिक्रिया देने के लिए कूदता है। ' –

+0

"नहीं। वे अलग-अलग असंबद्ध सामान करते हैं, और हम उन्हें एक साथ चलाने में सक्षम होना चाहिए।" मैं इसे अपनी आंखों से देख रहा हूं - वे ** ** ** एक साथ काम नहीं कर रहे हैं। "लेकिन, विफलता के मामले में जेएसएफ अनुरोध प्रसंस्करण बंद कर देता है और दूसरे चरण को छोड़ देता है और प्रतिक्रिया देने के लिए कूदता है।" यह कैसे प्रासंगिक है, यद्यपि?सत्यापन और रूपांतरण एक ही चरण में होता है और शेष चरण को छोड़ने से पहले जेएसएफ कम से कम इस चरण को पूरा करने के लिए चलाएगा (सभी * सबमिट किए गए मानों को मान्य करने के लिए * और * सभी * सत्यापन * रूपांतरण त्रुटियों को दिखाएं)। –

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