您的位置:首页 > 编程语言 > Java开发

struts2.2.1+spring 3.0.3+hibernate3.6+dwr3.0全注解整合详解

2011-08-25 11:40 561 查看
今天搭建了一个ssh+dwr框架,其实ssh框架配置和以前差不多,主要是使用了注解实现C和M层,下面就是web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>nwr-web</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext*.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<filter>
<filter-name>struts-prepare</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.essential.action</param-value>
</init-param>
</filter>
<filter>
<filter-name>struts-execute</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
</filter>
<servlet>
<servlet-name>dwr</servlet-name>
<servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<filter-mapping>
<filter-name>struts-prepare</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts-execute</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>News.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>402</error-code>
<location>/error.jsp</location>
</error-page>
</web-app>

唯一需要说明一下的就是如果要使用struts2的注解就必须在配置filter的时候带上actionPackages的参数,这个参数就是设置struts2容器搜索action的包路径。

下面是struts.xml的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<package name="default" extends="struts-default">
<global-results>
<result name="error">error.jsp</result>
<result name="input">error.jsp</result>
</global-results>
</package>
<constant name="struts.convention.default.parent.package"
value="default" />
</struts>

我是用的struts.convention插件把所有action的父包都定义为我自定义的一个default包,大家也可以自定义其它父包,这样定义的父包是所有action的默认父包,当然你也可以使用@package标签为action类定义不同的包。

下面介绍spring的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dwr = "http://www.directwebremoting.org/schema/spring-dwr"
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"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"
>
<dwr:annotation-scan scanRemoteProxy="true" base-package="com.essential.dwr"/>
<dwr:annotation-scan scanDataTransferObject="true" base-package="com.essential.entity"/>
<context:component-scan base-package="com.essential" />

<bean id="configurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath*:init.properties</value>
</property>
</bean>

<bean id="mainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>

<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
<property name="minPoolSize" value="${jdbc.minPoolSize}"></property>
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"></property>
<property name="maxIdleTime" value="${jdbc.maxIdleTime}"></property>
<property name="acquireIncrement" value="${jdbc.acquireIncrement}"/>
</bean>

<bean id="dataSource"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<ref local="mainDataSource" />
</property>
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>

<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
</props>
</property>

<property name="packagesToScan" value="${hibernate.packagesToScan}" />
</bean>

<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="upd*" propagation="REQUIRED" read-only="false" />
<tx:method name="del*" propagation="REQUIRED" read-only="false" />
<tx:method name="add*" propagation="REQUIRED" read-only="false" />
<tx:method name="insert*" propagation="REQUIRED" read-only="false" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="query*" propagation="SUPPORTS" read-only="true" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="productServiceMethods"
expression="${spring.execution}" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods" />
</aop:config>

</beans>

首先前两行配置是dwr和spring整合的配置第一个是配置dwr的远程代理对象的所在的包名,第二个则是dwr里的传输对象所在的包名。

下面一行是spring搜索bean的包名。下面其他的配置和以前没什么变化。

现在来讲讲struts2的action用注解怎么实现:

1.其实注解和xml配置步骤差不多首先肯定是配置包,但是我们前面用struts.convention配置了默认包,所以也不用再配置,然后肯定是配置访问的虚拟路劲咯,也就是配置namespace,使用@Namespace(value = "/mail")标签配置,value属性是配置namespace的路径。

2.配置好了namespace然后就是action咯,配置这个是使用@Action(value = "sendMail", results = { @Result(name = SUCCESS, type = "redirect", location = "../News.jsp") })标签,其中value是配置action的路径,results是配置action的处理结果跳转页面,也可以配置多个页面。

这样就配置好了一个完整的action咯,我们现在要和spring整合就必须调用spring的bean,要调用bean很简单定义一个私有变量,然后在变量上使用@resource标签就行了,但是需要注意的是这里的变量名必须和后面要讲到的@service标签中的名字要一致才行,不然注入不进来。

下面附上一个例子:

public class ActivityAction extends BaseAction {

/**
*
*/
private static final long serialVersionUID = 5488332603981342055L;

private long uid;

private long eventId;

private ActivityService activityService;

/**
* 查询活动列表
*
* @return
* @throws Exception
*/
@Action(value = "findActivityList")
public String findActivityList() throws Exception {
List<ActivityVo> activityVos = activityService.findActivityList();
String result = ListToJsonString(activityVos);
toWrite(result);
return null;
}

/**
* 参加活动
*
* @return
* @throws Exception
*/
@Action(value = "joinActivity")
public String joinActivity() throws Exception {
boolean isSucc = activityService.insertActivityForUser(eventId, uid);
toWrite(isSucc + "");
return null;
}

/**
* 根据用户标识查找活动列表
*
* @return 我的活动列表
* @throws Exception
*/
@Action(value = "findMyActivityList")
public String findMyActivityList() throws Exception {
List<ActivityVo> activityVos = activityService.findMyActivityList(uid);
String result = ListToJsonString(activityVos);
toWrite(result);
return null;
}

@Resource
public void setActivityService(ActivityService activityService) {
this.activityService = activityService;
}

public void setUid(long uid) {
this.uid = uid;
}

public void setEventId(long eventId) {
this.eventId = eventId;
}

}

然后来讲讲service的配置,配置方法是使用@service(value="serviceName")标签设置service,很简单不用多讲,而且调用dao的时候和action调用service一样使用@resource标签引入属性就行了,下面是例子源码:

@Service(value = "activityService")
public class ActivityServiceImpl implements ActivityService {

@Resource
ActivityDao activityDao;

private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

@Override
public boolean insertActivityForUser(long eventId, long uid) {
return activityDao.insertActivityForUser(eventId, uid);
}

@Override
public List<ActivityVo> findActivityList() {
List<Activity> list = activityDao.findActivityList();
List<ActivityVo> activityVos = new ArrayList<ActivityVo>();
for (Activity activity : list) {
ActivityVo activityVo = new ActivityVo();
activityVo.setId(activity.getId());
activityVo.setTitle(activity.getTitle());
activityVo.setPublishTime(df.format(activity.getPublishTime()));
activityVo.setImagurl(activity.getImagurl());
activityVo.setContent(activity.getContent());
activityVos.add(activityVo);
}
return activityVos;
}

@Override
public List<ActivityVo> findMyActivityList(long uid) {
List<Activity> list = activityDao.findMyActivityList(uid);
List<ActivityVo> activityVos = new ArrayList<ActivityVo>();
for (Activity activity : list) {
ActivityVo activityVo = new ActivityVo();
activityVo.setId(activity.getId());
activityVo.setTitle(activity.getTitle());
activityVo.setPublishTime(df.format(activity.getPublishTime()));
activityVo.setImagurl(activity.getImagurl());
activityVo.setDatetime(activity.getDatetime());
activityVo.setDescription(activity.getDescription());
activityVo.setContent(activity.getContent());
activityVos.add(activityVo);
}
return activityVos;
}
}

然后就是dao的配置和前面的差不多就是定义dao的时候是用@repository标签,直接贴代码就行了:

@Repository(value = "activityDao")
public class ActivityDao extends BaseDao<Activity> {

/**
* 参加活动
*
* @param eventId
*            活动ID
* @param uid
*            用户ID
* @return 成功返回true,失败返回false
*/
@SuppressWarnings("unchecked")
public boolean insertActivityForUser(long eventId, long uid) {
Session session = getSession();
Query query = session
.createSQLQuery("select au.aid from activity_users au where au.aid=:aid and au.uid=:uid");
List list = query.setParameter("uid", uid).setParameter("aid", eventId)
.list();
if (list.size() > 0) {
return false;
} else {
session.createSQLQuery(
"insert into activity_users(aid,uid) values(:aid,:uid)")
.setParameter("uid", uid).setParameter("aid", eventId)
.executeUpdate();
return true;
}
}

/**
* 查询活动列表
*
* @return 活动列表
*/
@SuppressWarnings("unchecked")
public List<Activity> findActivityList() {
Session session = getSession();
List<Activity> list = session.createQuery(
"from Activity where status = 2 order by publishTime desc")
.setMaxResults(10).list();
return list;
}

/**
* 根据用户标识查询用户参加的所有活动
*
* @param uid
*            用户标识
* @return 活动列表
*/
@SuppressWarnings("unchecked")
public List<Activity> findMyActivityList(final long uid) {
return getHibernateTemplate().execute(new HibernateCallback() {

@Override
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
List<Activity> list = session
.createQuery(
"select a from Activity a left join a.users u where u.id=:uid order by a.publishTime desc")
.setParameter("uid", uid).list();
return list;
}
});
}

}

下面是BaseDao的代码:

public class BaseDao<E> extends HibernateDaoSupport {

@Resource(name = "sessionFactory")
public void setInjectionSessionFacotry(SessionFactory sessionFacotry) {
super.setSessionFactory(sessionFacotry);
}

@PostConstruct
public void injectSessionFactory() {
logger.info(super.getSessionFactory());
}

public Serializable save(E entity) {
return getHibernateTemplate().save(entity);
}

public void update(E entity) {
getHibernateTemplate().update(entity);
}

public void delete(E entity) {
getHibernateTemplate().delete(entity);
}

public User query(long id) {
return getHibernateTemplate().get(User.class, id);
}

}

在这个类里面注入sessionFactory对象。

下面来讲讲dwr的配置,要配置dwr的远程代理对象在类上使用@RemoteProxy类中的方法@RemoteMethod这样在javascript中直接用类名+方法名直接调用就行了。如果要调用spring的bean和上面一样,就不不多说。如果dwr和jsp页面传输的时候需要用到java实体那么就在需要传输的实体类上用@DataTransferObject标签,才能正确转换类型,不然会报异常。下面是例子:

@RemoteProxy
public class TestDwr implements Serializable {

/**
*
*/
private static final long serialVersionUID = -2060851629180328131L;

@RemoteMethod
public String testDwr() {
return "测试.";
}
}

实体的例子大家可以随便定义一个类就行了加上标签就OK,这里就不列出来了。

下面是jsp使用dwr必须引入3个jsp:

<script type="text/javascript" src="<%=path %>/dwr/engine.js"></script>
<script type="text/javascript" src="<%=path %>/dwr/util.js"></script>
<script type="text/javascript" src="<%=path %>/dwr/interface/TestDwr .js"></script>

前面2个是dwr必须要使用的2个js包,后面一个就是你在java中定义的类.这样就可以调用里面的方法了。

到这里全部讲完了,有什么不足的地方还请各位多补充。

所有jar包已经上传,需要的可以去下载http://download.csdn.net/detail/yaoyeyzq/4516689
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: