基于Maven搭建Spring + Hibernate + Struts2项目【原创】

目录
[隐藏]

一、前期准备工作

1.项目介绍:

本文记述了搭建一个基于spring、struts2,Hibernate框架项目的完整过程。

使用Maven来管理项目。采用Junit进行单元测试。服务器使用Tomcat。

项目名为SS2HDemo,实现一个简单的登陆功能。

(1)登陆界面:

6d15bb29-6f03-4dcf-98cf-b2fb8e665e2e

(2)登陆成功界面:

490a117d-f352-494d-bf03-f8ad9f3d8dfe

2.项目环境和工具

IDE Intellij:https://www.jetbrains.com/idea/download/

3.创建一个Web项目工程

Intellij中创建web项目,以及配置tomcat的过程可以参考“技术流”->”Tool”目录下的两篇博文:
(1)Intellij 创建Maven项目 http://7player.cn/2015/01/23/intellij-%E5%88%9B%E5%BB%BAmaven%E9%A1%B9%E7%9B%AE/
(2)Intellij 配置Tomcat http://7player.cn/2015/01/23/intellij-%E9%85%8D%E7%BD%AEtomcat/
一个创建完成后的初始化结构图:

ae385cdd-138b-4b29-88d1-e5148e7277da

二、SS2H开发过程

1.基础数据

(1)在mysql中创建数据库:ss2hdemo

(2)创建表:user,sql脚本如下

    drop table if exists users;  
    create table users(  
     id int(10) not null auto_increment,  
     name varchar(45) not null,  
     password varchar(20) not null,  
     primary key(id)  
    )engine=InnoDB;  

2.配置Maven

配置pom.xml文件。配置用到的第三方依赖包。

注意:这个配置文件是根据项目实际需要不断修改的。这里提供的是最终配置文件。

另外,Intellij也会根据用到编写代码时用到的jar包自动识别提示修改pom.xml的功能(但不能完全依靠IDE的提示)。

这里HIbernate用到的版本是Hibernate3.*。而最新的是Hibernate4.*,两者之间存在一些用法区别,请注意。

【pom.xml】

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.7player.ss2h</groupId>
  <artifactId>SS2HDemo</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SS2HDemo Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!--junit-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!--struts2-->
    <dependency>
      <groupId>org.apache.struts</groupId>
      <artifactId>struts2-core</artifactId>
      <version>2.3.20</version>
    </dependency>
    <!--使用Hibernate3-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>3.6.10.Final</version>
    </dependency>
    <!--spring-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>3.1.1.RELEASE</version>
    </dependency>
    <!--mysql-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.34</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>SS2HDemo</finalName>
  </build>
</project>

3.Hibernate相关

(1)对应数据库的user表,建立相应的User类(POJO),为MVC的模型层(Model)。放在cn.no7player.ssh.po包目录下:

【User.java】

package cn.no7player.ssh.po;
/**
 * Created by zl on 1/21/2015.
 */
public class User {
    private int id;
    private String name;
    private String password;
    public int getId(){
        return id;
    }
    public void setId(int id){
        this.id = id;
    }
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getPassword(){
        return password;
    }
    public void setPassword(String password){
        this.password = password;
    }
}

(2)创建user对应的的hibernate配置文件——user.hbm.xml。文件放在项目的resources目录下:

【user.hbm.xml】

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.no7player.ssh.po">
    <class name="User" >
        <id name="id" >
            <generator class="identity"/>
        </id>
        <property name="name"></property>
        <property name="password"></property>
    </class>
</hibernate-mapping>

(3)建立UserDAO接口,放在cn.no7player.ssh.dao包目录下

【UserDAO.java】

package cn.no7player.ssh.dao;
import cn.no7player.ssh.po.User;
import java.util.List;
/**
 * Created by zl on 1/21/2015.
 */
public interface UserDao {
    public String addUser(User user);
    public List<User> findUserByName(String name);
    public List<User> listAll();
}

(4)创建接口的实现:UserDAOImpl类

【UserDAOImpl.java】

package cn.no7player.ssh.dao.impl;
import cn.no7player.ssh.dao.UserDao;
import cn.no7player.ssh.po.User;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import java.util.List;
/**
 * Created by zl on 1/21/2015.
 */
@SuppressWarnings("ALL")
public class UserDaoImpl extends HibernateDaoSupport implements UserDao{
    @Override
    public String addUser(User user) {
        String success = "";
        String name = user.getName();
        if(findUserByName(name).size() == 0){
            try {
                getHibernateTemplate().save(user);
                success = "User saved ok!";
            } catch (DataAccessException e) {
                success = "Sorry, user can't be added.";
            }
        } else {
            success = "The username has been existed!";
        }
        return success;
    }
    @SuppressWarnings("unchecked")
    @Override
    public List<User> findUserByName(String name) {
        return getHibernateTemplate().find("from User where name = ?",name);
    }
    @SuppressWarnings("unchecked")
    @Override
    public List<User> listAll() {
        return getHibernateTemplate().find(" from User ");
    }
}

4.Service业务逻辑层

建立Service层的接口以及其实现。该层用来处理业务逻辑。本例中功能较为简单,实现中只是简单调用dao层的接口。

(1)UserService接口,放在cn.no7player.ssh.service包目录下:

【UserService.java】

package cn.no7player.ssh.service;
import cn.no7player.ssh.po.User;
import java.util.List;
/**
 * Created by zl on 1/21/2015.
 */
public interface UserService {
    public String addUser(User user);
    public List<User> findUserByName(String name);
    public List<User> listAll();
}

(2)UserServiceImpl实现,放在cn.no7player.ssh.service.impl包目录下:

【UserServiceImpl.java】

package cn.no7player.ssh.service.impl;
import cn.no7player.ssh.dao.UserDao;
import cn.no7player.ssh.po.User;
import cn.no7player.ssh.service.UserService;
import java.util.List;
/**
 * Created by zl on 1/21/2015.
 */
public class UserServiceImpl implements UserService{
    private UserDao userDao;
    public UserDao getUserDao() {
        return userDao;
    }
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public String addUser(User user) {
        return userDao.addUser(user);
    }
    @Override
    public List<User> findUserByName(String name) {
        return userDao.findUserByName(name);
    }
    @Override
    public List<User> listAll() {
        return userDao.listAll();
    }
}

5.spring相关

(1)创建Spring的配置文件applicationContext.xml,放在resources目录下。

其中包含数据库的配置内容,根据个人环境修改。配置中还包含多个bean的例如注入的配置,可以根据自己的项目结构修改。

注意:部分内容可能会提示出错,原因是依赖的包没加入,要在pom.xml中加入对应的依赖包。比如如下hibernate3的依赖:

    <!--使用Hibernate3-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>3.6.10.Final</version>
    </dependency>

完整的applicationContext.xml:

【applicationContext.xml】

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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.xsd">
       <!--数据源-->
       <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName">
                     <value>com.mysql.jdbc.Driver</value>
              </property>
              <property name="url">
                     <value>jdbc:mysql://localhost:3307/ss2hdemo</value>
              </property>
              <property name="username" value="root"/>
              <property name="password" value="123456" />
       </bean>
       <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
              <property name="dataSource">
                     <ref bean="dataSource"/>
              </property>
              <property name="mappingLocations">
                     <value>user.hbm.xml</value>
              </property>
              <property name="hibernateProperties">
                     <props>
                            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                            <prop key="hibernate.show_sql">true</prop>
                     </props>
              </property>
       </bean>
       <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
              <property name="sessionFactory">
                     <ref bean="sessionFactory"/>
              </property>
       </bean>
       <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
              <property name="sessionFactory">
                     <ref bean="sessionFactory"/>
              </property>
       </bean>
       <bean id="service" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
              <property name="transactionManager">
                     <ref bean="transactionManager"/>
              </property>
              <property name="transactionAttributes">
                     <props>
                            <prop key="add">PROPAGATION_REQUIRED</prop>
                            <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                     </props>
              </property>
       </bean>
       <bean id="userDAO" class="cn.no7player.ssh.dao.impl.UserDaoImpl">
              <property name="hibernateTemplate">
                     <ref bean="hibernateTemplate"/>
              </property>
       </bean>
       <bean id="userService" class="cn.no7player.ssh.service.impl.UserServiceImpl">
              <property name="userDao">
                     <ref bean="userDAO"/>
              </property>
       </bean>
</beans>

(2)建立一个辅助工具类,用来获取ApplicationContext,放在cn.no7player.ssh.util包目录下:

【InitApplicationContext.java】

package localhost.login.util;  
      
    import org.springframework.context.ApplicationContext;  
    import org.springframework.context.support.ClassPathXmlApplicationContext;  
      
    public class InitApplicationContext {  
          
        private static ApplicationContext context = null;  
          
        private InitApplicationContext(){  
              
        }  
        public static ApplicationContext getApplicationContext(){  
            if(context == null){  
                context = new ClassPathXmlApplicationContext("applicationContext.xml");  
            }  
            return context;  
        }  
    }  

6.struts2相关

(1)建立用户登陆的action,为MVC的控制层(Controller)。

【UserLoginAction.java】

package cn.no7player.ssh.action;
import cn.no7player.ssh.po.User;
import cn.no7player.ssh.service.UserService;
import cn.no7player.ssh.util.InitApplicationContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.springframework.context.ApplicationContext;
import java.util.List;
/**
 * Created by zl on 1/22/2015.
 */
public class UserLoginAction extends ActionSupport{
    private UserService userService;
    private User user;
    public UserLoginAction() {
        ApplicationContext context = InitApplicationContext.getApplicationContext();
        userService = (UserService) context.getBean("userService");
    }
    @Override
    public String execute() throws Exception {
        System.out.println(user.getName());
        if (!isValid(user.getName())) {
            return INPUT;
        }
        if (!isValid(user.getPassword())) {
            return INPUT;
        }
        if(!userCheck(user)){
            System.out.println("INPUT");
            return INPUT;
        }
        System.out.println("SUCCESS");
        ActionContext.getContext().getSession().put("user" , user);
        return SUCCESS;
    }
    public boolean isValid(String keyword) {
        return keyword != null && keyword != "";
    }
    public boolean userCheck(User user) {
        List<User> userList = userService.findUserByName(user.getName());
        if (userList == null || userList.size() < 1) {
            return false;
        }
        User checkUser = userList.get(0);
        System.out.println(checkUser.getName());
        if (user.getName().equals(checkUser.getName()) && user.getPassword().equals(checkUser.getPassword())) {
            return true;
        }
        addActionError("Username or password is wrong, please check!");
        return false;
    }
    public UserService getUserService() {
        return userService;
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}

(2)配置struts.xml文件

【struts.xml】

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
        <package name="default" namespace="/" extends="struts-default">
                <global-results>
                        <result name="error">/error.jsp</result>
                </global-results>
                <global-exception-mappings>
                        <exception-mapping exception="java.lang.Exception" result="error"/>
                </global-exception-mappings>
                <action name="login" class="cn.no7player.ssh.action.UserLoginAction">
                        <!-- 定义三个逻辑视图和物理资源之间的映射 -->
                        <result name="input">/login.jsp</result>
                        <result name="error">/error.jsp</result>
                        <result name="success">/welcome.jsp</result>
                </action>
        </package>
</struts>

(3)配置web.xml文件,使其支持struts2

【web.xml】

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Struts Blank</display-name>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <!--<listener>-->
        <!--<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>-->
    <!--</listener>-->
</web-app>

7.JSP相关

MVC的视图层(View)

(1)index.jsp 首页,登陆界面

<%--
  Created by IntelliJ IDEA.
  User: zl
  Date: 1/23/2015
  Time: 9:15 AM
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>Log in</title>
    </head>
    <body>
        <s:form action="login" validate="true">
            <s:textfield label="User Name" name="user.name" required="true"/>
            <s:password label="Password" name="user.password" required="true"/>
            <s:iterator value="errors">
                <s:property/>
            </s:iterator>
            <s:submit value="login"/>
        </s:form>
    </body>
</html>

(2)welcome.jsp 登陆成功页面:

<%--
  Created by IntelliJ IDEA.
  User: zl
  Date: 1/23/2015
  Time: 9:15 AM
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Hello</title>
</head>
<body>
  <h2>Welcome</h2>
  <s:if test="#session.user!=null">
    <h2>Hello <s:property value="#session.user.name"/></h2>
  </s:if>
</body>
</html>

(3)error.jsp 出错页面:

<%--
  Created by IntelliJ IDEA.
  User: zl
  Date: 1/23/2015
  Time: 9:44 AM
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
  <h2>Oh God,It's Wrong!</h2>
</body>
</html>

三、单元测试

测试用例应该在编写每一个模块时一起完成,但为了前面操作的流畅性,这里就把测试代码单独放在这里了。

1.测试dao层

【UserDaoTest.java】

package cn.no7player.ssh.dao;
import cn.no7player.ssh.po.User;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class UserDaoTest extends TestCase {
    private ApplicationContext context = null;
    private User user = null;
    private UserDao userDAO = null;
    public void setUp() throws Exception {
        super.setUp();
        context = new ClassPathXmlApplicationContext("applicationContext.xml");
        userDAO = (UserDao)context.getBean("userDAO");
    }
    public void tearDown() throws Exception {
        userDAO = null;
        user = null;
    }
    public void testAddUser() throws Exception {
        user = new User();
        user.setName("username");
        user.setPassword("password");
        userDAO.addUser(user);
        Assert.assertNotNull(user.getId());
        User userTwo = new User();
        userTwo.setName("username1");
        userTwo.setPassword("password");
        userDAO.addUser(userTwo);
        Assert.assertNotNull( user.getId());
    }
    public void testListAll() throws Exception {
        List<User> users = userDAO.listAll();
        Assert.assertEquals(users.size(), 2);
    }
}

2.测试action

【UserLoginActionTest.java】

package cn.no7player.ssh.action;
import cn.no7player.ssh.po.User;
import cn.no7player.ssh.service.UserService;
import cn.no7player.ssh.util.InitApplicationContext;
import com.opensymphony.xwork2.Action;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
public class UserLoginActionTest extends TestCase {
    private User user;
    private UserService userService;
    private ApplicationContext context = null;
    private UserLoginAction loginAction = null;
    public void setUp(){
        context = InitApplicationContext.getApplicationContext();
        loginAction = new UserLoginAction();
        userService = (UserService)context.getBean("userService");
    }
    //注:需要先执行UserDaoTest测试
    public void testUserLogin(){
        user = new User();
        user.setName("username");
        user.setPassword("password");
        try {
            loginAction.setUser(user);
            loginAction.setUserService(userService);
            Assert.assertEquals(Action.SUCCESS, loginAction.execute());
            user.setPassword("password1");
            System.out.println(loginAction.getActionErrors());
            Assert.assertEquals(Action.INPUT, loginAction.execute());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四、总结

1.项目全部结构图

4eb0fc52-f66c-4be3-a2ce-9d0205b79c40

2.为了能正常登陆测试,数据库应该添加一些数据。

301f5e64-91de-43ed-9721-250123a2f229

3.启动Tomcat,访问地址:http://localhost:8080/SS2HDemo/

38fd7b05-44a1-447a-b536-a0c9bcfd213a
分享到:

3 条评论

昵称
  1. 匿名

    按照博主的博文一步步进行,总体来说还是很顺利,但是数据库表的名称有误,导致一直查询不对,目前我也不知道类的名称是不是一定要和数据库表的名称一致,总之,把数据库的表的名称改为user之后就能顺利运行了

  2. 郭子

    表示每一步都是按着做的,并没有成功。pom的依赖都是一样的。整个项目跑是跑起来了,但是一点击“login”就出来500错误,个人猜测是spring的配置文件没有加载,不管怎么样还是很感谢博主的精心编写。辛苦了。鞠躬

  3. 匿名

    按照楼主的博文,终于搭建成功,我的jdk版本是1.8,需要修改java Target bytecode version为1.8