2012-12-21 20 views
5

W mojej aplikacji JSF istnieje Filter, który służy do sprawdzania procesu uwierzytelniania. Gdy uwierzytelnianie nie powiedzie się, filtr przekierowuje do login.xhtml.Ustaw twarze wiadomości przez filtr

Jak mogę przekazać FacesMessage do mojej strony logowania od Filter?

Chociaż użyłem poniżej, To nie jest w porządku.

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null)); 

AuthenticationFilter.java

public class AuthenticationFilter implements Filter { 
    private FilterConfig config; 
    private ServletContext servletContext; 

    public void init(FilterConfig filterConfig) { 
     config = filterConfig; 
     servletContext = config.getServletContext(); 
    } 

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
     HttpServletRequest httpRequest = (HttpServletRequest) servletRequest; 
     HttpServletResponse httpResponse = (HttpServletResponse) servletResponse; 
     HttpSession session = httpRequest.getSession(); 
     User user = (User) session.getAttribute(Constants.LOGIN_USER); 
     if (user == null) { 
      ... 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null)); 

      String loginView = httpRequest.getContextPath() + Constants.LOGIN_PAGE; 
      httpResponse.sendRedirect(loginView); 
     } else if (!user.getRole().equals(Role.SYSTEM_ADMINISTRATOR)) { 
      .... 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null)); 

      String loginView = httpRequest.getContextPath() + Constants.LOGIN_PAGE; 
      httpResponse.sendRedirect(loginView); 
     } else { 
      filterChain.doFilter(servletRequest, servletResponse); 
     } 
     servletContext.log("Exiting the filter"); 
    } 

    public void destroy() { 
     //Nothing to do. 
    } 
} 

Odpowiedz

7

FacesContext jest tworzony przez FacesServlet. Gdy znajdujesz się w filtrze, nie jest on jeszcze wywoływany. Filtry są uruchamiane przed serwletami. Więc nigdy nie możesz dostać do ręki FacesContext w filtrze. Ponadto twarze wiadomości są określane jako żądania, więc przekierowanie spowodowałoby ich zniknięcie.

Pozwól, aby login.xhtml ustawił się sam podczas <f:event type="preRenderView">. Najprościej byłoby pozwolić filtrowi tymczasowo umieścić go w zakresie sesji.

session.setAttribute("message", message); 
httpResponse.sendRedirect(loginView); 

które następnie usunąć z zakresu sesji w wstępnego renderowania widzenia słuchacza metody login.xhtml:

String message = (String) externalContext.getSessionMap().remove("message"); 

if (message != null) { 
    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null)); 
} 
+0

dzięki za wsparcie. – CycDemo

+0

Nie ma za co. – BalusC

0

wpadłem na podobnym problemie z próby uzyskania FacesContext w czasomierz EJB. BalusC wskazał na wielu wątkach, że nie można tego zrobić. Alternatywnie można użyć "ServletContextListener", ale ScheduledExecutorService nie definiuje harmonogramu tak dobrze jak timer EJB.

W każdym razie jedną z sugestii, które zrobił, było wysłanie żądania strony WWW do stronicowania JSF, wspieranego przez zarządzany komponent bean, w celu wykorzystania metod z zakresu zasóbowego aplikacji, które chciałem skonfigurować za pomocą licznika czasu.

Wspominam o tym, ponieważ wygląda na to, że można zrobić coś podobnego, gdzie przekazuje się param do strony JSF z żądaną wiadomością i adresem IP użytkownika lub czymś podobnym. Ta strona może być wspierana przez komponent bean o żądanym zakresie, do którego wstrzyknięto komponentowy obszar aplikacji, który przechowuje te na mapie z adresem IP jako kluczem. Następnie, gdy użytkownik zostanie przekierowany na stronę logowania, strona ta może wywołać metodę komunikatu o błędzie pobierania na komponencie o żądanym zakresie z tym samym komponentem, do którego wstrzyknięto komponentowy obszar aplikacji, który otrzymuje komunikat o błędzie dla tego adresu IP lub czegoś podobnego.

W każdym razie, jestem pewien, że odpowiedź BalusC jest wystarczająca i bardziej właściwa niż ta, ale jego "po prostu prośba z timera timera" zadziałała dobrze dla mnie w zakresie planowania wywołań metod dotyczących fasoli o zasięgu aplikacji, a ja pomyślałem, że mogę tu skorzystać z jego możliwości.

@BalusC Czy masz pojęcie o tym, o czym mówię? Nie mogę tego znaleźć.

Powiązane problemy