3

I get javax.faces.FacesException: java.lang.NullPointerException when I type something in the zip code and hit submit with country set to default null value. If I select the country and then type something everything works. I tried SubmittedValue, but it is working the opposite way - with null is working and after this is giving null exception.

@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);
            }
        }
    }
}
}

Here's the 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>
4

1 に答える 1

2

ここ、

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

まったく使用toString()しないでください。あなたはそれをキャストする必要があります:

country = (String) Input.getValue();

NullPointerExceptionそれ以外の場合は、getValue()返された場合にスローされnullます。javadocが明確に述べているように、インスタンス メソッドを呼び出そうとすると ( で行ったように )、とりわけ aがスローされNullPointerExceptionます。nulltoString()

この問題は技術的に JSF とは無関係であることに注意してください。それは単なる基本的なJavaです。例外のjava.langパッケージは、これで非常に良いヒントです。javax.faces(または) パッケージの例外が発生した場合はjavax.el、真の JSF (または EL) の問題について話すことができます。

以下も参照してください。


具体的な問題とは関係ありませんが、私はJava の命名規則を尊重します。変数名は小文字で始まります。inputの代わりに使用しInputます。また、ローカリゼーションの手動制御は奇妙です。10 の言語をサポートする必要がある場合はどうしますか? スイッチをすべての場所に展開しますか? およびで JSF 組み込みのローカリゼーション機能を利用し<resource-bundle>ますResourceBundle#getBundle()

于 2013-09-06T17:16:39.747 に答える