当前位置: 代码迷 >> Web前端 >> spring hiberbate blazeDs 调整java
  详细解决方案

spring hiberbate blazeDs 调整java

热度:497   发布时间:2012-09-10 22:20:13.0
spring hiberbate blazeDs 整合java

1.服务器我打算使用预装了BlazeDS的Turn Key Server。

下载BlazeDS的Turnkey Server。

2.安装配置Spring。

?参http://coenraets.org/flex-spring/文章,首先下载Flex-Spring.zip文件,将Java文件展开到BlazeDS的Samples的Src目录下。

然后下载最新的Spring的包spring.jar,复制到Samples的WEB-INF的lib目录下。

接下来编辑Samples的Web.xml文件,添加Spring的配置项目

???
??? <!-- Spring configuration file (Not needed if you don't use Spring) -->
??? <context-param>
??????? <param-name>contextConfigLocation</param-name>
??????? <param-value>/WEB-INF/applicationContext.xml</param-value>
??? </context-param>

???? <!-- Spring ContextLoaderListener (Not needed if you don't use Spring) -->
??? <listener>
??????? <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
??? </listener>
?

为了让Flex-Remoting能够将Spring的Bean正确传给Flex客户端,我们需要配置基于Spring的Factory。

编辑{Samples}\WEB-INF\flex\services-config.xml文件,添加

???
?????? <!-- Spring factory: not needed if you don't use Spring) -->
??? <factories>
??????? <factory id="spring" class="flex.samples.factories.SpringFactory"/>
??? </factories>
? 为了使用springfactory,需要将预编译好的flex-spring-factory.jar添加到web-inf的lib目录下

前面下载的Flex-spring.zip包中带了两个Spring的例子程序,为了让Spring能够正确地组装例子对应的Spring Bean,我们需要在WEB-INF目录下创建applicationContext.xml

<beans>

??? <bean id="rateFinderBean" class="flex.samples.spring.mortgage.SimpleRateFinder"/>

??? <bean id="mortgageBean" class="flex.samples.spring.mortgage.Mortgage">
????????? <property name="rateFinder" ref="rateFinderBean"/>
??? </bean>
???
??? <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
??????? <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
??????? <property name="url" value="jdbc:hsqldb:hsql://localhost:9002/flexdemodb"/>
??????? <property name="username" value="sa"/>
??????? <property name="password" value=""/>
??? </bean>

??? <bean id="productDAOBean" class="flex.samples.spring.store.SimpleProductDAO">
??????? <property name="dataSource" ref="dataSource"/>
??? </bean>
???

</beans>

?接下来我们要公开这些Spring Bean的接口给Flex的客户端,编辑Remoting-Config.xml文件

???
??? <destination id="mortgageService">
??????? <properties>
??????????? <factory>spring</factory>
??????????? <source>mortgageBean</source>
??????? </properties>
??? </destination>

??? <destination id="productService">
??????? <properties>
??????????? <factory>spring</factory>
??????????? <source>productDAOBean</source>
??????? </properties>
??? </destination>
?

?接下来,创建一个Flex应用,指定服务器的路径为http://localhost:8400/samples,创建下面的客户端

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
??? <mx:RemoteObject id="ro" destination="mortgageService"/>
???
??? <mx:TextInput id="amount" x="113" y="10"/>
??? <mx:Button label="Calculate" click="ro.calculate(Number(amount.text))" x="155" y="40"/>
??? <mx:TextInput id="monthlyPayment" text="{ro.calculate.lastResult}" x="113" y="70"/>???
</mx:Application>

运行后即可。

基于ProductDAO的Spring例子类似上面的例子,要注意的是在运行前确保执行了SampleDB下的StartDB命令运行了HSQL的例子数据库。

3.安装配置Hibernate

安装配置Hibernate,主要是参考了http://www.adobe.com/devnet/flex/articles/flex_hibernate.html这篇文章。

首先,安装Mysql,然后创建consultant_db,用户名,密码指定为root,root。

然后下载Hibernate的包

Hibernate Core 3.3.1
Hibernate Annotations 3.4.0 GA
Hibernate EntityManager 3.4.0 GA
Hibernate Validator 3.1.0
将Hibernate的包全部复制到web-inf的lib下。

为了登录日志,我们使用Log4j,在Src目录下创建一个log4j.xml文件,内容如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration debug="false"
??? xmlns:log4j="http://jakarta.apache.org/log4j/">

??? <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
??????? <param name="target" value="System.out" />
??????? <layout class="org.apache.log4j.PatternLayout">
??????????? <param name="ConversionPattern"
??????????????? value="%d{HH:mm:ss.SSS}? %-5p? %-40.70C{6} %x - %m%n" />
??????? </layout>
??? </appender>

??? <appender name="ADC_DEMO"
??????? class="org.apache.log4j.RollingFileAppender">

??????? <!-- Change the log path and file name here! -->
??????? <param name="File" value="c:/temp/logs/adc.log" />
??????? <param name="Append" value="true" />
??????? <param name="MaxFileSize" value="2MB" />
??????? <param name="MaxBackupIndex" value="8" />
??????? <layout class="org.apache.log4j.PatternLayout">
??????????? <param name="ConversionPattern"
??????????????? value="%d{HH:mm:ss.SSS}? %-5p? %-40.70C{6} %x - %m%n" />
??????? </layout>
??? </appender>

??? <appender name="LOG_APACHE"
??????? class="org.apache.log4j.RollingFileAppender">

??????? <!-- Change the log path and file name here! -->
??????? <param name="File" value="c:/temp/logs/apache.log" />
??????? <param name="Append" value="true" />
??????? <param name="MaxFileSize" value="2MB" />
??????? <param name="MaxBackupIndex" value="8" />
??????? <layout class="org.apache.log4j.PatternLayout">
??????????? <param name="ConversionPattern"
??????????????? value="%d{HH:mm:ss.SSS}? %-5p? %-40.70C{6} %x - %m%n" />
??????? </layout>
??? </appender>

??? <logger name="com.adobe" additivity="false">
??????? <level value="DEBUG" />
??????? <appender-ref ref="ADC_DEMO" />
??????? <appender-ref ref="STDOUT" />
??? </logger>

??? <!-- Hibernate -->
??? <logger name="org.hibernate">
??????? <level value="WARN" />
??? </logger>

??? <!-- Apache Commons -->
??? <logger name="org.apache.commons">
??????? <level value="INFO" />
??????? <appender-ref ref="LOG_APACHE" />
??????? <appender-ref ref="STDOUT" />
??? </logger>

??? <!-- Apache Jasper -->
??? <logger name="org.apache.jasper">
??????? <level value="INFO" />
??????? <appender-ref ref="LOG_APACHE" />
??????? <appender-ref ref="STDOUT" />
??? </logger>

??? <!-- Apache Catalina -->
??? <logger name="org.apache.catalina">
??????? <level value="INFO" />
??????? <appender-ref ref="LOG_APACHE" />
??????? <appender-ref ref="STDOUT" />
??? </logger>

??? <!-- Apache Coyote -->
??? <logger name="org.apache.coyote">
??????? <level value="INFO" />
??????? <appender-ref ref="LOG_APACHE" />
??????? <appender-ref ref="STDOUT" />
??? </logger>

??? <logger name="net">
??????? <level value="WARN" />
??????? <appender-ref ref="ADC_DEMO" />
??????? <appender-ref ref="STDOUT" />
??? </logger>

??? <!--
??????? DEFAULT: All log message are send to Appender ADC_DEMO and STDOUT.
??????? Log Level Order: DEBUG, INFO, WARN, ERROR, FATAL
??? -->
??? <root>
??????? <priority value="DEBUG" />
??????? <appender-ref ref="STDOUT" />
??????? <appender-ref ref="ADC_DEMO" />
??? </root>

</log4j:configuration>

然后创建Hibernate配置文件,在Src目录下创建META-INF目录,然后新建一个persistence.xml,内容如下

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns :x si="http://www.w3.org/2001/XMLSchema-instance"
?
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
? <persistence-unit name="consultant_db">
??? <properties>
????? <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
????? <property name="hibernate.connection.url" value="jdbc:mysql://localhost/consultant_db" />
????? <property name="hibernate.connection.username" value="root" />
????? <property name="hibernate.connection.password" value="root" />
????? <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
????? <property name="hibernate.connection.pool_size" value="6" />
????? <property name="hibernate.connection.autoReconnect" value="true" />
????? <property name="hibernate.generate_statistics" value="false" />
????? <property name="hibernate.show_sql" value="true" />
????? <property name="hibernate.use_sql_comments" value="false" />
????? <property name="hibernate.hbm2ddl.auto" value="update" />
??? </properties>
? </persistence-unit>
</persistence>

然后将例子中的consultant及其Service的Java文件及其目录结构复制到Src目录下。注意因为例子程序使用了标记,我们需要将JAVA编译器的兼容性调整为Java 5.0以上。创建好类之后,我们还要配置remoting-config.xml,公开服务器端接口

??? <!-- ADC Demo application -->
????????????????????????????????
??? <destination id="consultantService">
??????? <properties>
??????????? <source>com.adobe.demo.ConsultantService
??????????? </source>
??????? </properties>
??? </destination>

最后,创建对应的Flex客户端,直接将下载的例子代码覆盖后,运行即可。注意:我们创建Flex客户端及Java服务器端集成工程时,最好参考这篇英文文章的配置,可以很方便地实现服务器及客户端的Debug调试。

?4.基于Spring Security 2.0的安全认证

这个环境的配置主要是基于http://www.adobe.com/devnet/flex/articles/flex_security.html这篇文章。注意这篇文章的最新的程序有了一些改进,改进版本可以从http://code.google.com/p/gridshore下载。

首先编辑web.xml文件,添加过滤器定义

<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>接着在将例子中的spring-security.xml,spring-business.xml, spring-intergration.xml复制到WEB-INF目录下,并将这三个文件的引用加入到web.xml中

??? <!-- Spring configuration file (Not needed if you don't use Spring) -->
??? <context-param>
??????? <param-name>contextConfigLocation</param-name>
??????? <param-value>
????????? /WEB-INF/applicationContext.xml,
????????? /WEB-INF/spring-business.xml,
????????? /WEB-INF/spring-integration.xml,
????????? /WEB-INF/spring-security.xml
??????? </param-value>
??? </context-param>

接着将Server端的代码复制到WEB-INF的Src目录下。注意,spring用aspectj来实现aop,所以需要将aspectj的jar放到lib目录下。

接下来配置Hibernate特性,在classes目录下创建Database.properties文件,内容如下

hibernate.sql.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.sql.generateddl=true
hibernate.sql.show=true
jdbc.driverclass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/consultant_db
jdbc.username=root
jdbc.password=root

然后,在Persistent.xml中添加下面内容

? <persistence-unit name="books" transaction-type="RESOURCE_LOCAL">
????? <provider>org.hibernate.ejb.HibernatePersistence</provider>
????? <class>nl.gridshore.samples.books.domain.Book</class>
????? <class>nl.gridshore.samples.books.domain.Author</class>
????? <properties>
????????? <property name="hibernate.archive.autodetection" value="class"/>
????? </properties>
? </persistence-unit>?

?接下来,我们同样也要公开对应的Service,在Remoting-config.xml中添加下面Service

<destination id="bookManager">
? <properties>
??? <factory>spring</factory>
??? <source>bookManager</source>
? </properties>
</destination>

<destination id="authenticationHelper">
? <properties>
??? <source>nl.gridshore.samples.books.web.security.AuthenticationHelper </source>
? </properties>
</destination>最后一个需要注意的地方就是我们需要将tomcat的servlet-api.jar复制到WEB-INF的lib目录下,否则

??????? ApplicationContext appContext =?????????????? WebApplicationContextUtils.getWebApplicationContext(FlexContext.getServletConfig().getServletContext());

这句话运行时会报错。

5.一点关于Spring Security的补充

上面的例子程序使用的用户名和密码是直接定义在XML文件中的,但是实际环境中经常是需要将用户信息保存在数据库中,为此我们要修改认证Provider来使用jdbc-user-service。

编辑spring-security.xml,添加内容

??? <security:authentication-provider>
<!--??????? <security:user-service>-->
<!--??????????? <security:user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN"/>-->
<!--??????????? <security:user name="user" password="user" authorities="ROLE_USER"/>-->
<!--??????? </security:user-service>-->
??????????? <security:jdbc-user-service data-source-ref="dataSource"
????????????? users-by-username-query="SELECT U.username, U.password, U.accountEnabled AS 'enabled' FROM User U where U.username=?"
????????????? authorities-by-username-query="SELECT U.username, R.name as 'authority' FROM User U JOIN Authority A ON u.id = A.userId JOIN Role R ON R.id = A.roleId WHERE U.username=?"
??????????? />?
??? </security:authentication-provider>

?JDBC User Service对应的Schema是

create table users(
username varchar_ignorecase(50) not null primary key,
password varchar_ignorecase(50) not null,
enabled boolean not null);
create table authorities (
username varchar_ignorecase(50) not null,
authority varchar_ignorecase(50) not null,
constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);;

如果应用使用的用户名表结构不一样,可以使用自定义的SQL来转换字段名,如上文所示。

?如果我们想控制一个用户同一时刻只能有一个Session在线,可以在Web.xml中添加

<listener>
<listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
</listener>

然后将下面定义添加到Spring-security.xml中

??? <security:http auto-config="true">
??????? .....
??????? <security:concurrent-session-control max-sessions="1" />???????
??? </security:http>

注意:Flex Security那篇文章中的代码缺少设置Detail的方法调用,跟并发session控制一起使用的时候,会导致java.lang.IllegalArgumentException异常,下面是我修改后的认证方法

??? public AuthorizationData authenticatePrincipal(String username, String password) {
???????
??????? ApplicationContext appContext =
??????????????? WebApplicationContextUtils.getWebApplicationContext(FlexContext.getServletConfig().getServletContext());
??????? AuthenticationManager manager = (AuthenticationManager)appContext.getBean("_authenticationManager");
??????? UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
??????????????? new UsernamePasswordAuthenticationToken(username,password);
???????
??????? //不执行SetDetails方法的话、如果使用了concurrent-session-control定义会引发异常
??????? usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetails(FlexContext.getHttpRequest()));

??????? Authentication authentication = manager.authenticate(usernamePasswordAuthenticationToken);
??????? SecurityContextHolder.getContext().setAuthentication(authentication);

??????? return obtainGrantedAuthorities();
??? }
?

另外,例子中没有提供登录注销的功能,下面是我实现的Logout的函数

??? public void sessionLogout(){
?????????? SecurityContextHolder.getContext().setAuthentication(null);
??? }

  相关解决方案