NullPointer异常 - JSF事件处理(ValueChangeListener)

时间:2016-06-09 18:47:56

标签: java jsf jsf-2 xhtml jsf-2.2

我正在学习JSF事件处理,当我尝试运行一些示例代码时,我得到了一个空指针异常。

这是我的 index.xhtml 代码段

<h:form>
            <h2>Implement valueChangeListener</h2>
            <hr />
            <h:panelGrid columns="2">
                Selected Locale:
                <h:selectOneMenu value="#{userData.selectedCountry}" onchange="submit()">
                    <f:valueChangeListener type="com.cyb3rh4wk.test.LocaleChangeListener" />
                    <f:selectItems value="#{userData.countries}" />
                </h:selectOneMenu>
                Country Name:
                <h:outputText id="countryInterface" value="#{userData.selectedCountry}" />
            </h:panelGrid>
        </h:form>

UserData.java

@ManagedBean(name = "userData", eager = true)
@ApplicationScoped
public class UserData implements Serializable{
    private static Map<String, String> countryMap;
    private String selectedCountry = "United Kingdom";
    static  {
        countryMap = new LinkedHashMap<String, String>();
        countryMap.put("en", "United Kingdon");
        countryMap.put("fr", "French");
        countryMap.put("de", "German");
        countryMap.put("def", "Default");
    }  
    public String getSelectedCountry() {
        return selectedCountry;
    }
    public void setSelectedCountry(String selectedCountry) {
        this.selectedCountry = selectedCountry;
        System.out.println("Locale set");
    }    
    public Map<String, String> getCountries() {
        return countryMap;
    }        
    public void localeChanged(ValueChangeEvent event) {
        selectedCountry = event.getNewValue().toString();
    }        
}

LocaleChangeListener.java

public class LocaleChangeListener implements ValueChangeListener    {
    @Override
    public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
        UserData userData = (UserData) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userData");
        String newLocale = event.getNewValue().toString();
        if (newLocale != null)
            userData.setSelectedCountry(newLocale);
        else
            userData.setSelectedCountry("Default");   
    } 
}

当我在Glassfish服务器上运行这些时,我得到错误

java.lang.NullPointerException
    at com.cyb3rh4wk.test.LocaleChangeListener.processValueChange(LocaleChangeListener.java:25)
    at com.sun.faces.facelets.tag.jsf.core.ValueChangeListenerHandler$LazyValueChangeListener.processValueChange(ValueChangeListenerHandler.java:128)
    at javax.faces.event.ValueChangeEvent.processListener(ValueChangeEvent.java:134)

任何人都可以帮我吗?

1 个答案:

答案 0 :(得分:1)

  1. 您收到NullPointerException,因为在会话范围内找不到userData

  2. 发生这种情况的原因是您将userData放在应用程序范围(@ApplicationScoped注释的托管bean上)并在会话范围内进行搜索。

    < / LI>
  3. 尽管您确认userData为空,但它仍会打印Locale set,因为该bean位于应用程序范围内,如上面2.中所述。

  4. 那么解决方案是什么?将@ApplicationScoped更改为@SessionScoped或通过更改:

    访问您的userData
    UserData userData = (UserData) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userData");
    
  5.     FacesContext ctx = FacesContext.getCurrentInstance();
        UserData userData = (UserData)ctx.getExternalContext().getApplicationMap().get("userData");