struts2+hibernate4+spring4整合开发

前话

首先说的一点是,me 是个菜鸟;其次要说的一点是,hibernate 和 spring 这些框架可能不会向前兼容,所以很多各种书籍上说的例子,使用同样的版本就算了,使用最新的版本它可能就跑不通,当然使用的 jar 包甚至 u 发现“肿么没有” !最后的一点是,me 只是按 me 的想法跑通了一个最新版本的 struts 2.3.15 + hibernate 4.2.3 + spring 4.0.0,而且只是一个简单的 demo,所以并不涉及很高级的操作和框架详细的用法,比如事务、日志、包的依赖管理等等。me 使用的设计,也是按照 me 以前的想法(当然这种想法来自于各种书籍和以前的项目经验)来实现的,可能不是“标准的”用法。

框架介绍

Struts 2 是优秀的 MVC (Model - View - Controller)框架,所有的 request 都交给对应的 action 处理,根据处理结果再跳转到指定的 page。所谓的 url 和 aciton 的映射以及 page 的跳转和参数的传递,都是控制器干的事,而 page 则对应的是视图 view,model 对应的是数据处理。action 往往是作为控制器来说的,它调用 model 的服务(service)进行处理,当然 me 们也可以在 action 种直接处理数据,比如直接 JDBC 连接数据库。

Hibernate 是一个 ORM (object relation mapping)框架,好吧,有 map 说明这是一个映射框架。数据库中的表是二维结构,一条一条记录,每条记录对应一些字段;实际上可以看出来,如果一个字段对应一个类的属性的话,这样,一张表正好对应一个类,一条记录正好对应一个对象,very good !假设 action 中调用的 service 负责处理数据,比如 me 们希望保存一个 user 对象(注册的不是一个 user 吗?),对于程序猿来说,user.save() 要比,自己连接数据库,然后 insert into user values(...) 要好多了。Hibernate 就可以帮助 me 们这样使用。

Spring 是一个 Ioc 框架,可以帮助 me 们是进行所谓的“面向接口”编程。me 们可以在 web 容器(可以认为是 jsp 服务器)启动的时候将一些需要实例化的对象交给 spring 容器管理,比如将 service 交给 spring,me 们可以在每一个 action 中从 spring 容器中提取一个对象,然后使用 service。

设计

现在 me 们希望在一个注册页面中,点击注册,然后将 username 和 password 作为一条记录插入 user 数据表中;同时在后台查看所有的 user 数据。sturts2 的 MVC 倒不用多说,当 me 们点击注册的时候,控制转义到一个 action —— LoginAction 处理,action 调用后面的 service。User 实体类和 user_info 表建立映射关系,me 使用注解 annoation,而不是配置文件,这样对于 User 的操作自动转换为对 user_info 的操作。对于 User 的增删改查交给 UserDao 处理,DAO (data access object) 貌似叫数据访问对象,或是数据访问层,它负责对于 User 的 save、update、delete 和 find;而和业务比较近的一层写成 service,它操作 dao 来为 action 提供服务。

上代码

视图页面

下面是 login.jsp 的主要代码,虽然名字是 login 但是实际上是注册功能,O__O"…(如此名不副实 ! )。当然还得准备一个 welcome.jsp,me 就不多粘贴了。tips:action 的值对应的是 login.action,而不是通常的某个 process_login.jsp !

  1. <form action="login.action" method="POST"  >
  2. username: <input type="text" name="username"><br>
  3. password: <input type="text" name="password"><br>
  4. <input type="submit" id="register"  value="提交" >
  5. <input type="reset" id="delete"  value="取消" >
  6. </form>

User 类

下面是 User 类的主要代码,而不是全部代码,全部的包括 package 和每个属性的 getter、setter。上面的注解就是解决属性和 user_info表中字段的对应关系。

  1. import javax.persistence.Entity;
  2. import javax.persistence.Id;
  3. import javax.persistence.Table;
  4. import javax.persistence.Column;
  5.  
  6. @Table(name="user_info", catalog="test")
  7. public class User {
  8.         @Id
  9.         @Column(name="id")
  10.         private int id;
  11.        
  12.         @Column(name="username")
  13.         private String username;
  14.  
  15.         @Column(name="age")
  16.         private int age;
  17.  
  18.         @Column(name="password")
  19.         private String password;
  20.        
  21.         public User(){
  22.                
  23.         }
  24.         public User(String usr, String pwd){
  25.                 username = usr;
  26.                 password = pwd;
  27.         }
  28. }

UserDao 类

OO 的一个特点是先写接口,其次写实现类,实际上 UserDao 只是一个接口,而真正的 DAO 是 UserDaoImpl 类:

  1. import java.util.List;
  2.  
  3. public interface UserDao {
  4.        
  5.     public User save(User user);
  6.     public User delete(User user);
  7.    
  8.     public List<User> getAllUsers();
  9. }
  1. package model.impl;
  2.  
  3. import java.util.Iterator;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6.  
  7. import org.hibernate.SessionFactory;
  8. import org.hibernate.Transaction;
  9. import org.hibernate.Session;
  10. import org.hibernate.Query;
  11.  
  12. import model.User;
  13. import model.UserDao;
  14.  
  15. public class UserDaoImpl implements UserDao {
  16.     private SessionFactory sessionFactory = null;
  17.    
  18.         @Override
  19.         public User save(User user) {
  20.                 try{
  21.                         Session sess = sessionFactory.openSession();
  22.                         Transaction tx = sess.beginTransaction();
  23.                        
  24.                         sess.save(user);
  25.                         tx.commit();
  26.                        
  27.                         sess.close();
  28.                        
  29.                         return user;
  30.                 }catch(Exception e){
  31.                         e.printStackTrace();
  32.                         return null;
  33.                 }
  34.         }
  35.  
  36.         @Override
  37.         public User delete(User user) {
  38.                 try{
  39.                         Session sess = sessionFactory.openSession();
  40.                         Transaction tx = sess.beginTransaction();
  41.                         sess.delete(user);
  42.                         tx.commit();
  43.                         sess.close();
  44.                         return user;
  45.                 }catch(Exception e){
  46.                         e.printStackTrace();
  47.                         return null;
  48.                 }
  49.         }
  50.  
  51.         public SessionFactory getSessionFactory() {
  52.                 return sessionFactory;
  53.         }
  54.  
  55.         public void setSessionFactory(SessionFactory sessionFactory) {
  56.                 this.sessionFactory = sessionFactory;
  57.         }
  58.  
  59.         @Override
  60.         public List<User> getAllUsers() {
  61.             List<User> users = new LinkedList<User>();
  62.                 try{
  63.                         Session sess = sessionFactory.openSession();
  64.                         Query query = sess.createQuery("from User");
  65.  
  66.                     List<?> l = query.list();
  67.                     Iterator<?> i1 = l.iterator();
  68.  
  69.                     User user= null;
  70.                     while (i1.hasNext()) {
  71.                         user = (User)i1.next();
  72.                         // System.out.println(user.getUsername());
  73.                         users.add(user);
  74.                     }                
  75.                 }catch(Exception e){
  76.                         e.printStackTrace();
  77.                 }finally{
  78.                         ;
  79.                 }
  80.                 return users;
  81.         }
  82.  
  83. }

UserService 类

下面是 UserServiceImpl 实现类,而不是UserService 接口;

  1. package service.impl;
  2.  
  3. import java.util.List;
  4.  
  5. import model.User;
  6. import model.UserDao;
  7. import service.UserService;
  8.  
  9. public class UserServiceImpl implements UserService {
  10.     private UserDao userDao;
  11.    
  12.         @Override
  13.         public User reigsterUser(User user) {
  14.                 return userDao.save(user);
  15.         }
  16.  
  17.         @Override
  18.         public User deleteUser(User user) {
  19.                 return userDao.delete(user);
  20.         }
  21.        
  22.         @Override
  23.         public List<User> getAllUsers() {
  24.                 return userDao.getAllUsers();
  25.         }
  26.  
  27.         public UserDao getUserDao() {
  28.                 return userDao;
  29.         }
  30.  
  31.         public void setUserDao(UserDao userDao) {
  32.                 this.userDao = userDao;
  33.         }
  34.  
  35. }

LoginAction

  1. package action;
  2.  
  3. import org.apache.struts2.ServletActionContext;
  4. import com.opensymphony.xwork2.ActionSupport;
  5. import org.springframework.web.context.WebApplicationContext;
  6. import org.springframework.web.context.support.WebApplicationContextUtils;
  7.  
  8. import model.User;
  9. import service.UserService;
  10. import java.util.List;
  11.  
  12. public class LoginAction extends ActionSupport{
  13.         private static final long serialVersionUID = -7919288320923232999L;
  14.        
  15.         private String username;
  16.     private String password;
  17.    
  18.     public String execute(){
  19.         User registerUser = new User(username, password);
  20.         System.out.println("user: " + username + "\n" + "pwd: " + password);
  21.        
  22.         WebApplicationContext ctx =WebApplicationContextUtils.getRequiredWebApplicationContext(
  23.                         ServletActionContext.getServletContext()
  24.                         );
  25.        UserService server = ctx.getBean("server", service.impl.UserServiceImpl.class);
  26.        
  27.        server.reigsterUser(registerUser);       // register user
  28.        
  29.        List<User> users =server.getAllUsers();
  30.        for(User user: users){
  31.            System.out.println(user.getUsername()+" "+user.getAge() + " " +user.getPassword());
  32.        }
  33.        
  34.        return "success";
  35.     }
  36.    
  37.         public String getUsername() {
  38.                 return username;
  39.         }
  40.         public void setUsername(String username) {
  41.                 this.username = username;
  42.         }
  43.         public String getPassword() {
  44.                 return password;
  45.         }
  46.         public void setPassword(String password) {
  47.                 this.password = password;
  48.         }
  49.    
  50.    
  51. }

各种配置

上面的只是处理代码,需要结合配置才能正常使用,不,还得结合实际的 jar 包!

Article type: 

Comments

代码可以看逻辑的分层以及处理,没有配置,上面的东西是跑不起来的。

web.xml配置

  1.   <!-- contex 参数:spring 的配置文件 -->
  2.   <context-param>
  3.       <param-name>contextConfigLocation</param-name>
  4.       <param-value>classpath:resource/applicationContext.xml</param-value>
  5.   </context-param>
  6.  
  7.         <!-- spring 支持:spring listener -->
  8.         <listener>
  9.                 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  10.         </listener>
  11.    
  12.   <!-- struts2支持:struts2 filter -->
  13.   <filter>
  14.       <filter-name>struts2</filter-name>
  15.       <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  16.    </filter>
  17.  
  18.    <filter-mapping>
  19.       <filter-name>struts2</filter-name>
  20.       <url-pattern>/*</url-pattern>
  21.    </filter-mapping>

src 下需要一个 resource 文件夹,当然这个名字是 me 起的,下面有个 applicationContext.xml 文件和 jdbc.properties 文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3.         <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  4.                 <property name="driverClass">
  5.                         <value>${driverClass}</value>
  6.                 </property>
  7.                 <property name="jdbcUrl">
  8.                         <value>${jdbcUrl}</value>
  9.                 </property>
  10.                 <property name="user">
  11.                         <value>${user}</value>
  12.                 </property>
  13.                 <property name="password">
  14.                         <value>${password}</value>
  15.                 </property>
  16.         </bean>
  17.    
  18.     <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
  19.         <property name="dataSource" ref="dataSource"></property>
  20.         <property name="annotatedClasses">
  21.      <list>
  22.        <value>model.User</value>
  23.      </list>
  24.      </property>
  25.  
  26.         <property name="hibernateProperties">  
  27.             <props>  
  28.                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
  29.                 <prop key="hibernate.show_sql"> true</prop>  
  30.             </props>  
  31.         </property>  
  32.     </bean>
  33.    
  34.         <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  35.                 <property name="sessionFactory" ref="sessionFactory"/>  
  36.         </bean>
  37.  
  38.         <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  39.                 <property name="locations">
  40.                         <list>
  41.                                 <value>classpath:resource/jdbc.properties</value>
  42.                         </list>
  43.                 </property>
  44.         </bean>
  45.        
  46.         <bean id="userDao" class="model.impl.UserDaoImpl">
  47.             <property name="sessionFactory">
  48.                 <ref bean="sessionFactory"/>
  49.             </property>
  50.         </bean>
  51.        
  52.         <bean id="server" class="service.impl.UserServiceImpl">
  53.                 <property name="userDao" ref="userDao"></property>
  54.         </bean>
  55. </beans>
# jdbc.properties
#mysql
jdbcUrl=jdbc:mysql://localhost:3306/test
driverClass=com.mysql.jdbc.Driver
user=root
password=root

src下添加一个 struts.xml 配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
  4.  
  5. <struts>
  6.    <constant name="struts.devMode" value="true" />
  7.    <package name="hello" extends="struts-default">
  8.       <action name="login" class="action.LoginAction" method="execute">
  9.          <result name="success">/welcome.jsp</result>
  10.       </action>
  11.    </package>
  12. </struts>

貌似就这些配置文件,一个是项目配置 web.xml,一个是 spring 的配置 applicationContex.xml,一个是 spring 的辅助配置 jdbc.properties,一个是 sturts 的配置 struts.xml。剩下的就是 jar 包的问题了。

精诚所至,金石为开

一个笨方法是,将所有的 struts2、hibernate 4 和 spring 4 的jar 包全部全进去,O__O"…。me 没有试过,不过应该是可以的,不过也可能会有些冲突。下面罗列很可能是必须添加的包:

spring包

  • spring-aop-xxx.jar
  • spring-aspects-xxx.jar
  • spring-beans-xxx.jar
  • spring-context-xxx.jar
  • spring-context-support-xxx.jar
  • spring-core-xxx.jar
  • spring-expression-xxx.jar
  • spring-jdbc-xxx.jar
  • spring-orm-xxx.jar
  • spring-tx-xxx.jar
  • spring-web-xxx.jar

hibernate包

  • antlr-xxx.jar
  • c3p0-xxx.jar
  • spring-beans-xxx.jar
  • common-logging-xxx.jar
  • dom4j-xxx.jar
  • hibernate-jpa-xxx-api.jar
  • javassist-xxx.jar
  • javax.annotation-api-xxx.jar
  • jboss-logging-xxx.jar
  • hibernate-commons-annotations-xxx.jar
  • hibernate-core-xxx.jar

struts2包

  • commons-io-xxx.jar
  • commons-lang-xxx.jar
  • freemaker-xxx.jar
  • common-logging-xxx.jar
  • ongl-xxx.jar
  • struts2-core.jar
  • xwork-core-xxx.jar
  • javax.annotation-api-xxx.jar
  • commons-lang3-xxx.jar
  • struts2-spring-plugin-xxx.jar

精诚所至,金石为开