附录(收藏文章出处):
http://wenku.baidu.com/view/ed5fc7bbfd0a79563c1e7299.html
使用MyEclipse集成SSH和DWR
金庸Ematrix http://blog.csdn.net/ematrix001
使用 MyEclipse 集成 SSH 和 DWR
开发环境: JDK 1.5 Tomcat 6.0 Spring 2.5 Struts 1.3 Hibernate 3.2 DWR 2.0 MyEclipse 6.5 SQL Server 2005
使用 MyEclipse 集成 SSH 和 DWR
一、整合Spring和Struts
Spring和Struts整合的价值在于将Struts使用的BO或DAO 乃至Action交给Spring管理,从而充分利用 Spring强大的IoC和AOP 特性。
无论使用哪种方式整合,都需要为 Struts装载 Spring 应用上下文环境。有以下三种方式:
1) 在struts-config.xml中使用Struts Plugin
2) 在web.xml中使用ContextLoaderListener
3) 在web.xml中使用ContextLoaderServlet
注意: 用Struts PlugIn的方式加载Spring配置文件有可能导致DWR无法取得Spring中定义的bean,因为DWR有可能先于Struts被访问使用,而此时Struts配置文件还未加载! 因此,在Spring、Struts和DWR 集成时,应该在web.xml中通过ContextLoaderLisenter或ContextLoaderServlet加载Spring配置文件。 最佳实践是使用Struts PlugIn的方式加载Struts Action配置文件/WEB-INF/action-servlet.xml,而使用ContextLoaderLisenter或ContextLoaderServlet方式加载Spring配置文件applicationContext.xml,通过两次加载完成Spring所有配置文件的加载。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>SpringContextServlet</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property
property="contextConfigLocation" value="/WEB-INF/classes/applicationContext.xml,/WEB-INF/action-servlet.xml"/>
</plug-in>
使用 MyEclipse 集成 SSH 和 DWR
至少有四种Spring与Struts整合方式:
1. 手工创建Spring 环境整合 Spring和Struts
为了Web应用环境可以和Spring的IoC容器很好的结合,Spring提供了专门用于Web应用环境中的 Spring容器——WebApplicationContext。使用ContextLoaderPlugIn装载 Spring 应用程序环境时,ContextLoaderPlugIn会自动创建一个WebApplicationContext对象,并加载相应的配置文件,然后将其保存在ServletContext中。之后所有的Servlet或Action便都可以通过ServletContext访问该WebApplicationContext实例并从中获取BO或DAO Bean。
2. 使用 Spring 的 ActionSupport 类整合 Struts
org.springframework.web.struts.ActionSupport 类提供了一个 getWebApplicationContext() 方法可以获取到WebApplicationContext实例,您所做的只是从 Spring 的 ActionSupport 而不是 Struts Action 类扩展您的动作:
结论:第1、2种整合方式由Spring来管理BO或DAO Bean,实现了表示层和业务逻辑层的解耦,但Struts的Action和Spring耦合在了一起,违反了Spring“非侵入”性原则;另外,Action类负责查找由Spring管理的Bean,也违背了Spring控制反转(IoC)的原则。以下第3、4种整合方式实现了由Spring来管理Struts Action,实现了Struts和Spring的解耦,从而解决了以上问题。
3. 使用 Spring 的 DelegatingRequestProcessor 覆盖 Struts 的 RequestProcessor
用Spring的DelegatingRequestProcessor重载Struts 默认的 RequestProcessor。这样当收到一个针对Action的请求时,DelegatingRequestProcessor会自动从Spring Context中查找对应的Action Bean。 在struts-config.xml中添加:
<controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/>
public class AddActionSupport extends ActionSupport {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
AddForm addForm = (AddForm) form;
UserInfo user=new UserInfo();
user.setUserName(addForm.getName());
user.setUserPwd(addForm.getPassword());
UserInfoDAO userInfoDAO=
(UserInfoDAO)getWebApplicationContext().getBean("userInfoDAO");
userInfoDAO.save(user);
return mapping.findForward("success");
}
}
ServletContext servletContext=this.getServlet().getServletContext();
WebApplicationContext ctx=
WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserInfoDAO userInfoDAO=(UserInfoDAO)ctx.getBean("userInfoDAO");
使用 MyEclipse 集成 SSH 和 DWR
4. 【最佳方案】使用DelegatingActionProxy将Struts Action 管理全权委托给 Spring 框架
Action 的创建和对象的依赖注入全部由IOC容器来完成,使用Spring的DelegatingAcionProxy来帮助 实现代理的工作。DelegatingActiongProxy继承于org.apache.struts.action.Action 。此时需要将struts-config.xml中所有Action类别全部配置为 org.springframework.web.struts.DelegatingActionProxy:
3、4两种方式都需要在WEB-INF下新建一个action-servlet.xml作为Spring context文件,创建Struts Action Bean,并对Action进行BO或DAO Bean注入:
结论: 以上2种方式实现了由Spring管理Struts的Action,从而可以利用Spring在Struts Action中轻松的注入BO或DAO,还可以将 Spring 的 AOP 拦截器应用于Struts 动作,用最小的代价处理横切关注点。 第3种整合方式只需要配置一个<controller>,不需要改动Struts Action配置信息,但Struts的 RequestProcessor只能被重载一次,如果在应用中还要进行编码等其它功能RequestProcessor重载时,此种方式将异常繁琐。 第4种整合方式可以避免RequestProcessor的占用,但必须将struts-config.xml中所有Action类别全部配置为 org.springframework.web.struts.DelegatingActionProxy。
<action
attribute="loginForm"
input="/login.jsp"
name="loginForm"
path="/login"
scope="request"
type="org.springframework.web.struts.DelegatingActionProxy">
<forward name="error" path="/error.html" />
<forward name="success" path="/success.html" />
</action>
<!--name 的取值一定要和Struts 配置文件action 中的path 的值相对应-->
<bean name="/login" class="cn.qdqn.ssh.struts.action.LoginAction">
<property name="userBO">
<ref bean="userBO"/>
</property>
</bean>
使用 MyEclipse 集成 SSH 和 DWR
二、整合Spring与Hibernate
Spring整合Hibernate的价值在于Spring为Hibernate增加了以下内容:
Session management:Spring为Hibernate的session提供了有效、容易和安全的控制
Resource management:Spring控制Hibernate的SessionFactories,JDBC datasources及其它相关资源
Integrated transaction management:完整的事务管理
Exception wrapping:异常的包装
1. 利用Spring IoC容器创建SessionFactory
可以使用org.springframework.orm.hibernate3.LocalSessionFactoryBean创建SessionFactory实例,共 有以下二种方式:
1) 【最佳方案】直接使用Hibernate配置文件hibernate.cfg.xml
Hibernate配置文件hibernate.cfg.xml如下:
Spring配置文件中SessionFactory初始化配置方法:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="myeclipse.connection.profile">
com.microsoft.sqlserver.jdbc.SQLServerDriver
</property>
<property name="connection.url">
jdbc:sqlserver://localhost:1433;databaseName=SSH
</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="connection.driver_class">
com.microsoft.sqlserver.jdbc.SQLServerDriver
</property>
<property name="dialect">
org.hibernate.dialect.SQLServerDialect
</property>
<mapping resource="cn/qdqn/ssh/entity/UserInfo.hbm.xml" />
</session-factory>
</hibernate-configuration>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="classpath:hibernate.cfg.xml">
</property>
</bean>
使用 MyEclipse 集成 SSH 和 DWR
2) 在Spring配置文件中整合所有Hibernate配置参数
注意:使用MyEclipse集成SSH时,org.apache.commons.dbcp.BasicDataSource所在的包commons-dbcp-1.2.2.jar不会默认加载,另外还需加载commons-pool-1.4.jar,两者均可在Apache网站commons项目下找到。否则运行程序会出现以下异常:
java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getDeclaredConstructor(Unknown Source)
……
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"
value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url"
value="jdbc:sqlserver://localhost:1433;databaseName=SSH"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource">
</property>
<property name="mappingResources">
<list>
<value>cn/qdqn/ssh/entity/UserInfo.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.SQLServerDialect
</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
使用 MyEclipse 集成 SSH 和 DWR
2. DAO开发
1) 使用Hibernate原生API实现DAO
A. 使用原生API实现DAO
B. 在applicationContext.xml配置原生DAO Bean
C. 运行测试
结论:使用Hibernate原生API实现DAO可以做到Hibernate和Spring完全分离,缺点是无法利用Spring封装Hibernate所提供的额外功能。
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDAORaw dao=(UserInfoDAORaw)ctx.getBean("userInfoDAORaw");
List<UserInfo> list=dao.findAll();
for(UserInfo info : list){
System.out.println(info.getUserName()+"-"+info.getUserPwd());
}
<bean id="userInfoDAORaw" class="cn.qdqn.ssh.dao.UserInfoDAORaw">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
public class UserInfoDAORaw implements IUserInfoDAO {
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public List findAll() {
return this.sessionFactory.getCurrentSession()
.createQuery("from UserInfo").list();
}
部分代码省略„„
}
使用 MyEclipse 集成 SSH 和 DWR
2) 【最佳方案】使用Spring框架所提供的HibernateDaoSupport类实现DAO
A. 使用MyEclipse反向工程生成Spring 整合Hibernate 的DAO,该DAO继承自Spring的org.springframework.orm.hibernate3.support.HibernateDaoSupport
B. 在applicationContext.xml配置DAO Bean
C. 运行测试
注意:HibernateDaoSupport通过getHibernateTemplate()方法得到HibernateTemplate实例进行保存、删除等操作,但是HibernateTemplate默认不进行事务处理,而在Hibernate中这些操作必须在事务下执行才能得到正确的结果,因此必须使用Spring声明式事务管理。
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDAORaw dao=(UserInfoDAORaw)ctx.getBean("userInfoDAO");
List<UserInfo> list=dao.findAll();
for(UserInfo info : list){
System.out.println(info.getUserName()+"-"+info.getUserPwd());
}
<bean id="userInfoDAO" class="cn.qdqn.ssh.dao.UserInfoDAO">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
public class UserInfoDAO extends HibernateDaoSupport {
private static final Log log = LogFactory.getLog(UserInfoDAO.class);
// property constants
public static final String USER_NAME = "userName";
public static final String USER_PWD = "userPwd";
public void save(UserInfo transientInstance) {
log.debug("saving UserInfo instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}
部分代码省略„„
}
使用 MyEclipse 集成 SSH 和 DWR
3. 使用Spring声明式事务管理
1) 使用Spring 1.x 的事务代理类进行事务管理
A. 在applicationContext.xml中声明事务管理器,注入sessionFactory属性
B. 在applicationContext.xml中使用Spring AOP代理方式实现声明式事务
C. 通过代理Bean获取DAO Bean,进行数据库操作
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDAO dao=(UserInfoDAO)ctx.getBean("userInfoDAOProxy");
UserInfo user=new UserInfo();
user.setUserName("比尔盖茨");
user.setUserPwd("windows");
dao.save(user);
<bean id="userInfoDAOProxy" class=
"org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--必须为true时CGLIB才不用强制编写DAO接口-->
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="target">
<ref bean="userInfoDAO"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
使用 MyEclipse 集成 SSH 和 DWR
问题1:运行程序会报以下异常:
解决方法:原因是Spring与Hibernate所使用的asm版本冲突,删除asm.2.2.3.jar即可。 问题2:对每个业务逻辑Bean或DAO Bean都要设置事务代理Bean将是一个非常庞大的工作量! 改进方法: 可以通过定义“基类”来解决重复性编码!如:
结论:采用Spring 1.x配置事务要额外配置一个代理对象,原来Bean的获取方式也要修改,因此,也是一种“侵
入式”的解决方案,虽然没有侵入到Bean程序代码中。
java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
at net.sf.cglib.core.ClassEmitter.begin_class(ClassEmitter.java:77)
at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:173)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:117)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108)
at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104)
at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69)
„„„„
<bean id="baseDAOProxy" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="userInfoDAOProxy" parent="baseDAOProxy">
<property name="target">
<ref bean="userInfoDAO"/>
</property>
</bean>
使用 MyEclipse 集成 SSH 和 DWR
2) 使用Spring 2.x 的aop 和tx 声明式配置进行事务管理
A. 在applicationContext.xml中添加aop和tx名称空间
B. 在applicationContext.xml中声明事务管理器,注入sessionFactory属性
C. 通过<tx:advice>定义事务通知
D. 将事务通知advice和切面pointcut组合起来
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<aop:config>
<aop:pointcut id="daoMethods"
expression="execution(* cn.qdqn.ssh.dao.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="do*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/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">
„„„„
</beans>
使用 MyEclipse 集成 SSH 和 DWR
E. 两种应用测试:
a) 对于Java Application,直接获取DAO Bean,进行数据库操作
问题:运行程序会报以下异常
解决方法:此时唯有JDK 基于接口的代理将起作用,因此每个BO或DAO类必须要有对应的Interface,可以使用MyEclipse的重构功能生成BO或DAO类的接口定义,将获取的BO或DAO Bean放在相应接口对象的引用中即可。代码修改如下:
b) 对于Web Application,在Struts Action定义BO或DAO,通过Spring在action-servlet.xml中
进行注入
Exception in thread "main" java.lang.ClassCastException: $Proxy1
at cn.qdqn.ssh.test.AddUserInfo.main(AddUserInfo.java:18)
<bean name="/add" class="cn.qdqn.ssh.struts.action.AddAction">
<property name="userInfoDAO">
<ref bean="userInfoDAO"/>
</property>
</bean>
public class AddAction extends Action {
private UserInfoDAO userInfoDAO;
public UserInfoDAO getUserInfoDAO() {
return userInfoDAO;
}
public void setUserInfoDAO(UserInfoDAO userInfoDAO) {
this.userInfoDAO = userInfoDAO;
}
„„„„
}
ApplicationContext ctx=
new ClassPathXmlApplicationContext("applicationContext.xml");
IUserInfoDAO dao=(IUserInfoDAO)ctx.getBean("userInfoDAO");
UserInfo user=new UserInfo();
user.setUserName("比尔盖茨");
user.setUserPwd("windows");
dao.save(user);
ApplicationContext ctx=
new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDAO dao=(UserInfoDAO)ctx.getBean("userInfoDAO");
UserInfo user=new UserInfo();
user.setUserName("比尔盖茨");
user.setUserPwd("windows");
dao.save(user);
使用 MyEclipse 集成 SSH 和 DWR
问题:启动Tomcat会报以下异常
解决方法:同Java Application所遇错误相类似,只需将Struts Action定义的等待被注入的BO或DAO替换为其相应的Interface形式即可纠正该错误。如下代码:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name '/add' defined in ServletContext resource [/WEB-INF/action-servlet.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy1] to required type [cn.qdqn.ssh.dao.UserInfoDAO] for property 'userInfoDAO'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy1] to required type [cn.qdqn.ssh.dao.UserInfoDAO] for property 'userInfoDAO': no matching editors or conversion strategy found
Caused by:
org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessException details (1) are:
PropertyAccessException 1:
org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy1] to required type [cn.qdqn.ssh.dao.UserInfoDAO] for property 'userInfoDAO'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy1] to required type [cn.qdqn.ssh.dao.UserInfoDAO] for property 'userInfoDAO': no matching editors or conversion strategy found
„„„„
public class AddAction extends Action {
private IUserInfoDAO userInfoDAO;
public IUserInfoDAO getUserInfoDAO() {
return userInfoDAO;
}
public void setUserInfoDAO(IUserInfoDAO userInfoDAO) {
this.userInfoDAO = userInfoDAO;
}
„„„„
}
使用 MyEclipse 集成 SSH 和 DWR
3) 【最佳方案】使用Spring 2.x 的@Transactional标注进行事务管理
A. 在BO或DAO类中添加事务标注@Transactional
B. 在applicationContext.xml中添加transactionManager和<tx:annotation-driven>
注意:proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。
C. 测试运行,一切正常
ApplicationContext ctx=
new ClassPathXmlApplicationContext("applicationContext.xml");
UserInfoDAO dao=(UserInfoDAO)ctx.getBean("userInfoDAOProxy");
UserInfo user=new UserInfo();
user.setUserName("比尔盖茨");
user.setUserPwd("windows");
dao.save(user);
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true"/>
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class UserInfoDAO extends HibernateDaoSupport {
private static final Log log = LogFactory.getLog(UserInfoDAO.class);
public static final String USER_NAME = "userName";
public static final String USER_PWD = "userPwd";
public void save(UserInfo transientInstance) {
log.debug("saving UserInfo instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
}
}
部分代码省略„„
}
使用 MyEclipse 集成 SSH 和 DWR2.0
三、整合Spring与DWR(可以参考附件那个url):
下面的s1shstudy项目中 DWR2.0与javaBean和spring交互的例子。
Spring与DWR整合的价值在于DWR使用的BO全部交给Spring管理,从而充分利用Spring强大的IoC和AOP 特性。
1. 添加dwr.jar到WEB-INF/lib下,并在web.xml中添加对DWR的加载代码
2. 改WEB-INF/web.xml,需要:
//读取spring配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
//dwr 处理servlet
<!-- 添加DWRServlet的映射 -->
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param> //这个参数为dwr2.0必须
<param-name>classes</param-name>
<param-value>java.lang.Object</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
3. 在WEB-INF下添加dwr.xml配置文件,用来配置所需要暴露在前端页面的业务逻辑类
(参考http://fangang.javaeye.com/blog/119767)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<!-- 与javaBean通信 -->
<create creator="new" javascript="service">
<param name="class" value="cn.jiabeis.s1shstudy.service.DwrAjaxService"/>
</create>
<!-- 生成javascript对象 -->
<convert converter="hibernate3" javascript="Student" match="cn.jiabeis.s1shstudy.model.Student" />
<!-- 与spring通信 -->
<create creator="spring" javascript="studentService">
<param name="beanName" value="studentService"/>
</create>
</allow>
</dwr>
4. 在前端页面中使用DWR
(1)testDwr.jsp:与javaBean交互。
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<script type="text/javascript" src="dwr/interface/service.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
//默认为异步,如果改为同步,可以调用:dwr.engine.setAsync(false);
function sayHello(){
service.sayHello("张三",
function(data){
alert(data);
}
);
}
</script>
</head>
<body>
<a href="#" οnclick="sayHello()">Test1</a>
</body>
</html>
(1)/student/studentQuery.jsp:与spring交互。
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html>
<head>
<title>Insert title here</title>
<script type="text/javascript" src="/s1shstudy/dwr/engine.js"></script>//注意这里src的路径为绝对路径,如果用相对路径与页面位置有关。
<script type="text/javascript" src="/s1shstudy/dwr/util.js"></script>
<script type="text/javascript" src="/s1shstudy/dwr/interface/studentService.js"></script>
<script type="text/javascript">
//默认为异步,如果改为同步,可以调用:dwr.engine.setAsync(false);
function callBack(data){
if(data){
var student = new Student()
var student = data;
alert(student.stuId+":"+student.stuName+":"+student.stuGender+":"+student.stuAge);
}else{
alert("不存在!");
}
}
function getAllStuAbout(){
var stuId= document.getElementsByName("stuId")[0].value;
alert("before");
studentService.getStudentsById(stuId, callBack);
alert("after");
}
</script>
</head>
<body>
<html:form action="/studentQuery">
鼠标移动实现异步查询:
<br>
stuId : <html:text property="stuId" οnblur="getAllStuAbout()" />
<html:errors property="stuId" />
<br/>
</html:form>
</body>
</html>