2013-11-26 3 views
0
@SessionScoped public class User { 
... //settings, attributes, etc 
} 

@ViewScoped public class FooController { 
@ManagedProperty(value="#{user}") 
private User user; 
... 
} 

@RequestScoped public class LoginController { 
@ManagedProperty(value="#{user}") 
private User user; 
public String login() { 
    //handle Servlet 3.0 based authenticate()... if success, make new User object and slap it into context 
    request.getSession().setAttribute("user", user); 
    return "?faces-redirect=true"; 
} 
... 
} 

xhtml страницы включают элементы управления доступом практически на каждой странице. Идеальным было бы то, что они могут войти в систему, и страница обновится, а существующий FooController будет иметь ссылку на текущего пользователя, который условно отображает кнопки/элементы. Поведение заключается в том, что логин происходит, но вид FooController по-прежнему «действителен», поэтому управляемый компонент никогда не пытается быть введенным повторно. Если я перейду со страницы и вернусь на нее [восстановление объекта с расширенным представлением], пользовательский компонент будет хорошо преобразован ... но я бы предпочел не иметь этот промежуточный шаг. Есть идеи?Обновить вид вложенных компонентов JSF beans вставляется в фасоль

Я пробовал различные формы FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("user"); в надежде, что он перетянет его с сеанса, но безрезультатно. Я не хочу тесно связывать код в моем LoginController, чтобы ссылаться на конкретную недействительность FooController или BarController или любого другого, который ссылается на пользовательский компонент.

ответ

0

Ok, я понял это на домой, это была проблема жизненного цикла. Я пытался заставить JSF сделать что-то, что он не должен делать с управляемыми бобами.

Вместо new'ing вверх User объекта и переназначение его к управляемому экземпляру user в LoginController, я изменил метод входа, чтобы выглядеть следующим образом:

public String login() { 
    //handle Servlet 3.0 based authenticate()... if success... 
    User loadedFromDB = someDao.load(principal.getName()); 
    user.setDefaultPage(loadedFromDB.getDefaultPage()); // NOTE: The user object IS THE MANAGED BEAN 
    user.setDefaultScheme(loadedFromDB.getDefaultScheme()); // This is the same object the view scoped bean has a ref on, so directly setting that object's fields proliferates that to any other bean that has the user in scope. 
    ... //etc... not calling NEW, not reassigning object ref to user 
    loadedFromDB = null; 
    return "?faces-redirect=true"; 
} 

Это выполняет то, что было необходимо. Кто знал, если вы прекратите сражаться с картой на минуту и ​​просто воспользуетесь ею, это поможет вам :)

0

Почему вы пытаетесь удалить user@SessionBean), из viewMap (карты @ViewScoped объектов в текущем сеансе работы)?

Вы должны быть удаления FooController, то @ViewScoped, фасоль из viewMap, т.е.

FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("fooControl‌​ler");. 

Это то, что будет избавиться от viewscoped боб и заставить новый, который будет создан. Тогда, конечно, вам все равно нужно обновить страницу.

Если вы намерены извлекать сессионный компонент, однако, вы должны получить доступ к сессии непосредственно:

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("user");. 

Это избавляется от объекта пользователя

+0

Ну, цель состоит не столько в том, чтобы удалить пользовательский компонент, а в том, чтобы размножать обновленный объект User на любой bean. Я протестировал ваше решение, которое работает, но 'FooController' является лишь одним из примерно 20 видов видимых бобов, которые могут быть живы в зависимости от того, на какой странице пользователь входит. [Форма входа - панель всплывающих окон, включенная почти на каждую страницу]. Казалось бы, проблема с запутанностью заключается в том, чтобы использовать кодовое имя 'LoginController '20+ beans для удаления. – Eric

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