2013-01-16 27 views
1

我有一個複合組件(實際上是一個驗證碼),我將它用於h:表單。
當我點擊我的h:表單的提交按鈕時,出現以下錯誤。JSF 2 - 複合組件 - Bean驗證因組件空值而失敗

16 janv。 2013 10時02分06秒javax.faces.validator.BeanValidator驗證
注意:不能使用空值驗證組件:驗證碼:captchaText

這裏是驗證碼的複合組件的XHTML代碼

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:composite="http://java.sun.com/jsf/composite" xmlns:xcc="http://java.sun.com/jsf/composite/components"> 
<h:body> 

    <composite:interface> 
    <composite:attribute name="id" type="java.lang.String" /> 
    <composite:attribute name="imageWidth" type="java.lang.Integer" /> 
    <composite:attribute name="imageHeight" type="java.lang.Integer" /> 
    <composite:attribute name="imageClass" type="java.lang.String" /> 
    <composite:attribute name="inputClass" type="java.lang.String" default="" /> 
    <composite:attribute name="placeholder" type="java.lang.String" default="" /> 
    <composite:attribute name="failureMessage" type="java.lang.String" default="Captcha validation failed" /> 

    <composite:editableValueHolder name="captchaText" /> 
    </composite:interface> 

    <composite:implementation> 
    <h:inputText id="captchaText" required="true" styleClass="#{cc.attrs.inputClass}" placeholder="#{cc.attrs.placeholder}" 
     autocomplete="off" maxlength="10"> 
     <f:param name="failureMessage" value="#{cc.attrs.failureMessage}" /> 
     <f:validateLength minimum="6" /> 
     <f:validator validatorId="captchaValidator" /> 
    </h:inputText> 
    <h:graphicImage id="captchaImage" alt="" style="margin-left:3px;" styleClass="#{cc.attrs.imageClass}" width="#{cc.attrs.imageWidth}" 
     height="#{cc.attrs.imageHeight}" value="__captcha.jpg" /> 
    </composite:implementation> 

</h:body> 
</html> 

這是Captcha的JSF驗證器代碼。

import javax.faces.application.FacesMessage; 


import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.validator.FacesValidator; 
import javax.faces.validator.Validator; 
import javax.faces.validator.ValidatorException; 

import net.paissad.waqtsalat.servlet.CaptchaServlet; 

    @FacesValidator(CaptchaValidator.VALIDATOR_ID) 
    public class CaptchaValidator implements Validator { 

    public static final String VALIDATOR_ID = "captchaValidator"; 

    @Override 
    public void validate(final FacesContext context, final UIComponent component, final Object value) throws ValidatorException { 

     final String enteredValue = (String) value; 
     final String expectedValue = (String) context.getExternalContext().getSessionMap() 
      .get(CaptchaServlet.CAPTCHA_KEY); 

     final boolean ok = (enteredValue != null) && (enteredValue.equals(expectedValue)); 
     if (!ok) { 
      String summary = (String) component.getAttributes().get("failureMessage"); 
      if (summary == null) summary = ""; 
      throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, summary)); 
     } 
    } 

} 

我不是真的有必要展示構建真正驗證碼圖像的CaptchaServlet的代碼。我只能說它確實很好。我從這個代碼啓發here

這裏基本上是如何在我的表單中使用複合組件。 (這不是我的實際使用情況的BTW)

<h:form> 
    <xcc:captcha id="captcha" imageClass="img-rounded" placeholder="#{i18n.Captcha_enter_code_here}" failureMessage="Captcha validation failed" /> 
    <h:commandButton styleClass="btn btn-success" type="submit" value="#{i18n.Submit}" 
      actionListener="#{accountRegistrationController.register}" action="success" /> 
</h:form> 

的形式呈現這樣的(與法國本地化):

enter image description here

我更喜歡使用複合成分+驗證+ servlet的
我寧願避免使用控制器bean(@Named/@RequestScoped)和驗證Captcha輸入值的方法。

當我在Eclipse中調試Validator代碼時,代碼的行爲是正確的。唯一錯誤的是下面的代碼部分不會從Captcha組件中檢索「failureMessage」屬性,我該如何解決這個問題?它始終爲空。

String summary = (String) component.getAttributes().get("failureMessage"); 

那麼,我該如何解決Bean驗證問題?
如何在我的驗證器中正確檢索屬性'failureMessage'?

我已經嘗試了很多東西,現在我依靠你了。
在此先感謝您的幫助。

PS:我目前使用的是TomEE 1.5+,Java6。

回答

1

看起來像您的inputText標記缺少值屬性。 value屬性執行輸入和bean之間的綁定。

<h:inputText value="#{yourBean.yourValue" ... 
+0

你好Christophe,我已經測試過,發佈之前。我甚至做了以下** **沒有EL。但錯誤依然存在。更糟糕的是,我放棄了html5屬性「佔位符」的好處,如果我設置了默認值,它將不再使用。無論如何,設置「價值」屬性並沒有完成這項工作。 – paissad

+0

關於HTML5支持,如果您不想等待,您需要等待JSF 2.2或使用OmniFaces。另一種解決方案是在頁面加載後通過JavaScript添加佔位符。 –

+0

正如你在截圖中看到的那樣,佔位符已經在工作。的確,我正在使用OmniFaces。 – paissad