On 1/7/06, Craig McClanahan <[EMAIL PROTECTED]> wrote:

> In a JSF application, there's actually two ways to implement classic Front
> Controller type functionality, such as "send the user to the logon page if
> they are not currently logged on":
>

Concrete examples will help make this clearer, so here are the pure-servlet
and pure-JSF ways to accomplish this:

* With a servlet Filter that gets invoked in front of the JSF controller
> (Shale has support for this).  When
>   Struts 1.0 was created, there was no such thing, so we had to provide
> this capability inside ActionServlet.
>   Now, the container has a much more flexible mechanism that can work on
> either JSF requests or
>   non-JSF requests.
>

import com.mycompany.mypackage.User;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class LogonCheckFilter implements Filter {

    // No initialization required
    public void init(FiterConfig config) {}

    // No finalization required
    public void destroy() {}

    // Process each incoming request this filter is mapped to
    public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {

        // Check for a user object in session scope
        User user = (User)
          ((HttpServletRequest) request).getSession().getAttribute("user");

        // NOTE - we do not need it for this use case, but we also have
access
        // to the current request's parameters, headers, cookies, and so on

        // If the user is not logged on, redirect to the logon page
        if (user == null) {
            // Do a RequestDispatch.forward() to display the logon page
instead of the requested page
            RequestDispatcher rd = ((HttpServletRequest)
request).getRequestDispatcher("/logon.jsp");
            rd.forward(request, response);
            return;
        }

        // Otherwise, do the standard processing for this request
        chain.doFilter(request, response);

    }

}


* By using a JSF PhaseListener to interact with the JSF Lifecycle (which has
> Controller capabilities as well)
>   This is the way most AJAX enabled JSF components interact with the
> server side of their asynchronous
>   requests ... they submit a request to a URL mapped to FacesServlet, and
> a component-provided
>   PhaseListener intercepts control after the Restore View phase has
> completed.  But the point is clear ...
>   the Lifecycle implementation plays a controller role as well, and you
> can customize its behavior with
>   phase listeners quite easily.
>
>
import com.mycompany.mypackage.User;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

public class LogonCheckListener implements PhaseListener {

    // Tell JSF which lifecycle phase(s) we are interested in
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

    // No "before phase" processing required
    public void beforePhase(PhaseEvent event) {}

    // Perform the logon check after restore view has been completed
    public void afterPhase(PhaseEvent event) {

        // Check for a user object in session scope
        FacesContext context = event.getFacesContext();
        User user = (User)
          context.getExternalContext().getSessionMap().get("user");

        // NOTE - we do not need it for this use case, but we also have
access
        // to the current request's parameters, headers, cookies, and so on,
        // as well as the restored state of the component tree for the page
that
        // is submitting this request, as of the last time it was rendered

        // If the user is not logged on, redirect to the logon page
        if (user == null) {
            // Create the view for the logon page and render it
            context.getApplication().getViewHandle().createView
              (context, "/logon.jsp");
            context.renderResponse();
            return;
        }

        // Otherwise, do the standard processing for this request
        ; // No extra processing required

    }

}

Both approaches are functionally equivalent, in that (when the user is not
logged on) they bypass the normal form submit processing and cause the logon
page to be rendered instead.  If the user *is* already logged on, the
standard processing proceeds.

Craig

Reply via email to