Part III: Знайомство з інтеграцією Spring з BlazeDS

Простий приклад

Для створення простої програми інтеграції Spring BlazeDS необхідно:

  • Налаштувати Spring у web.xml.
  • Налаштувати посередника повідомлень BlazeDS як Spring-керований бін у контексті конфігураційного файлу програми.
  • Налаштувати та показувати біни як віддалені об'єкти у контексті конфігураційного файлу програми.

Примітка: В залежності від мапування DispatcherServlet, визначеного в web.xml, можливо вам також потрібно буде налагодити конфігурацію каналу по замовченню у BlazeDS файлі services-config.xml.

У web.xml ви налаштовуєте DispatcherServlet для ініціалізації Spring WebApplicationContext як і раніше. Потім у цій простій конфігурації ви мапуєте всі /messagebroker запити до DispatcherServlet.

<strong>web.xml</strong>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/web-application-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>

</web-app>

У web-application-config.xml спочатку ви налаштовуєте посередник повідомлень BlazeDS як Spring-керований бін, використовуючи теґ message-broker. Це повинно ініціалізувати посередника повідомлень BlazeDS. Якщо використовувати теґ message-broker без відповідних дочірних елементів, то всі вхідні запити DispatcherServlet мапуватимуться в MessageBroker. Можна додати відповідні дочірні елементи для більшого контролю.

Потім, разом з відповідним брокером повідомлення, ви налаштовуєте Spring біни звичайним способом для віддаленого доступу, використовуючи теґ remote-service.

<strong>web-application-config.xml</strong>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:flex="http://www.springframework.org/schema/flex"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/flex
        http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">

<flex:message-broker/>

    <bean id="productService" class="my.package.ProductDAO" >
        <flex:remote-service />
        <constructor-arg ref="dataSource"/>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:~/sprinflexdemodb/sprinflexdemodb" />
    </bean>

</beans>

Описана вище конфігурація дозволяє Flex програмі викликати публічні методи productService біну. Ось мінімальна Flex програма для заповнення таблиці даних переліком продуктів, отриманих віддаленим викликом методу FindAll() класу ProductService.

Зауважимо, що це — той самий код, що використовується при підключенні до звичайної інсталяції BlazeDS: клієнтський код є відокремленим від конкретної серверної реалізації.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:RemoteObject id="ro" destination="productService"/>

    <mx:DataGrid dataProvider="{ro.findAll.lastResult}" width="100%" height="100%"/>

    <mx:Button label="Get Data" click="ro.findAll()"/>

</mx:Application>

Безпека Інтеграції

Повний опис Spring Security виходить за рамки цієї статті. Ви можете звернутися до документації Spring для більш докладної інформації. Налаштування основного файлу web.xml щоб використовувати Spring Security:

<strong>web.xml</strong>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

    <display-name>Spring BlazeDS Integration Samples</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/config/web-application-config.xml
            /WEB-INF/config/web-application-security.xml
        </param-value>
    </context-param>

    <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>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
     </servlet-mapping>

     <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

Для ознайомлення з основним провайдером аутентифікації конфігурація може бути визначена у web-application-security.xml наступним чином:

<strong>web-application-security.xml</strong>
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">

    <http auto-config="true" session-fixation-protection="none"/>

    <authentication-provider>
        <user-service>
            <user name="john" password="john" authorities="ROLE_USER, ROLE_ADMIN" />
            <user name="guest" password="guest" authorities="ROLE_GUEST" />
        </user-service>
    </authentication-provider>

</beans:beans>

Потім у контексті вашої веб-аплікації можна встановити параметри безпеки в звичний спосіб. Наведений нижче приклад визначає, що користувача слід автентифікувати та прив'язати роль ROLE_USER для доступу до методів "find*".

<bean id="productService" class="flex.spring.samples.product.ProductDAO" >
    <flex:remote-service/>
    <constructor-arg ref="dataSource"/>
    <security:intercept-methods>
        <security:protect method="find*" access="ROLE_USER" />
    </security:intercept-methods>
</bean>

Тепер, якщо ви не є автентифікованими в Flex програмі, то при запуску клієнтської програми, отримаєте помилку Access Denied.

Інтеграція Spring Security також дозволяє вам автентифікуватись зсередини Flex програми використовуючи звичайний channelSet.login() API. У наступній версії програми включено простий інтерфейс користувача та базову інфраструктуру для автентфікації з використанням ChannelSet API.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    applicationComplete="applicationCompleteHandler()">

    <mx:Script>
        <![CDATA[

            import mx.messaging.ChannelSet;
            import mx.messaging.channels.AMFChannel;
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;

            private function applicationCompleteHandler():void
            {
                var channel:AMFChannel = new AMFChannel("my-amf", "http://localhost:8080/messagebroker/amf");
                var channelSet:ChannelSet = new ChannelSet();
                channelSet.addChannel(channel);
                ro.channelSet = channelSet;
            }

            private function faultHandler(event:FaultEvent):void
            {
                Alert.show(event.fault.faultString, "Error accessing RemoteObject");
            }

            private function login():void
            {
                ro.channelSet.login(userId.text, password.text);
            }

            private function logout():void
            {
                ro.channelSet.logout();   
            }

        ]]>
    </mx:Script>

    <mx:RemoteObject id="ro" destination="productService" fault="faultHandler(event)"/>

    <mx:Form>
        <mx:FormItem label="User Id">
            <mx:TextInput id="userId"/>
        </mx:FormItem>
        <mx:FormItem label="Password">
            <mx:TextInput id="password" displayAsPassword="true"/>
        </mx:FormItem>
        <mx:FormItem direction="horizontal">
            <mx:Button label="Login" click="login()"/>
            <mx:Button label="Logout" click="logout()"/>
        </mx:FormItem>
    </mx:Form>

    <mx:DataGrid dataProvider="{ro.findAll.lastResult}" width="100%" height="100%"/>

    <mx:Button label="Get Data" click="ro.findAll()"/>

</mx:Application>

Статус та Плани

Проект інтеграції Spring BlazeDS все ще знаходиться в стадії розробки, проте наразі доступний білд Milestone 2 надає потрібні можливісті. Наступним етапом буде забезпечення інтеграцією з BlazeDS Message Service. Інтеграція із сервісом керування даними у LiveCycle Data Services ES також запланована.

Короткі Висновки

Проект інтеграції Spring BlazeDS дозволяє безшовно інтегрувати Flex, BlazeDS і Spring для побудувати виразних, високопродуктивних та добре пророблених програм Rich Internet Applications. Якщо ви вже є Spring розробником, тоді можна використовувати існуючу інфраструктуру і просто виставити ваші біни для для віддаленого доступу Flex клієнтами через BlazeDS remoting. Якщо ви вже є Flex та BlazeDS розробником, тоді можна використовувати інтеграцію Spring BlazeDS для вільного використання багатьох зручних можливостей Spring IoC контейнера та інших компонентів Spring Framework.

Ресурси

Оригінал тут.

Коментарі 7

SharpSteel - 24 вересня 2009, 13:16

У меня не вышло настроить Spring. Сервер отказывается запускать blazeds, так как не смог запустить loader.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

    <display-name>BlazeDS + Spring</display-name>
    <description></description>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/config/web-application-config.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>

</web-app>

ошибка следущая:

INFO: Reloading context [/blazeds]
INFO: Container org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/
blazeds] has not been started
SEVERE: Error listenerStart
SEVERE: Context [/blazeds] startup failed due to previous errors
zenyk - 24 вересня 2009, 13:49

яка версія Spring?

також варто поставити логування в режим DEBUG — покаже детальну помилку чому не завантажилось

SharpSteel - 24 вересня 2009, 16:27

Spring v.3.0.0.M4

в логах следущая ошибка:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 11 in XML document from ServletContext resource [/WEB-INF/applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException: The prefix "flex" for element "flex:message-broker" is not bound.
zenyk - 24 вересня 2009, 17:08

це означає що flex нейм спейс не прописаний:

www.springframework.org/schema/flex

www.springframework.org/schema/flex/spring-flex-1.0.xsd"

SharpSteel - 24 вересня 2009, 16:35

С префиксом разобрался. Я затупил немного)

Вот следущая ошибка:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 12 in XML document from ServletContext resource [/WEB-INF/applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'flex:message-broker'.
SharpSteel - 24 вересня 2009, 16:51

И с этим я разобрался. Но вот на этой ошибке я застрял:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_flexRemotingAnnotationPostProcessor': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.flex.config.json.JsonConfigMapPropertyEditor]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonFactory
zenyk - 24 вересня 2009, 17:12

треба додати JAR звідси

jackson.codehaus.org/Download

Коментувати
© 2009 - 2020, Розробка - соціальна ІТ спільнота.
Контакти: info@rozrobka.com
Правила користування