验证失败时的Nullpointerexception使用转换器的JSF

验证失败时的Nullpointerexception使用转换器的JSF

问题描述:

我使用的是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

根源

问题的根本原因是输入组件状态的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