2016-06-09 19 views
-1

Ich lerne JSF-Ereignisbehandlung, und wenn ich versuche, Beispielcode auszuführen, erhalte ich eine Null-Zeiger-Ausnahme.NullPointer-Ausnahme - JSF-Ereignisbehandlung (ValueChangeListener)

Das ist mein index.xhtml Schnipsel,

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

Als ich diese auf Glassfish Server laufen, erhalte ich eine Fehler,

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) 

Kann jemand mir dabei helfen?

+0

Haben Sie überprüft, dass 'userData' nicht null ist? – ujulu

+0

Nach der Überprüfung, habe ich userData als null, aber immer noch "Gebietsschema gesetzt" wird gedruckt, wenn ich die Ausnahme abfangen und Fehlermeldung ausgeben. – Shinchan

Antwort

1
  1. Sie erhalten NullPointerException weil userData nicht im Sitzungsbereich gefunden.

  2. Der Grund dafür ist, dass Sie die userData im Anwendungsbereich (@ApplicationScoped Annotation auf Ihrer verwalteten Bean) setzen und im Sitzungsumfang suchen.

  3. Obwohl Sie verifiziert haben, dass userData null ist, druckt es immer noch Locale set, da die Bean im Anwendungsbereich der Anwendung ist, wie in 2. oben beschrieben.

  4. Was ist die Lösung? Entweder ändern @ApplicationScoped-@SessionScoped oder Zugriff auf Ihre userData durch Änderung:

    UserData userData = (UserData) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("userData"); 
    

zu

FacesContext ctx = FacesContext.getCurrentInstance(); 
    UserData userData = (UserData)ctx.getExternalContext().getApplicationMap().get("userData");