2. Configuration for Spring

Library dependencies

In order to initialize GDS/Tide for Spring and Hibernate, you must add granite.jar, granite-hibernate.jar, and granite-spring.jar to your WEB-INF/lib or in the lib directory of an ear. If you use another JPA provider, just replace the granite-hibernate.jar with the appropriate one from the GDS ditribution, for example granite-eclipselink.jar for EclipseLink.

In the case of ear packaging, it is important to put all libs in ear/lib and to make sure that no jar concerning JPA persistence is left in WEB-INF/lib.

Spring MVC simplified configuration

The easiest way to configure GraniteDS for a Spring project is to integrate it with a Spring MVC dispatcher servlet. First add one to web.xml :

web.xml
<web-app version="2.4" ...>
    ...
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>	
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/graniteamf/*</url-pattern>
    </servlet-mapping>	
    ...    
</web-app>

Then an empty dispatcher-servlet.xml :

dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
  xmlns="http://www.springframework.org/schema/beans"
  xsi:schemaLocation="
       http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">      
</beans>

Finally add the Flex filter configuration in the Spring configuration :

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:graniteds="http://www.graniteds.org/config"
  xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       	http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-2.5.xsd
       	http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
       	http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
       	http://www.graniteds.org/config 
            http://www.graniteds.org/public/dtd/2.1.0/granite-config-2.1.xsd">

        ...
  	
  <graniteds:flex-filter url-pattern="/*" tide="true">
      <graniteds:tide-annotations>
          <graniteds:value>org.springframework.stereotype.Controller</graniteds:value>
      </graniteds:tide-annotations>
  </graniteds:flex-filter>
</beans>

The flex-filter declaration will setup an AMF processor for the specified url pattern, and the tide attribute specifies that you want a Tide-enabled service factory. Note that the effective url that will be listened to by GraniteDS is the combination of this url-pattern with the servlet-mapping defined in web.xml for the dispatcher servlet.

Other configurations can be done with flex-filter :

  • tide-annotations is equivalent to tide-component annotated-with="" in granite-config.xml. It allows to define the list of annotation names that enable remote access to Spring beans.
  • tide-roles allows to define a list of security roles that are required to access the Tide remote destination. In general it is not necessary to define this destination-wide security and only rely on Spring security for fine-grained access to individual beans.
  • security-service allows to specify the security service implementation.
  • exception-converters allows to define a list of server-side exception converters. It's the equivalent to exception-converters in granite-config.xml.
  • amf3-message-interceptor allows to define a message interceptor. You have to define the bean name of an existing bean implementing AMFMessageInterceptor.

Additional elements can also be configured in the Spring beans file :

  • tide-identity allows to declare the identity bean. When using Spring Security ACL you can define here the necessary attributes acl-service, sid-retrieval-strategy and object-identity-retrieval-strategy.
  • tide-persistence allows to declare the persistence implementation for your application. It is not necessary when you have only one transactionManager, otherwise just specify the name of the transactionManager to use. Tide/Spring will automatically determine the kind of transaction management it should use (JTA, JPA or Hibernate API).

Generic configuration for Spring

If you don't use the simplified configuration described above, you have to add the following configuration to your web.xml:

web.xml
<web-app version="2.4" ...>
    ...
    <!-- Granite config context listener -->
    <listener>
        <listener-class>org.granite.config.GraniteConfigListener</listener-class>
    </listener>

    <!-- Spring -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext.xml
        	     classpath*:applicationContextSecurity.xml
        </param-value>
    </context-param>
    
     <!-- Spring listener -->
     <listener>
             <listener-class>
                     org.springframework.web.context.ContextLoaderListener
             </listener-class>
     </listener>

     <!-- Spring listener for web-scopes (request, session) -->
     <listener>
             <listener-class>
                     org.springframework.web.context.request.RequestContextListener
             </listener-class>
     </listener>
    
     <filter>
	 <filter-name>springSecurityFilterChain</filter-name>
	 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
     </filter>
     <filter-mapping>
	<filter-name>springSecurityFilterChain</filter-name>
	<url-pattern>/*</url-pattern>
     </filter-mapping> 
    
     <!-- GDS AMF message filter -->
     <filter>
        <filter-name>AMFMessageFilter</filter-name> 
        <filter-class>org.granite.messaging.webapp.AMFMessageFilter</filter-class> 
        
        <!--
        Uncomment (part of) this block if configs are not present at default locations.
        <init-param>
            <param-name>servicesConfigPath</param-name>
            <param-value>/WEB-INF/flex/services-config.xml</param-value>
        </init-param>
        <init-param>
            <param-name>graniteConfigPath</param-name>
            <param-value>/WEB-INF/granite/granite-config.xml</param-value>
        </init-param-->

    </filter>
    
    <filter-mapping>
        <filter-name>AMFMessageFilter</filter-name> 
        <url-pattern>/graniteamf/*</url-pattern> 
    </filter-mapping>
    
    <!-- GDS AMF Servlet -->
    <servlet>
        <servlet-name>AMFMessageServlet</servlet-name>
        <servlet-class>org.granite.messaging.webapp.AMFMessageServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    ...
</web-app>

Of course the Spring configuration part can be changed to suit the needs of your application. This is just a basic example of a Spring application configuration. The important parts for Tide are the GDS servlets/filters.

Then you have to configure the specific Tide/Spring destination and service factory in service-config.xml:

services-config.xml
<services-config>

    <services>
        <service id="granite-service"
            class="flex.messaging.services.RemotingService"
            messageTypes="flex.messaging.messages.RemotingMessage">
            <!--
             ! Use "tideSpringFactory" and "graniteamf" for "spring" destination (see
             ! below). The destination must be "spring" when using Tide with default
             ! configuration.
             !-->
            <destination id="spring">
                <channels>
                    <channel ref="graniteamf"/>
                </channels>
                <properties>
                    <factory>tideSpringFactory</factory>
                    <entityManagerFactoryBeanName>
                        entityManagerFactory
                    </entityManagerFactoryBeanName>
                </properties>
            </destination>
        </service>
    </services>

    <!--
     ! Declare tideSpringFactory service factory.
     !-->
    <factories>
        <factory id="tideSpringFactory"
            class="org.granite.tide.spring.SpringServiceFactory" />
    </factories>

    <!--
     ! Declare my-graniteamf channel.
     !-->
    <channels>
        <channel-definition id="graniteamf" class="mx.messaging.channels.AMFChannel">
            <endpoint
                uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf"
                class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>

</services-config>

Note that the destination named "spring" will be the one and only configuration needed for all remote component calls.

There is a little more configuration in granite-config.xml for Tide and Spring security integration:

granite-config.xml without automatic scanning
<granite-config>
    <externalizers>
        <externalizer type="org.granite.hibernate.HibernateExternalizer">
            <include annotated-with="javax.persistence.Entity"/>
            <include annotated-with="javax.persistence.MappedSuperclass"/>
            <include annotated-with="javax.persistence.Embeddable"/>
        </externalizer>
        ...
    </externalizers>
    
    ...

    <security type="org.granite.messaging.service.security.SpringSecurityService"/>

    <tide-components>
        <!-- List of component matchers, see 'Enabling components' section -->
    </tide-components>
    
</granite-config>

This part is more simple with automatic scanning:

granite-config.xml with automatic scanning
<granite-config scan="true">

    <security type="org.granite.messaging.service.security.SpringSecurityService"/>

    <tide-components>
        <!-- List of component matchers, see 'Enabling components' section -->
    </tide-components>

</granite-config>

 

Note that this default configuration will only allow lazy loading with JPA providers declared with a bean name entityManagerFactory. If you need to use a plain Hibernate Session, you will have to change the <entityManagerFactoryBeanName> in service-config.xml to <persistence-manager-bean-name>tidePersistenceManager</persistence-manager-bean-name> and add a few lines to applicationContext.xml that will declare a special Tide persistence manager that is able to handle the Hibernate API (assuming here that the Hibernate session factory is named sessionFactory):

applicationContext.xml
  <!-- All this AOP stuff just to ensure the Tide persistence manager will be transactional -->
  <aop:config>
    <aop:pointcut id="tidePersistenceManagerMethods" 
        expression="execution(* org.granite.tide.ITidePersistenceManager.*(..))"/>
    <aop:advisor advice-ref="tidePersistenceManagerMethodsTxAdvice" 
        pointcut-ref="tidePersistenceManagerMethods"/>
  </aop:config>

  <tx:advice id="tidePersistenceManagerMethodsTxAdvice" 
    transaction-manager="transactionManager">
    <tx:attributes>
      <tx:method name="*" propagation="REQUIRED" read-only="true"/>
    </tx:attributes>
  </tx:advice>

  <bean id="tidePersistenceManager"
    class="org.granite.tide.hibernate.HibernateSessionManager" scope="request">
    <constructor-arg>
      <ref bean="sessionFactory"/>
    </constructor-arg>
  </bean>

 


Browse Space

- Pages
- Blog
- Labels
- Attachments
- Bookmarks
- Mail
- Advanced

Explore Confluence

- Popular Labels
- Notation Guide

Your Account

Log In

Other Features

Add Content


Copyright © 2011 Granite Data Services S.A.S. All Rights Reserved.