how to access faces context and backing beans in a servlet filter

    So the thing is that for some reason or the other you would like to populate values in your Javaserver Faces backing beans in a servlet filter. Ur big fat mama in this case is Craig McClanaghan (much kudos to him btw for all the work he has done for Struts and JSF). Craig happily explains how to get a reference to your bean from the faces context, but then bluntly states that sorry, because a filter is running before a Faces servlet the context hasn't been set up for this request, so you cannot access it in a filter. Stupid as I am, I didn't believe that.

    JSF people probably forgot the whole filter spec, which is SOO useful for all handly things, such as authorization and for supporting stupid devices that only know how to generate GET requests. Anyway, the code to set up a faces context in a filter:


// You need an inner class to be able to call FacesContext.setCurrentInstance
// since it's a protected method
private abstract static class InnerFacesContext extends FacesContext 
{
  protected static void setFacesContextAsCurrentInstance(FacesContext facesContext) {
    FacesContext.setCurrentInstance(facesContext);
  }
}

private FacesContext getFacesContext(ServletRequest request, ServletResponse response) {
  // Try to get it first 
  FacesContext facesContext = FacesContext.getCurrentInstance();
  if (facesContext != null) return facesContext;

  FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
  LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); 
  Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);

  // Either set a private member servletContext = filterConfig.getServletContext(); 
  // in you filter init() method or set it here like this:
  // ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();
  // Note that the above line would fail if you are using any other protocol than http

  // Doesn't set this instance as the current instance of FacesContext.getCurrentInstance 
  facesContext = contextFactory.getFacesContext(servletContext, request, response, lifecycle);

  // Set using our inner class
  InnerFacesContext.setFacesContextAsCurrentInstance(facesContext);

  // set a new viewRoot, otherwise context.getViewRoot returns null
  UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "yourOwnID");
facesContext.setViewRoot(view);

  return facesContext;
}

// You can even use a NavigationHandler
  NavigationHandler navigationHandler = facesContext.getApplication().getNavigationHandler();

  navigationHandler.handleNavigation(facesContext,"getrequest", "works");

// you could just render the page here but since we are still in filter, it might be
// a better idea to forward to the actual page
// facesContext.getApplication().getViewHandler().renderView(facesContext, facesContext.getViewRoot() );

  request.getRequestDispatcher(facesContext.getViewRoot().getViewId() ).forward(request, response);


你可能感兴趣的:(bean,servlet,struts,JSF,Access)