2012-12-21 32 views
5

Trong ứng dụng JSF của tôi, có một Filter được sử dụng để kiểm tra quá trình authenticati0n. Khi xác thực thất bại, bộ lọc chuyển hướng đến login.xhtml.Đặt FacesMessage theo Bộ lọc

Tôi làm cách nào để chuyển FacesMessage vào trang đăng nhập của mình từ Filter?

Mặc dù, tôi đã sử dụng bên dưới, Không được.

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. 
    } 
} 

Trả lời

7

Các FacesContext được tạo ra bởi các FacesServlet. Khi bạn đang ở trong một bộ lọc, nó chưa được gọi. Bộ lọc chạy trước các servlet. Vì vậy, bạn không bao giờ có thể có được một bàn tay để FacesContext trong một bộ lọc. Ngoài ra, đối mặt với các tin nhắn được yêu cầu phạm vi, do đó, chuyển hướng sẽ khiến chúng biến mất.

Cho phép tự động đặt login.xhtml đặt trong thời gian <f:event type="preRenderView">. Cách dễ nhất là để cho bộ lọc đặt nó tạm thời trong phạm vi phiên.

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

Mà bạn sau đó loại bỏ khỏi phạm vi phiên trước render xem phương pháp nghe của login.xhtml:

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

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

cảm ơn sự hỗ trợ của bạn. – CycDemo

+0

Bạn được chào đón. – BalusC

0

Tôi chạy vào một vấn đề tương tự với cố gắng để có được FacesContext trong một timer EJB. BalusC đã chỉ ra nhiều chủ đề mà không thể làm được điều này. Ngoài ra, bạn có thể sử dụng một 'ServletContextListener', nhưng ScheduledExecutorService không xác định lịch trình là độc đáo như một bộ đếm thời gian EJB.

Trong mọi trường hợp, một đề xuất mà anh ta đưa ra là thực sự đưa ra yêu cầu web tới một trang JSF được hỗ trợ bởi một bean được quản lý để sử dụng các phương pháp trên bean phạm vi ứng dụng mà tôi muốn thiết lập với bộ hẹn giờ.

Tôi đề cập đến điều này, vì có vẻ như bạn có thể làm điều gì đó tương tự, nơi bạn chuyển một thông số tới trang JSF với thông điệp bạn muốn và địa chỉ IP của người dùng hoặc thứ gì đó. Trang đó có thể được hỗ trợ bởi một bean có phạm vi yêu cầu, trong đó có một bean có phạm vi ứng dụng được chèn vào trong đó lưu trữ những thứ đó trong một bản đồ với IP làm khóa. Sau đó, khi người dùng được chuyển hướng đến trang đăng nhập, trang đó có thể gọi một phương thức nhận thông báo lỗi trên một bean có phạm vi yêu cầu với cùng một phạm vi ứng dụng được chèn vào nó, nó nhận được thông báo lỗi cho IP đó hoặc một thứ gì đó dọc theo các dòng đó.

Trong mọi trường hợp, tôi chắc chắn rằng câu trả lời của BalusC là đầy đủ và phù hợp hơn, nhưng đề xuất 'chỉ cần thực hiện yêu cầu từ bộ đếm thời gian ejb' đã làm việc tốt cho tôi để lên lịch các cuộc gọi phương thức trên các ứng dụng, và tôi nghĩ rằng tôi có thể sử dụng nó ở đây.

@BalusC bạn có bất kỳ ý tưởng nào về bài đăng mà tôi đang đề cập đến không? Tôi không thể tìm thấy nó.

Các vấn đề liên quan