Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set FacesMessage by Filter

In my JSF Application, there is a Filter which is used to check the authenticati0n process. When the authentication is failed, the filter redirect to login.xhtml.

How can I pass the FacesMessage to my login page from Filter?

Although, I used below, It is not OK.

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.
    }
}
like image 630
Zaw Than oo Avatar asked Dec 21 '12 05:12

Zaw Than oo


1 Answers

The FacesContext is created by the FacesServlet. When you're inside a filter, it's not been invoked yet. Filters run before servlets. So you can never get a hand to the FacesContext in a filter. Plus, faces messages are request scoped, so a redirect would have made them to disappear anyway.

Let the login.xhtml set it by itself during a <f:event type="preRenderView">. Easiest way would be to let the filter put it temporarily in the session scope.

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

Which you then remove from the session scope in pre render view listener method of login.xhtml:

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

if (message != null) {
    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
}
like image 91
BalusC Avatar answered Oct 23 '22 19:10

BalusC