2013-04-25 97 views
4

我這裏有一個問題:定製驗證類工作不

情景: 我有一個JSF-2,春季(豆線)的應用。我寫了一個自定義驗證器,我想執行它。

@FacesValidator("com.test.vali") 
@Named("com.test.vali") 
public class TestValidator implements Validator { 

    @Override 
    public void validate(FacesContext arg0, UIComponent arg1, Object arg2) throws ValidatorException { 
     System.out.println("dhkdfkbhdfbkdfksdfdfk"); 

    } 

} 

我嘗試使用以下方式來注入驗證:

路#1:

<h:inputText value="#{helloWorld.name}"> 
     <f:validator binding="#{com.test.vali}" /> 
    </h:inputText> 

輸出

當試圖呈現的頁面,它拋出了一個例外。

javax.servlet.ServletException: /testRichFaces.xhtml @17,48 <f:validator> A validator id was not specified. Typically the validator id is set in the constructor ValidateHandler(ValidatorConfig) 

搜查這個有很多,並驗證像幾個方面:

  1. 的Java文件是在一個包。

路#2

<f:validator validatorId="com.test.vali" /> 

輸出

javax.servlet.ServletException: Expression Error: Named Object: com.test.vali not found. 
從路#1

所以和方式#2,我能理解,沒有任何註解的是爲我工作。

然後,我想移動到最後的辦法:

路#3:在faces-config.xml中添加驗證,只是爲了證明我使用2.0標準:

<faces-config xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" 
version="2.0"> 

和校驗配置爲:

<validator> 
     <validator-id>com.test.vali</validator-id> 
     <validator-class>teet.TestValidator</validator-class> 
</validator> 

輸出

Works

現在問題出現了,即使使用JSF-2.0,我也不得不求助於faces-config.xml。

我在做什麼錯誤?

讓我們知道是否需要更多配置。

+0

@Named註釋不是必需的。你如何管理你的後臺bean。如果它們使用Spring批註註釋,則必須在faces-config.xml中配置org.springframework.web.jsf.el.SpringBeanFacesELResolver。 – Ravi 2013-04-25 13:19:05

+0

另請參閱http://stackoverflow.com/questions/12470512/scoperequest-not-working – Ravi 2013-04-25 13:20:20

回答

8

首先,您基本上混合了兩種註冊驗證器實例的方式,它們彼此完全獨立工作:通過@FacesValidator註冊爲驗證器,或通過@Named註冊爲CDI受管bean。這些註釋彼此不認識,也不考慮對方。你基本上最終得到兩個完全不同的實例,它們不共享每個其他數據。爲避免以後出現混淆,強烈建議刪除其中一個註釋,以便您可以保證始終使用同一個實例。

至於爲什麼這樣1失敗:

@Named("com.test.vali") 
public class TestValidator implements Validator { 
    // ... 
} 
<f:validator binding="#{com.test.vali}" /> 

這是因爲該時期.是EL一個特殊的運營商代表一個bean屬性訪問或豆方法調用。使用#{com.test.vali}將僅查找豆#{com},然後test屬性,然後依次查找其屬性vali。換句話說,它基本上試圖通過com.getTest().getVali()獲得驗證器,其中com是一個CDI託管bean,如@Named("com")

這不是你所期望的。擺脫這些名稱的時期。更好的是,堅持默認實例名稱,testValidator。這是最明智的選擇,當然,如果你給你的班級明智的名字。

@Named 
public class TestValidator implements Validator { 
    // ... 
} 
<f:validator binding="#{testValidator}" /> 

至於爲什麼會這樣失敗2:

@FacesValidator("com.test.vali") 
public class TestValidator implements Validator { 
    // ... 
} 
<f:validator validatorId="com.test.vali" /> 

@FacesValidator不正確啓動過程中拾起可能發生。當所討論的類不在WAR內部時,反過來可能發生這種情況,而是在例如內部EAR或EJB。在這種情況下,您需要在faces-config.xml中明確註冊驗證器。但更好的是把這個類放在WAR中,你應該也就是絕對不是在項目的EAR或EJB部分有任何JSF構件。它會將模型/服務邏輯(JPA,EJB等)緊密結合到視圖(JSF),並使其不再可用於其他視圖(前端),如JAX-RS,Spring MVC,Struts2等。

+0

+1用於捕獲兩個註釋和「。」 EL表達式中的操作符事實。根本沒有想到「。」 – 2013-04-25 16:31:10

+0

我刪除了FacesValidator並保留@Named以保持一致性,但有一件事我無法清除。我做了一個擴展UIInput的自定義控件,併爲此做了一個驗證器。使用,我嘗試註冊驗證器。但是在測試時我無法執行它。在調試時,我可以看到具有自定義組件的驗證器。但由於某種原因,它沒有執行。然後我重寫組件的驗證方法,以獲取驗證器並執行綁定的每個驗證器的驗證方法。這是對的嗎? – 2013-04-25 16:36:07

+0

默認情況下,或者值爲空時,不會調用配置。爲此,應該使用'required'屬性,或者'javax.faces.VALIDATE_EMPTY_FIELDS'上下文參數應該設置爲'true'。 – BalusC 2013-04-25 17:40:46