2012-05-22 2 views
1

Я использую HttpSession в качестве переменной экземпляра, какМогу ли я использовать объект HttpSession в качестве переменной экземпляра в Managed Bean. Получение NotSerializableException исключение

@ManagedBean 
@ViewScoped 
public class CountryPages_Detail { 

    private HttpSession session; 

    public CountryPages_Detail() { 
     session = ConnectionUtil.getCurrentSession(); 
    } //end of constructor 

    public String preview() { 
     session.setAttribute("countryDetailImageNames", imageNames); 
     session.setAttribute("countryDetailImages", images); 
     session.setAttribute("countrySummary", countrySummary);   
     return "countryPages_View?faces-redirect=true"; 

    } //end of preview() 
} //end of class CountryPages_Detail 

ConnectionUtl Класс:

public static HttpSession getCurrentSession() { 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 
    HttpServletRequest httpServletRequest = (HttpServletRequest) externalContext.getRequest(); 

    HttpSession currentSession = (HttpSession) externalContext.getSession(false); 

    if (currentSession != null) {   
     return currentSession; 
    } else {   
     return null; 
    } 
} //end of getCurrentSession() 

Я хочу спросить, правильно ли это путь? На самом деле я использую в моей web.xml

<context-param> 
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
    <param-value>server</param-value> 
</context-param> 

Но когда я изменил его на <param-value>client</param-value>, то первым я получил исключение, что один из моего класса не является сериализации, после принятия его сериализации теперь я получаю исключение,

SEVERE: Error Rendering View[/index.xhtml] 
java.io.NotSerializableException: org.apache.catalina.session.StandardSessionFacade 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156) 
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509) 
    .... 

При использовании сервера он работал нормально. Зачем? Я хочу спросить, когда мы сервер в param-value, тогда все наши управляемые компоненты, которые находятся в viewScope (@ViewScoped), находятся на сервере, и когда мы меняем его на клиента, тогда все наши управляемые компоненты @ViewScoped находятся на клиенте? Кроме того, если мои компоненты не находятся в @ViewScoped, то элемент javax.faces.STATE_SAVING_METHOD создает какую-либо разницу? Опция STATE_SAVING_METHOD относится только к @ViewScoped или она также влияет на @RequestScope или @SessionScopr или на другие области? благодаря

ответ

2

Вы должны абсолютно не разжиться внешних контекстных ресурсов как HttpSession в качестве переменной экземпляра. Просто извлеките его в области threadlocal. Вы можете использовать ExternalContext#sessionMap() для управления картой атрибутов сеанса без необходимости импорта javax.servlet в ваш код JSF (что обычно является признаком того, что вы делаете что-то неправильно или неуклюже, благодаря чему вы полностью работаете со своим JSF без используя полномочия JSF).

public String preview() { 
    Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap(); 
    sessionMap.put("countryDetailImageNames", imageNames); 
    sessionMap.put("countryDetailImages", images); 
    sessionMap.put("countrySummary", countrySummary);   
    return "countryPages_View?faces-redirect=true"; 
} 

Лучше, однако, создать управляемый bean-компонент, обработанный сеансом. У вас есть какой-то странный и довольно процедурный и не-OO-дизайн.

@ManagedBean 
@SessionScoped 
public class Country { 

    private List<Something> detailImageNames; 
    private List<Something> images; 
    private Something summary; 

    // ... 
} 

который используется следующим образом внутри CountryPagesDetail:

@ManagedProperty("#{country}") 
private Country country; 

public String preview() { 
    country.setDetailImageNames(imageNames); 
    country.setDetailImages(images); 
    country.setSummary(summary);   
    return "countryPages_View?faces-redirect=true"; 
} 

Он доступен по #{country.detailImageNames} и так далее.

+0

HHmm спасибо, что освободил меня, что в коде небезопасно делать такие вещи :). ОК, и если я хочу получать значения из sessionMap на следующей странице, то я снова получаю sessionMap как 'getExternalContext(). GetSessionMap();' на конструкторе следующей страницы, а затем используйте 'sessionMap.get (" countryDetailImageNames ")', чтобы получить значение с карты. Я прав? Я преследую эту переменную экземпляра так много мест .... (беспокоит) Хорошо, вы имеете в виду всякий раз, когда я хочу помещать что-то в сеанс, как я делаю в методе preview(), я всегда использую sessionMap, как вы предложили. ОК? – Basit

Смежные вопросы