You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2014/01/27 23:58:15 UTC

svn commit: r1561900 - /myfaces/site/cms-site/trunk/content/wiki/access-facescontext-from-servlet.mdtext

Author: lu4242
Date: Mon Jan 27 22:58:15 2014
New Revision: 1561900

URL: http://svn.apache.org/r1561900
Log:
test confluence to apache cms migration

Added:
    myfaces/site/cms-site/trunk/content/wiki/access-facescontext-from-servlet.mdtext

Added: myfaces/site/cms-site/trunk/content/wiki/access-facescontext-from-servlet.mdtext
URL: http://svn.apache.org/viewvc/myfaces/site/cms-site/trunk/content/wiki/access-facescontext-from-servlet.mdtext?rev=1561900&view=auto
==============================================================================
--- myfaces/site/cms-site/trunk/content/wiki/access-facescontext-from-servlet.mdtext (added)
+++ myfaces/site/cms-site/trunk/content/wiki/access-facescontext-from-servlet.mdtext Mon Jan 27 22:58:15 2014
@@ -0,0 +1,140 @@
+Title: Access FacesContext From Servlet
+<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{scrollbar}](cdata[{scrollbar}.html)
+]></ac:plain-text-body></ac:macro>
+<ac:macro ac:name="info"><ac:rich-text-body>
+<p>In JSF 2.0 or later it is better to create a custom ResourceHandler
+wrapper and use FacesServlet instead. In that way, JSF will create
+FacesContext instance.</p></ac:rich-text-body></ac:macro>
+
+<p>There have been several posts asking how to get a Faces Context from
+outside of JSF such as in a servlet. There are many reasons for doing this
+such as:</p>
+
+<ol>
+	<li>Getting to a managed bean in session scope</li>
+	<li>Getting or setting the current view id</li>
+	<li>Generating additional content to be displayed in a faces
+component</li>
+	<li>Performing authentication and session management</li>
+	<li>Various other reasons you can come up with...</li>
+</ol>
+
+
+<p>Below is one way to do this. </p>
+
+<p><em>&lt;disclaimer&gt;I can't take credit for the approach as the
+question popped up last year on Sun's Creator forum and has since been
+modified/adapted/shared so many times I can no longer remember what is
+adopted code and what is original. However, it works and works well &ndash;
+at least in our Tomcat 5.5x apps&lt;/disclaimer&gt;</em></p>
+
+<p>We used several servlets and filters to drive external content into our
+JSF apps. In particular we use this approach to generate Jasper Reports,
+JFreeChart images and generate PDFs on the fly using iText. The same code
+is also used in a filter to manage sessions.</p>
+
+<ac:macro ac:name="code"><ac:parameter
+ac:name="title">AbstractFacesServlet.java</ac:parameter><ac:plain-text-body><![CDATA[
+public abstract class AbstractFacesServlet extends HttpServlet {
+       
+    public AbstractFacesServlet() {
+	super();
+    }
+    public void init(ServletConfig config) throws ServletException {
+	super.init(config);
+    }	 
+    protected abstract void processRequest(HttpServletRequest request,
+HttpServletResponse response) throws ServletException, IOException;
+    
+    /** Handles the HTTP <code>GET</code> method.
+    * @param request servlet request
+    * @param response servlet response
+    */
+    protected void doGet(HttpServletRequest request, HttpServletResponse
+response) throws ServletException, IOException {
+	processRequest(request, response); 
+    }
+    protected void log(FacesContext facesContext, String message) {
+	facesContext.getExternalContext().log(message);
+    }
+    /** Handles the HTTP <code>POST</code> method.
+    * @param request servlet request
+    * @param response servlet response
+    */ 
+    protected void doPost(HttpServletRequest request, HttpServletResponse
+response) throws ServletException, IOException {
+	processRequest(request, response);
+    }
+    protected FacesContext getFacesContext(HttpServletRequest request,
+HttpServletResponse response) {
+	FacesContext facesContext = FacesContext.getCurrentInstance();
+	if (facesContext == null) {
+
+	    FacesContextFactory contextFactory	=
+(FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
+	    LifecycleFactory lifecycleFactory =
+(LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); 
+	    Lifecycle lifecycle =
+lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
+
+	    facesContext =
+contextFactory.getFacesContext(request.getSession().getServletContext(),
+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,
+"");
+	    facesContext.setViewRoot(view);		   
+	}
+	return facesContext;
+    }
+    public void removeFacesContext() {
+	InnerFacesContext.setFacesContextAsCurrentInstance(null);
+    }
+    protected Application getApplication(FacesContext facesContext) {
+	return facesContext.getApplication();	     
+    }
+    protected Object getManagedBean(String beanName, FacesContext
+facesContext) {        
+	return
+getApplication(facesContext).getVariableResolver().resolveVariable(facesContext,
+beanName);
+    }
+    // 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);
+	}
+    }	  
+}
+]
+]></ac:plain-text-body></ac:macro>
+
+<p>This is simple to use and extend and, as I stated earlier, has been
+handed around several lists. We provide convienience methods for access to
+managed beans and to the Application. Concrete classes extend the base
+class and provide getters for session-managed components etc.</p>
+
+<p>Note: You should always relase the FacesContext after you're done with
+it (see <a class="external-link"
+href="http://ocpsoft.com/java/jsf-java/please-tell-your-developers-to-call-facescontextrelease/"
+rel="nofollow">http://ocpsoft.com/java/jsf-java/please-tell-your-developers-to-call-facescontextrelease/</a>).
+I've added the removeFacesContext() method to the above code, and you
+should call that after calling .release() on the context.</p>
+
+<p><em>In closing, I'm sure there may be better ways for doing this but
+more importantly, there are probably good reasons for <span
+style="text-decoration: underline;">not doing this at all</span> and
+changing to Phase Listeners and staying within the JSF framework which I
+think is an important topic for continued discussion.</em></p>
+<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{scrollbar}](cdata[{scrollbar}.html)
+]></ac:plain-text-body></ac:macro>