validation - 多字段验证,获取另一个组件的值导致 NullPointerException

标签 validation jsf jsf-2.2

当我在邮政编码中键入内容并点击提交并将国家/地区设置为默认空值时,出现 javax.faces.FacesException: java.lang.NullPointerException。如果我选择国家然后输入一些东西一切正常。我尝试了 SubmittedValue,但它以相反的方式工作 - null 正在工作,在此之后给出 null 异常。

@FacesValidator("zipV")
public class ZipValidator implements Validator {

LocaleBean Bean = new LocaleBean();
String language;
private static final String ZIP_PATTERN_BG = "\\d{4}";
private static final String ZIP_PATTERN_US = "\\d{5}";
private static final String ZIP_PATTERN_DEFAULT = "[A-Za-z0-9]*";
private String zip_pattern;
private Pattern pattern;
private Matcher matcher;
private String country;


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

    language = Bean.getLanguage();

    UIInput Input = (UIInput) component.getAttributes().get("country");
    country = Input.getValue().toString();
    String zip = (String) value;


    if (country == null || country.isEmpty()) {
        return; 
    }

    switch (country) {
        case "BGR":
            zip_pattern = ZIP_PATTERN_BG;
            break;
        case "USA":
            zip_pattern = ZIP_PATTERN_US;
            break;
        default:
            zip_pattern = ZIP_PATTERN_DEFAULT;
            break;
    }

    pattern = Pattern.compile(zip_pattern);

    matcher = pattern.matcher(value.toString());
    if (!matcher.matches()) {


        switch (language) {
            case "en": {
                FacesMessage msg = new FacesMessage("Invalid zip.");
                msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                throw new ValidatorException(msg);
            }
            case "bg": {
                FacesMessage msg = new FacesMessage("Невалиден пощенски код.");
                msg.setSeverity(FacesMessage.SEVERITY_ERROR);
                throw new ValidatorException(msg);
            }
        }
    }
}
}

这是 View :

<h:selectOneMenu id="country" value="#{account.country}" required="true" requiredMessage="#{msg['register.required']}" binding="#{country}">
<f:selectItem itemValue="#{null}" itemLabel="#{msg['register.countryQ']}"/>
<f:selectItems value="#{account.countries}"/>
<f:ajax listener="#{account.loadStates()}" render="state"/>
</h:selectOneMenu>

<h:inputText id="zipcode" required="true" requiredMessage="#{msg['register.required']}" value="#{account.zipcode}">
<f:validator validatorId="zipV"/>
<f:attribute name="country" value="#{country}"/>
</h:inputText>

最佳答案

这里,

country = Input.getValue().toString();

你不应该使用 toString()根本。你应该转换它:

country = (String) Input.getValue();

否则会抛出NullPointerException如果getValue()返回 null .作为its javadoc清楚地说,一个NullPointerException当您尝试在 null 上调用实例方法时将被抛出(就像你对 toString() 所做的那样)。

请注意,此问题在技术上与 JSF 无关。这只是基本的 Java。 java.lang异常包是一个很好的提示。如果你得到 javax.faces 的异常(或 javax.el )包,然后我们可以讨论真正的 JSF(或 EL)问题。

另见:


与具体问题无关,我真的很尊重Java naming conventions .变量名以小写开头。使用 input而不是 Input .另外,您对本地化的手动控制很奇怪。如果您需要支持 10 种语言怎么办?您是否将开关扩展到所有地方?通过 <resource-bundle> 使用 JSF 内置本地化工具和 ResourceBundle#getBundle() .

关于validation - 多字段验证,获取另一个组件的值导致 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18662673/

相关文章:

java - Spring Security 3.1 身份验证 ProviderManager 抛出 NotSerializableException

jsf - 如何使用注释而不是 XML 在嵌入式 Tomcat 中创建自定义组件标签

security - 使用 javax.faces.STATE_SAVING_METHOD 在客户端保存 session 的含义

jsf - 如何在 <p :selectOneMenu> after certain validations are violated 更改时重置输入组件

jsf - 是否可以在 richfaces 数据表中定义标签 "var"的动态值?

jquery - 提交时检查输入是否为空

validation - 验证Skype用户名是否正在使用

ruby-on-rails - Rails ActiveRecord:验证单个属性

spring - 将 Spring 加载的配置属性传递到 JSF 世界的正确方法

reactjs - 带有 yup 验证的对象或字符串类型有条件