【问题标题】:How to validate an input text component based on the value of a radio button component如何根据单选按钮组件的值验证输入文本组件
【发布时间】:2012-12-11 15:51:32
【问题描述】:

我正在尝试根据单选按钮组件的值验证输入文本组件,但是它会抛出 NullPointerException,我不明白为什么。

这是视图:

<h:form id="formId">
    <p:inputText validator="#{searchBean.validate}" id="name"
        required="true" requiredMessage="should contain only characters">
        <f:validateRegex pattern="[a-zA-Z]*" />
        <f:validator validatorId="inputValidator" />
    </p:inputText>
    <p:selectOneRadio value="#{searchBean.searchForm.selectedRadio}" id="customRadio">
        <f:selectItem itemLabel="city" itemValue="1" />
        <f:selectItem itemLabel="zipcode" itemValue="2" />
        <f:selectItem itemLabel="state" itemValue="3" />
    </p:selectOneRadio>
    <p:commandButton value="Search" action="results.jsf" />
</h:form>

这是验证器:

public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    UIViewRoot ui = new UIViewRoot();
    UIInput radio = (UIInput) ui.findComponent("formId:customRadio");
    boolean convertedAndValidatedValue = (Boolean) radio.getValue(); // This line is throwing the exception.
    System.out.println("Validate"+convertedAndValidatedValue);

    if (searchForm.selectedRadio.equals("city")) {
        validateForCity(convertedAndValidatedValue);
    } else if (searchForm.selectedRadio.equals("zipcode")) {
        validateForZipcode(convertedAndValidatedValue);
    } else {
        validateForState(convertedAndValidatedValue);
    }
}

这是一个例外:

javax.faces.FacesException
    at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:80)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:679) 
Caused by: java.lang.NullPointerException
    at com.placessearch.action.SearchBean.validate(SearchBean.java:76)
    at javax.faces.component.UIInput.validateValue(UIInput.java:1142)
    at javax.faces.component.UIInput.validate(UIInput.java:960)
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1204)
    at javax.faces.component.UIInput.processValidators(UIInput.java:693)
    at javax.faces.component.UIForm.processValidators(UIForm.java:240)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1081)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1081)
    at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1159)
    at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:72) 
    ... 19 more

【问题讨论】:

    标签: java validation jsf primefaces


    【解决方案1】:

    JSF 组件按照它们在组件树中出现的顺序进行转换和验证。您的验证器附加到出现在单选按钮组件之前 的输入文本组件。但是,您正在尝试访问单选按钮组件的转换和验证值,而此时它还没有被转换和验证。

    boolean convertedAndValidatedValue = (Boolean) radio.getValue();
    

    它只会返回null,而您又试图将其自动装箱到boolean,这只会导致NullPointerException

    您需要获取提交的值。请注意,您指定的项目值绝对不是布尔值。它是数字。另请注意,提交的值是 always String(仅仅是因为这正是 request.getParameter() 返回的类型,还因为此时它还没有被 JSF/EL 转换)。

    String submittedRadioValue = (String) radio.getSubmittedValue();
    
    if (submittedRadioValue != null) {
        int convertedRadioValue = Integer.valueOf(submittedRadioValue);
        // ...
    }
    

    更新:由于其意外性质而我忽略的另一个原因如下:

    UIViewRoot ui = new UIViewRoot();
    

    这肯定也不对。您应该从 faces 上下文中检索当前的,而不是手动创建一个完全空的。

    UIViewRoot ui = context.getViewRoot();
    

    否则radio 仍将是null,因此是NullPointerException 的另一个潜在原因。

    【讨论】:

    • 谢谢,我已经解决了 NullPointerException,但默认情况下必须在应用程序中选择一个单选按钮。
    • 只需在 bean 的(后)构造函数中预设 #{searchBean.searchForm.selectedRadio},就像对其他所有 JSF 输入组件所做的那样。
    猜你喜欢
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 2016-09-01
    • 2010-09-21
    • 1970-01-01
    • 2012-11-11
    相关资源
    最近更新 更多