引言
RIA(Rich Internet Application)—— 富 Internet 应用是种融入了传统桌面应用系统功能和特性 Web 应用系统RIA 结合了桌面应用反应快、交互性强优点和传统 Web 应用易于部署和维护特性从而为用户提供了更加健壮表现力更加丰富 Web 应用Adobe Flex 是当前流行基于 Flash RIA 开源框架您可以利用 Flex 基于 XML MXML、ActionScript 以及 SWC 文件(Flex 组件库)创建包含丰富图表、3D 特效、动画、音频以及视频用户界面而所有 Flex 组件将会由 Flex 编译器编译生成 SWF 2进制文件在 Flash Player 中运行
Spring 是个轻量级 J2EE 开源应用框架Spring 基于两大核心特性控制反转(Inversion of ControlIOC)和面向方面编程(Aspect-Oriented ProgrammingAOP)插件式架构降低了应用组件的间耦合性借助于 XML 配置文件Spring 容器可以轻松地帮助您管理应用组件以及它们的间依赖性同时 Spring 还提供事务管理框架、DAO 支持、支持主流 O/R Mapping 框架集成、支持各种标准 J2EE 组件技术集成(JavaMail/EJB/JMS/Web Service 等)、支持各种视图技术(Web 视图和非 Web 视图)集成
Hibernate 是 Java 平台上种成熟、全功能 O/R Mapping(对象 / 关系映射)开源框架Hibernate 在分层 J2EE 架构中位于数据持久化层它封装了所有数据访问细节使业务逻辑层可以专注于实现业务逻辑Hibernate 使用 O/R Mapping 将对象模型中对象映射到基于 SQL 关系数据模型中去通过使用 HQL(Hiberante Query Language)实现 Java 对象持久化使得您可以应用面向对象思维方式操纵数据库另外Hibernate O/R Mapping 还提供延迟加载、分布式缓存Cache等高级特性这样有利于缩短开发周期和降低开发成本
有关举例
本文样例是比较流行在线宠物商店应用场景分为两个部分:
demo_client:Flex 项目主要由 Flex 实现用户界面生成和对用户动作响应处理
demo_central:Java Web 项目主要由 Spring 实现业务逻辑、由 Hibernate 实现数据库读写访问控制以及由 BlazeDS 提供 Flex 访问远程对象接口在本文中 Spring、BlazeDS 和 Hibernate 所依赖 Jar 包均拷贝到 demo_central 项目 WebContent/WEB-INF/lib 目录下部署到 Tomcat 上
开发环境
Eclipse 3.3.1.1
Web Tools Platform(WTP) for eclipse
Adobe Flex Builder 3
Tomcat v6.0
MySQL v5.1
集成 Flex 和 Spring
如何将 Flex 和 Spring 进行集成使 Flex 前端能够和 Java EE 后端进行通信? Flex 通过远程思路方法和实时通信技术实现异步通信Flex 通信协议主要有 3种:HttpService、WebService 和 RemoteObjectRomoteObject 协议作为 Flex 提供最快通信方式通过集成 BlazeDS利用 AMF(Action Message Format) 2进制协议使得 Flex 前端能轻松和 Java EE 后端进行数据交互它是 Flex 集成 Spring 首选通信协议
BlazeDS
BlazeDS 是 Adobe Live-Cycle Service 免费开源版本它使用 AMF 2进制协议通过 AMF 管道构建了 Flex 和 Spring 进行数据通信桥梁BlazeDS 可以实现 Flex 对 Java 对象远程BlazeDS 可以部署运行在大多数 Web 应用服务器上如 Tomcat、Websphere、JBoss 以及 Weblogic在本文中我们将 BlazeDS 部署在 Tomcat 上BlazeDS 所依赖 jar 包如清单 1 所示:
清单 1. BlazeDS 依赖 Jar 包
flex-messaging-common.jar
flex-messaging-core.jar
flex-messaging-opt.jar
flex-messaging-proxy.jar
flex-messaging-remoting.jar
backport-util-concurrent.jar
cfgatewayadapter.jar
commons-httpclient-3.0.1.jar
commons-codec-1.3.jar
commons-logging.jar
concurrent.jar
xalan.jar
在 web.xml 部署描述符文件中添加 HttpFlexSessionHttpFlexSession 是 BlazeDS 个监听器负责监听 Flex 远程请求
清单 2. 定义 HttpFlexSession
<listener>
<listener->flex.messaging.HttpFlexSession</listener->
</listener>
SBI 和 Spring
现在我们需要引入 Spring BlazeDS Integration(SBI)SBI 项目是 SpringSource 发布开源项目
它是目前比较成熟用于集成 Flex 和 Spring 思路方法SBI 和 Spring 所依赖 Jar 包如清单 3 所示:
清单 3. SBI 和 Spring 依赖 Jar 包
org.springframework.flex-1.0.0.M2.jar(SBI)
spring-beans.jar
spring-context.jar
spring-context-support.jar
spring-core.jar
spring-tx.jar
spring-webmvc.jar
spring.jar
MessageBroker 是 SBI 个组件它职责是处理 Flex 远程请求MessageBroker 由 Spring 容器进行管理而不是由 BlazeDS在 Web.xml 中添加 DispatcherServlet 允许 Spring 自行管理 MessageBroker
清单 4. DispatcherServlet 配置
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet->
org.springframework.web.servlet.DispatcherServlet
</servlet->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
接下来需要在 BlazeDS 主配置文件 services-config.xml 中添加个管道定义以支持 DispatcherServlet 对 Flex 请求映射
清单 5. 在 services-config.xml 中定义管道
<channel-definition id="my-amf" ="mx.messaging.channels.AMFChannel">
<endpo url=
"http://{server.name}:{server.port}/{context.root}
/spring/messagebroker/amf"
="flex.messaging.endpos.AMFEndpo"/>
</channel-definition>
在 Spring 配置文件 applicationContext.xml 中引入 HandlerMapping 通过 MessageBrokerHandlerAdapter 将所有 Servlet 请求 URL 映射到由 Spring 容器管理 MessageBroker
因此需要定义如下两个 Bean:
清单 6. 定义 HandlerMapping 实现 Servlet 请求映射
<bean ="org.springframework.web.servlet.
handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*=springManagedMessageBroker
</value>
</property>
</bean>
<bean ="org.springframework.flex.messaging.servlet.
MessageBrokerHandlerAdapter"/>
最后将定义 MessageBrokerFactoryBean 工厂 Bean 用于创建 MessageBroker并为您 Service Bean 提供绑定服务
清单 7. 定义 MessageBrokerFactoryBean
<bean id="springManagedMessageBroker"
="org.springframework.flex.
messaging.MessageBrokerFactoryBean" />
在完成上述配置后启动 Tomcat 将发布 demo_central然后在浏览器中输入 http://localhost:8080/demo_central/spring/messagebroker/amf 并回车浏览器就会显示个空白 Web 页面这时我们就成功地对 Flex 和 Spring 进行了集成
集成 Spring 和 Hibernate
通过集成 Spring 和 Hibernate 3您能在 Spring 容器管理下通过 O/R Mapping 进行面向对象数据持久化在本文中我们使用 MySQL 数据库Hibernate 所需要 Jar 包如清单 8 所示:
清单 8. Hibernate 依赖 Jar 包
hibernate3.jar
hibernate-annotations.jar
hibernate-commons-annotations.jar
mysql-connector-java-5.0.8-bin.jar
首先定义 Hibernate.properties 创建 Hibernate 参数设置以及数据库连接信息
清单 9. Hibernate.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/pet_store
jdbc.username=username
jdbc.password=password
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.transaction.factory_=
org.hibernate.transaction.JDBCTransactionFactory
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
创建 HibernateContext.xml 配置文件对 Hibernate 进行配置并将其纳入 Spring 容器管理在这里我们使用基于 Java 5 注解 Hibernate 注解(Hibernate Annotations)实现对关系型数据库映射以代替传统 hbm.xml 映射文件这样不仅可以大大简化 Hibernate 映射配置而且利用 Java 元数据可以提高性能声明 SessionFactory 为 AnnotationSessionFactoryBean 将注解应用于 Hibernate 实体类中声明 RequiredAnnotationBeanPostProcessor 作为 BeanPostProcessor 实现它将强制 Bean 声明那些被 Spring 注解设置成 Required 属性否则将无法通过 XML 验证最后定义个类型为 HibernateTransactionManager txManager Bean并将它注入到 <tx:annotation-driven> transaction-manager 属性这样就能够在 Spring Bean 中应用 Hibernate 事务注解了HibernateContext.xml 如清单 10 所示:
清单 10. HibernateContext.xml
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
default-lazy-init="true">
<bean id="propertyConfigurer"
="org.springframework.beans.factory.
config.PropertyPlaceholderConfigurer">
<property name="location">
<value>
WEB-INF/hibernate.properties
</value>
</property>
</bean>
<bean id="sessionFactory"
="org.springframework.orm.hibernate3.
annotation.AnnotationSessionFactoryBean">
<property name="annotatedClasses">
<list>
<value>com.psdemo.core.do.Client</value>
<value>com.psdemo.core.do.Product</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">
${hibernate.show_sql}
</prop>
<prop key="hibernate.format_sql">
${hibernate.format_sql}
</prop>
......
<prop key="hibernate.connection.driver_">
${jdbc.driverClassName}
</prop>
<prop key="hibernate.connection.url">
${jdbc.url}
</prop>
<prop key="hibernate.connection.username">
${jdbc.username}
</prop>
<prop key="hibernate.connection.password">
${jdbc.password}
</prop>
</props>
</property>
</bean>
<bean ="org.springframework.beans.factory.
annotation.RequiredAnnotationBeanPostProcessor"/>
<bean id="txManager"
="org.springframework.orm.
hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
清单 11. Hiberante 实体类 Client.java
package com.psdemo.core.do;
import java.io.Serializable;
import javax.persistence.*;
@Entity
@Table(name="client")
public Client implements Serializable{
private final long serialVersionUID = 2L;
@Id
@Column(name="username")
private String username;
@Column(name="password")
private String password;
public String getUsername{
username;
}
public void Username(String username){
this.username = username;
}
public String getPassword{
password;
}
public void Password(String password){
this.password = password;
}
}
最后我们需要在 web.xml 部署描述符 contextConfigLocation 参数中装入 HibernateContext.xml 配置文件这时我们就成功完成了 Spring 和 Hibernate 集成通过 Spring 容器管理 HibernateHibernate 实现数据持久化管理
Java EE 服务器端
通过 Spring 对 Flex 以及 Hibernate 集成现在我们就可以在服务器端声明和定义业务逻辑对象和数据访问对象了
在 hibernateContext.xml 定义数据访问对象 DAO注入 SessionFactory
清单 12. 在 hibernateContext 定义 DAO
<bean id="clientDao"
="com.psdemo.core.dao.hibernate.ClientDaoImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
清单 13. ClientDaoImpl.java
public ClientDaoImpl extends HibernateDaoSupport
implements ClientDao {
@Override
public Client authenticateUser(String userName,
String password){
String paramNames = String{"userName", "password"};
String values = String{userName, password};
List results = this.getHibernateTemplate.
findByNamedParam("from Client as c
where c.username=:userName
and c.password=:password",
paramNames, values);
Iterator iter = results.iterator;
(iter.hasNext){
(Client)iter.next;
}{
null;
}
}
}
在 applicationContext.xml 中定义 Service 并开放其 BlazeDS 远程服务注入 DAO
清单 14. 定义 Service 并开放其 Flex 远程服务
<bean id="clientservice"
="org.springframework.flex.messaging.
remoting.FlexRemotingServiceExporter">
<property name="messageBroker"
ref="springManagedMessageBroker"/>
<property name="service" ref="clientService"/>
</bean>
<bean id="clientService"
="com.psdemo.core.services.ClientServiceImpl">
<property name="clientDao">
<ref bean="clientDao"/>
</property>
</bean>
Flex 客户端
Cairngorm
Cairngorm 是 Adobe 设计个针对 Flex 开发者构建 RIA 应用轻量级开源框架Cairngorm 通过设计模式实现了 MVC(Model-View-Controller)微型架构使得开发人员可以交付具有可重用性、可维护性中大型 RIA 应用在本文中我们使用 Cairngorm2.2.1为了引入 Cairngorm需要把它库文件 Cairngorm.swc 拷贝到 Flex 项目 libs 目录中
图 1. 将 cairngorm.swc 添加到 Flex 项目库
Cairngorm 是个事件驱动框架其编程模型主要由以下几个组件构成:
值对象(Value Object):值对象是个映射 Spring 实体类对象 ActionScript 类对象它将从 Server 端传输数据提供给可视化视图对象
清单 15. 值对象 ClientVO.as
package com.psdemo.client.model.vo
{
[Bindable]
[RemoteClass(alias="com.psdemo.core.do.Client")]
public ClientVO
{
public var username:String;
public var password:String;
}
}
前端控制器(Front Controller):前端控制器负责绑定由用户触发事件并将事件映射到相应命令
清单 16. 前端控制器 PMainController.as
public PMainController extends FrontController
{
public function PController
{
addCommand(AuthenticateUserEvent.EVENT_AUTH_USER,
AuthenticateUserCommand);
addCommand(GetProductsEvent.EVENT_GET_PRODUCTS,
GetProductsCommand);
}
}
业务代理(Business delegate):利用 Responder 处理由服务器端返回数据
清单 17. 业务代理 ClientDelegate.as
public ClientDelegate
{
private var responder:IResponder;
private var service:Object;
public function ClientDelegate(responder:IResponder)
{
this.service = ServiceLocator.getInstance.
getService("clientservice");
this.responder = responder;
}
public function authenticateUser(userName:String, password:String)
{
var call:AsyncToken = service.authenticateUser(userName, password);
call.addResponder(responder);
}
public function addClient(clientVO:ClientVO):void
{
var call:AsyncToken = service.addClient(clientVO);
call.addResponder(responder);
}
}
最新评论