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