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

时间:2013-09-06 16:46:43

标签: 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);
            }
        }
    }
}
}

以下是观点:

<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>

1 个答案:

答案 0 :(得分:2)

下面,

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>ResourceBundle#getBundle()使用JSF内置本地化工具。