Recent Changes - Search:

WebFacets

HOW-TOs

Authentication



SourceForge Logo









YourKit Java Profiler

Architecture

WebFacets is an extension of JFacets that allows facets to integrate nicely into J2EE WebApps.

Basically, WebFacets extends the FacetContext to enable facets to get access to the Servlet API objects (HttpServletRequest, HttpServletResponse and ServletContext). This way, you can get hold of the javax.servlet.http.* objects transparently inside your facets.

A ServletFilter is used to initialize the jfacets stuff for incoming requests in a transparent manner.

The WebFacetContext

WebFacets extends the base FacetContext provided in JFacets in order to use the facets with other web components (JSPs, servlets, Struts actions, whatever).

This is done by providing a new FacetContext (net.sourceforge.jfacets.web.IWebFacetContext) and associated FacetContextFactory (net.sourceforge.jfacets.web.WebFacetContextFactory), which is wired in using the Spring context.

This way, you can access all the web stuff from your facets like this :

// somewhere inside a ''facet''...
IWebFacetContext ctx = (IWebFacetContext)getContext();
ctx.getRequest().setAttribute("something", anObject);

Or, in Groovy :

// somewhere inside a Groovy facet
context.request.setAttribute("something", anObject);

The WebFacetContextFactory is simply injected in the system via the Spring ApplicationContext.

The WebFacetsFilter

This new component allows to obtain references on Servlet API objects (request, response and context) at run-time, and inject them into the FacetContextFactory so that is can create contexts with web objects (most of the "lightweight" components are actually instanciated when the filter receives a request, and used in this scope only - see below).

Basically, the filter performs the following tasks :

  • get hold of the jFacets bean as defined in the Spring context ;
  • get the WebFacetContextFactory and set the request, response and servlet context ;
  • bind the jFacets bean to the request for later use.

All this is completely transparent, you don't even have to really know it when programming with WebFacets.

The filter has to be configured in the webapp's web.xml, have a look here for more infos about that.

Spring config

Of course, all the wiring of the various components is done through Spring. Actually, only the filter is not a Spring bean.

The only noticeable thing here is the singleton policy. As you can see in the webFacetsAppCtx.xml context (see below), many beans are not singletons any more. This is due to the concurrency model of webapps, and the fact we need to inject request, response and servlet context into the FacetContextFactory for each incoming request. Using a factory instance per request is pretty simple and should not really be a performance issue.

Here under is an example ApplicationContext (you can find this file in the JFacets distribution - config-src/webFacetsAppCtx.xml) :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!--

A Spring Context for WebFacets that already provides
support for Java/XML and Groovy facets.

Configurable stuff in there :
 * profileRepository : specify your implementation class (and config options if any)  ;
 * xmlFacetDescriptorManager : specify the path the the XML file (CLASSPATH resource) ;
 * groovyFacetDescriptorManager : specify the base packages for Groovy facets discovery.

-->


<beans>

        <!--                               -->
        <!--      ProfileRepository        -->
        <!--                               -->
        <!--  This *has* to be configured  -->
        <!--  for your application.        -->
        <!--                               -->
        <bean id="profileRepository" singleton="true" 
                        class="net.sourceforge.jfacets.simpleprofiles.SimpleProfileRepository">

        </bean>

        <!--                                 -->
        <!--         Facet Managers          -->
        <!--                                 -->
        <!-- The config below allows to use  -->
        <!-- both plain java and groovy      -->
        <!-- facets in the same app.         -->
        <!--                                 -->
        <!-- Look at each manager's config   -->
        <!-- options.                        -->
        <!--                                 -->

        <!-- the XML facet descriptor manager -->
        <bean id="xmlFacetDescriptorManager" singleton="true"
                        class="net.sourceforge.jfacets.impl.FacetDescriptorManager">

                <constructor-arg index="0"><value>facets.xml</value></constructor-arg>
        </bean>

        <!-- the Groovy facet descriptor manager -->
        <bean id="groovyFacetDescriptorManager" singleton="true"
                        class="net.sourceforge.jfacets.groovy.GroovyFacetDescriptorManager"
                        init-method="initialize">

                <constructor-arg index="0">
                        <list>
                                <value>groovy-facets</value>
                        </list>
                </constructor-arg>
        </bean>

        <!-- the Meta facet descriptor manager -->
        <bean id="facetDescriptorManager" singleton="true"
                        class="net.sourceforge.jfacets.impl.MetaFacetDescriptorManager"
                        init-method="initialize">
              
                <property name="managers">
                        <list>
                                <ref bean="groovyFacetDescriptorManager"/>
                                <ref bean="xmlFacetDescriptorManager"/>
                        </list>
                </property>                              
        </bean> 

        <!--                                 -->
        <!-- Facet & Facet Context factories -->
        <!--                                 -->
        <!-- No additional config is         -->
        <!-- required here.                  -->
        <!--                                 -->

        <!--  a fall back factory, so that we can crate non-groovy facets too  -->
        <bean id="fallbackFacetFactory" singleton="true" 
                        class="net.sourceforge.jfacets.impl.DefaultFacetFactory">

        </bean>

        <!--  the main facet factory : creates GroovyFacets -->
        <bean id="facetFactory" singleton="true" 
                        class="net.sourceforge.jfacets.groovy.GroovyFacetFactory">

                <property name="fallbackFactory"><ref bean="fallbackFacetFactory"/></property>     
        </bean>

        <!--  the web facet context factory -->
        <bean id="facetContextFactory" singleton="false" 
                        class="net.sourceforge.jfacets.web.WebFacetContextFactory">

        </bean>

        <!--                                    -->
        <!--          Facet Repository          -->
        <!--                                    -->
        <!-- No additional config is required   -->
        <!-- here.                              -->
        <!--                                    -->

        <bean id="facetRepository" singleton="false"
                        class="net.sourceforge.jfacets.impl.FacetRepositoryImpl">

                <constructor-arg index="0"><ref bean="profileRepository"/></constructor-arg>
                <constructor-arg index="1"><ref bean="facetFactory"/></constructor-arg>
                <constructor-arg index="2"><ref bean="facetContextFactory"/></constructor-arg>
                <constructor-arg index="3"><ref bean="facetDescriptorManager"/></constructor-arg>
        </bean> 

        <!--                                    -->
        <!--       top-level WebFacets bean     -->
        <!--                                    -->
        <!-- No additional config is required   -->
        <!-- here.                              -->
        <!--                                    -->

        <bean id="jFacets" singleton="false" class="net.sourceforge.jfacets.web.WebFacets">
                <property name="facetRepository"><ref bean="facetRepository"/></property>
        </bean> 

</beans>

Spring Context Loading

The Spring ApplicationContext to be used by WebFacets can be specified in the WebFacetsFilter configuration (in web.xml). There are 3 ways for the framework to locate the context :

  1. Use the default XML context named webFacetsAppCtx.xml and searched in the CLASSPATH (default package) ;
  2. Specify the name of the CLASSPATH resource to be used as an init param of the filter ;
  3. Use Spring's ContextLoader filter/servlet.

1/ and 2/ allows to integrate easier in webapps that don't use Spring for anything else, or where you don't need to mix WebFacets beans with other Spring beans.

3/ allows to use multiple contexts, and use other Spring stuff in an integrated manner (Acegi, SpringMVC, etc). It's the preferred way, since it follows the overall principles of Spring. This option is only available from JFacets v1.3 and higher.

NOTE
Of course, whatever option you choose, it has no impact on how you assign and use the facets in your application.

Edit - History - Print - Recent Changes - Search
Page last modified on September 16, 2006, at 04:37 PM