2017-12-02 411 views
0

我使用的是OmniFaces的omnifaces.SelectItemsConverter,因此我可以在selectOneMenu中顯示對象的字符串值。一切正常,直到驗證失敗(f:validateDoubleRange)。一旦驗證失敗,我無所謂,我在selectOneMenu中顯示的對象的等號方法中獲得NullPointerException驗證失敗時的Nullpointerexception使用轉換器的JSF

這是equals方法:

@Override 
public boolean equals(Object obj) { 
    Car other = (Car) obj; 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    if (!number.equals(other.number)) 
     return false; 
    return true; 
} 

這是我使用OmniFaces'轉換器

<h:selectOneMenu id="id_1" value="#{myBean.car}" converter="omnifaces.SelectItemsConverter"> 
    <f:selectItems value="#{myBean.cars}" /> 
</h:selectOneMenu> 

這是導致NullPointerException

<h:inputText id="nom" value="#{myBean.num}" 
       style="height: 24px; "><f:validateDoubleRange minimum="0.0"/></h:inputText> 

我驗證在這一行中得到例外:

if (!number.equals(other.number)) 

other.number是確定的,但number是空

爲什麼this.number空?

+0

您意味着當您使用自定義轉換器時不會發生此問題。這是不正確的。請相應地重新審視您的問題。 – BalusC

+0

@BalusC我只是說我在使用該轉換器時出現此錯誤,我並不是說它是轉換器的錯。但我正在尋找一個解決方案,因爲我不知道我在做什麼錯... – AwesomeGuy

回答

0

根源

問題的根本原因是輸入組件狀態的JSF默認處理上的任何內部視圖輸入分量的驗證失敗之後。

在這個accepted answer中有很好的解釋。

解決方案

所以你的具體情況,如前面提到的答案表明,您需要指示JSF復位輸入組件狀態(h:selectOneMenu最重要的)和拉/從後盾刷新自己的價值觀驗證失敗後的bean模型。

如果您正在使用JSF 2.2及更高版本,你可以做到這一點,例如,像這樣

<h:commandButton value="Submit" actionListener="#{myBean.onSubmit()}" > 
    <f:ajax execute=":form:nom :form:id_1" 
      render=":form:messages :form:id_1" 
      resetValues="true"/> 
</h:commandButton> 

UPDATE:如果你是預JSF 2.2,你可以做到這一點使用Primefaces p:ajax,例如,像這樣的(並再次溶液和解釋可以在引用accepted answerPrimefaces showcase發現以及)

<h:commandButton value="Submit" actionListener="#{dtSelectionView.onSubmit()}"> 
     <p:ajax process="@form" update="@form" resetValues="true" /> 
</h:commandButton> 

(雖然我不建議只爲此目的導入Primefaces ...這是更好地探索其他可能性)

實際原因爲什麼this.number是空

我注意到,如果你嘗試提交後驗證失敗的第一時間(如果你不復位輸入)的h:selectOneMenu值,以下一些類創造了新的Car對象調用default constructor(和初始化number屬性爲默認值而你的情況等於null

Severe: java.lang.NullPointerException 
    at entities.Car.equals(Car.java:107) 
    at javax.faces.component.UIInput.compareValues(UIInput.java:1224) 
    at javax.faces.component.UIInput.validate(UIInput.java:990) 
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1248) 
    at javax.faces.component.UIInput.processValidators(UIInput.java:712) 
    at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:575) 
    at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183) 
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1689) 
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) 
    at javax.faces.component.UIForm.visitTree(UIForm.java:371) 
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) 
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) 
    at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403) 
    at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:266) 
    at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:57) 
    at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219) 
    at org.omnifaces.context.OmniPartialViewContext.processPartial(OmniPartialViewContext.java:139) 
    at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1193) 
    at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) 

坦率地說,我無法解釋這種情況發生的地點和原因,因爲它超出了我對這個問題的瞭解。

+0

我使用的是JSF 2.0,我如何使用來重置h:selectOneMenu值?我應該在哪裏放?它應該重置值,如果驗證失敗,我猜... – AwesomeGuy

+0

我用解決方案使用Primefaces p:ajax更新了我的答案。 –

+0

它的工作!謝謝! – AwesomeGuy