0
votes

In our application we have a dashboard, which will be loaded after login from an init() method with PostConstruct annotation.

Everything works fine, until the session is expired. In this moment, if I click on a button in dashboard, this init method will be called again, although I am not logged in. I will be redirected to the login page and now if I login, the PostConstruct method will not be called anymore and the content of dashboard can not be loaded.

I know that the PostConstruct will be called only once after a session is created (The Controller class is @SessionScoped). I guess the problem is that the server creates a new session after timeout, because the init method get called after timeout and before login, and that leads to not being called after login again. What would be the best solution to solve this problem?

One workaround would be to load the content of dashboard in a method which is not annotated with PostConstruct. But I wonder if the problem can be solved differently.

1
Start by finding out what is called and try to prebent that - Kukeltje

1 Answers

0
votes

You might implement a Servlet filter to monitor the status of your user sessions. This way, you will detect the expired session out of the Managed Bean and the init method won't be called.

This filter might look like:

public class UriFilter implements javax.servlet.Filter {
    @Inject SessionController session;
    private static final String SIGNON_PAGE_URI = "/myappname/engine/index.xhtml";
    private static final String SUBDOMAIN_URI = "/myappname/engine/";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse)response;  
        HttpServletRequest req = (HttpServletRequest )request;  
        String uri = ((HttpServletRequest) request).getRequestURI();
        if( !this.authorize(req ) && !(uri.endsWith("/") || uri.endsWith("index.xhtml") || !uri.endsWith(".xhtml")) ){ 
            if(request.getParameter("fileName") != null)
                res.sendRedirect(SIGNON_PAGE_URI+"?uri="+uri.substring(SUBDOMAIN_URI.length(), uri.length())+"?fileName="+request.getParameter("fileName"));
            else {
                res.setHeader("Cache-Control","no-cache, no-store, must-revalidate");  
                res.setHeader("Pragma","no-cache");  
                res.setDateHeader("Expires",0); 
                res.sendRedirect(SIGNON_PAGE_URI+"?faces-redirect=true");
            }
        } else{  
            //Desativa o cache do browser  
            res.setHeader("Cache-Control","no-cache, no-store, must-revalidate");  
            res.setHeader("Pragma","no-cache");  
            res.setDateHeader("Expires",0); 
            //Processa request e response  
            chain.doFilter( req, res );  
        }


    }

    private boolean authorize( HttpServletRequest req ){  
        boolean authorized = false;  
        HttpSession session = req.getSession(false);         
        if(session != null){  
            if(this.session != null) {
                if(this.session.getLogged() != null) {
                    authorized = true;
                }
            }   
        }  
        return authorized;  
    }

    @Override
    public void destroy() {

    }


}

The SessionController is the @SessionScoped that track the logged user.

In your web.xml file you have to specify the filter:

    <filter>
        <filter-name>URI Filter</filter-name>
        <filter-class>com.myappname.filter.UriFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>URI Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/engine/*</url-pattern>
    </filter-mapping>