2016-06-09 10 views
-1

Я изучаю обработку событий JSF, и когда я пытаюсь запустить образец кода, я получаю исключение Null Pointer Exception.NullPointer Exception - Обработка событий JSF (ValueChangeListener)

Это мой 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) 

Может кто-нибудь помочь мне с этим?

+0

Вы проверили, что 'userData' не равно нулю? – ujulu

+0

После проверки я получил userData как null, но все же «Locale set» печатается, когда я улавливаю сообщение об ошибке и выводим сообщение об ошибке. – Shinchan

ответ

1
  1. Вы получаете NullPointerException потому userData не найден в рамках сеанса.

  2. Причина, по которой это происходит, заключается в том, что вы помещаете userData в область приложения (аннотации на управляемый компонент) и просматриваете ее в области сеанса.

  3. Если вы подтвердили, что userData равно null, он по-прежнему печатает Locale set, потому что компонент находится в области приложения, как описано в 2. выше.

  4. Так в чем же решение? Либо изменить @ApplicationScoped к @SessionScoped или иметь доступ к userData путем изменения:

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

в

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