SSH 搭建点滴

来源:互联网 发布:海尔区域网络专员 编辑:程序博客网 时间:2024/06/15 01:06

转自:http://blog.csdn.net/marksinoberg/article/details/62235059

    • 前言
    • 开工
      • 第一步 导入相关jar包
      • 第二步 搭建Strtus2环境
        • 创建action和strutsxml
        • 设置过滤器
      • 第三步 搭建Hibernate环境
        • 创建实体类entity
        • 创建和实体类对应的映射配置文件Userhbmxml
        • 创建hibernate核心配置文件hibernatecfgxml
      • 第四步 搭建Spring环境
        • 创建Spring的核心配置文件
        • 让服务器启动的时候加载springxml
          • 注册监听器
          • 指定配置文件位置
      • 第五步 Strtus和Spring整合
        • 在spring中声明action类
        • 优化处理
      • 第六步 Spring和Hibernate的整合
        • 原本在hibernate中的数据源配置在springxml中
        • SessionFactory也在springxml文件中
      • 第七步 在dao层中使用HibernateTemplate
      • 第八步 配置事务的支持
    • 演示
      • 访问action
      • 后台打印数据
      • 对比数据库
    • 总结

前言

初学三大框架,懵懵懂懂,似是而非,云里雾里的,趁着眼下思路还算清晰,赶紧做个笔记,以备不时之需。

开工

三大框架,各有利弊,分开来用都是没的说,但是怎么能让它们整合起来发挥出各自的优势,却不是那么容易。
下面先列出我的项目目录图,以便于参照。
项目目录

第一步: 导入相关jar包

关于jar包,真的是让人又爱又恨的一个存在。版本之间不同的话,冲突还是很大的,尤其是大项目,依赖的jar包更是一个难题。

与之相比,Maven的存在在很大程度上解决了这个问题,仓库设置的恰当的话,更是一种享受。

为了更好的锻炼自己的能力,今天我还是按照原始的做法,从Dynamic Web Project开始吧。

一般来说,jar包都是项目经理或者团队之间预先准备好的,一方面可以解决版本问题,另一方面也能很好的管理团队的开发,维护。我这边东拼西凑的,也组织好了一份完整的jar包。有需要的话可以点击下面的链接下载(0积分,与君共勉)。
http://download.csdn.net/detail/marksinoberg/9782432

下载完之后,放到创建好的web项目的webContent文件夹下的WEB-INF的lib目录即可。
导入jar包

然后还可以add to build path.方面后续的操作。

第二步: 搭建Strtus2环境

我自己对于Struts2的理解,就是一个“前端(这是相对的概念,相对于整个项目而言)”的信使,管理着客户端发来的请求,然后把请求转发给不同的action来处理。

底层必然是使用FilterDispatcher了,这里就不过多讲述这方面的细节吧。

搭建环境也是非常清晰,大致分为以下两步。

创建action和struts.xml

刚才也说过了,请求是要经过特定的action来处理的,action相当于咱们的第一道“防线”。

下面在com.hailstudio.action包下创建一个UserAction,继承自ActionSupport类即可。(这样方便请求的处理操作)。

然后是在src目录下创建一个strtus.xml文件。注意好里面的schema约束和相对于action的设置,下面我给出我的案例。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts>    <package name="struts2" extends="struts-default" namespace="/">    <!-- 为了防止action被spring和strtus2加载两次,class的值写成spring的bean的id的值即可。 -->        <action name="userAction" class="userAction"></action>    </package></struts>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

里面注释的部分,是因为SSH整合的缘故,我们如果在class里面写上UserAction的全路径就会导致项目加载两次,这样的结果不是我们想要的,于是交给spring的容器来处理就好了。

具体的做法就是把class的值写成对应在spring中相对应的bean的id的值。

设置过滤器

设置过滤器的原因是为了让struts这个信使接收到来自客户端的请求。所以是很有必要的,在web.xml文件中添加上下面的代码就可以了。

<!-- 配置struts2的过滤器 -->    <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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

早前不知道为什么要这么设置,犯了很多的错误。大家引以为戒,就按照上面的格式来写就行了。

这也算是一个固定的表达吧。

第三步: 搭建Hibernate环境

hibernate作为持久化的一层,需要和底层数据打交道,所以咱们还是小心点好。不过搭建这个层面的环境还算是比较简单,按照路程一步步往下走吧。大致可以分为以下几个小步骤。

创建实体类entity

对应刚才的User系列,在com.hailstudio.entity包下面创建一个User.Java的类即可。

package com.hailstudio.entity;public class User {    private Integer uid;    private String username;    private String address;    public Integer getUid() {        return uid;    }    public void setUid(Integer uid) {        this.uid = uid;    }    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

创建和实体类对应的映射配置文件User.hbm.xml

这就没什么好说的了,Hibernate就是根据这个配置映射文件和底层数据库打交道的。其作用就是告诉Hibernate把我们的实体类怎么映射到数据库上。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>    <class name="com.hailstudio.entity.User" table="t_user">        <id name="uid" column="uid">            <generator class="native"></generator>        </id>        <property name="username" column="username"></property>        <property name="address" column="address"></property>    </class></hibernate-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

细节部分,还是参考官网文档比较好。

创建hibernate核心配置文件hibernate.cfg.xml

和strtus.xml文件一样,放到src的目录下即可。当然了,这个文件的文职我们可以任意指定,前提是spring来插手。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration>    <session-factory>        <!-- 数据源将在spring的配置中实现,这里可以注释掉        <property name="connection.username">root</property> <property name="connection.password">mysql</property>             <property name="connection.driver_class">com.mysql.jdbc.Driver</property>             <property name="connection.url">jdbc:mysql:///ssh?useUnicode=true&amp;characterEncoding=UTF-8</property> -->        <property name="connection.dialect">org.hibernate.dialect.MySQLDialect</property>        <!-- 解决没有配置方言的问题或者配置文件无法工作: http://blog.csdn.net/daryl715/article/details/1507385 -->        <!-- <property name="current_session_context_class">thread</property> -->        <!-- 但是在整合HibernateTemplate的时候就会出现会话未激活现象,用下面的代替:http://blog.csdn.net/maoyuanming0806/article/details/61417995 -->        <property name="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>        <property name="show_sql">true</property>        <property name="format_sql">true</property>        <property name="hbm2ddl.auto">update</property>        <!-- 引入映射文件 -->        <mapping resource="com/hailstudio/entity/user.hbm.xml" />    </session-factory></hibernate-configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

需要 注意的是切记不要忘记mapper文件的引入,不然核心配置文件还怎么工作?

第四步: 搭建Spring环境

针对MVC模型,Spring相当于一个中转站(Controller),接收来自Web层的Action请求,然后转交给持久层的Hibernate。

因此,不难看出,Spring在这里甚是重要。搭建起来思路也算是清晰,按照下面的步骤一点点来吧。

创建Spring的核心配置文件

Spring的核心配置文件的命名其实没有什么约束,起什么名字都是无所谓的,因为后续还需要手动指定一下。官方建议是命名为applicationContext.xml,但是我这边起了个更简洁的名字spring.xml。

对于这个核心配置文件,约束schema至关重要,我这里的案例也不是很全,但是基本上还算够用。

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"    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/tx    http://www.springframework.org/schema/tx/spring-tx.xsd    http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop.xsd    http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context-3.0.xsd">    <!-- dbcp数据连接池配置 -->    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"        destroy-method="close">        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>        <property name="url" value="jdbc:mysql://localhost:3306/ssh"></property>        <property name="username" value="root"></property>        <property name="password" value="mysql"></property>    </bean>    <!-- 让SessionFactory的创建也交给Spring来实现 -->    <bean id="sessionFactory"        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">        <!-- 把数据库的配置交给了spring的datasource了 -->        <property name="dataSource" ref="dataSource"></property>        <!-- 指定Hibernate的核心配置文件, -->        <property name="configLocations" value="classpath:hibernate.cfg.xml"></property>    </bean>    <!-- 创建action的bean对象 -->    <bean id="userAction" class="com.hailstudio.action.UserAction"        scope="prototype">        <property name="userService" ref="userService"></property>    </bean>    <!-- 创建service相关 -->    <bean id="userService" class="com.hailstudio.service.UserService">        <property name="userDao" ref="userDaoImpl"></property>    </bean>    <!-- 创建dao相关 -->    <bean id="userDaoImpl" class="com.hailstudio.dao.UserDaoImpl">        <property name="hibernateTemplate" ref="hibernateTemplate"></property>    </bean>    <!-- 引入HibernateTemplate模板的支持 -->    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">        <!-- 通过构造函数或者setter注入的方式将sessionFactory传给模板对象 -->        <property name="sessionFactory" ref="sessionFactory"></property>    </bean>    <!-- 开启事务管理器========然后开启注解 -->    <!-- 单纯配置好上面,无法完成持久化操作。必须要开启事务,否则只能为“只读”模式 -->    <bean id="transactionManager"        class="org.springframework.orm.hibernate5.HibernateTransactionManager">        <!-- 注入会话期工厂,可以点到源码中看到原因。sessionFactory中已经包含了DataSource -->        <property name="sessionFactory" ref="sessionFactory"></property>    </bean>    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven></beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

配置文件中很多东西没讲明白,后面会一一介绍每一个标签的作用的,这里就先这么写吧。

让服务器启动的时候加载spring.xml

为了让项目跑的更舒快,最好是在服务器启动的时候就加载这个核心配置文件,初始化一切需要的设置。

底层来讲,服务器启动就加载需要监听器和指定配置文件的步骤。
如下:

注册监听器

在web.xml文件中加上下面的代码。

<!-- 配置监听器,让服务器一旦启动就加载所需的配置文件,这个标签需要配合context-param来使用 -->    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

命名是固定的,按照上面的来写就行了。

指定配置文件位置

监听器的存在是为了告诉tomcat再启动的时候触发加载的行为,但是如果不指定配置文件的位置,服务器不可能自己找到的。通过下面的代码,就可以解决这一个问题。

还是在web.xml文件中,加上下面的代码。

<!-- 给服务器指定要加载的配置文件的路径 -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:spring.xml</param-value>    </context-param>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

classpath就是项目的类路径,如果spring.xml文件在具体的某一个包而不是在src路径下,我们只需要指定完整的路径即可。

从这里也可以看出,spring.xml文件的命名和放置的位置都是可以随意指定的了吧。

第五步: Strtus和Spring整合

Spring作为连接Strtus和Hibernate的桥梁,就在于要分别和它们来整合。

在具体的整合之前,我们再来思考一下,为什么要这么做。

因为Spring的IoC容器,我们把对象的创建权交给了Spring,所以action对象就得在spring中设置了。

具体有下面两个小步骤。

在spring中声明action类

action说到底,还是类,只要是类,spring就能很好的管理它。在spring.xml文件中写上如下代码。

<!-- 创建action的bean对象 -->    <bean id="userAction" class="com.hailstudio.action.UserAction"        scope="prototype">        <property name="userService" ref="userService"></property>    </bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

需要注意的就是action的scope需要设置为prototype,也就是多实例的。这是因为action本身的特性决定的。一个action要能被多次实例化,这样才能更好的处理多个客户端的请求嘛。

优化处理

优化处理就是减少不必要的对象的创建。具体来说也就是这个action bean对象只需要被spring处理就行了。所以这个class的值设置为这个类的完整类路径。而不需要再strtus的action标签中再次声明,对应刚才的strtus.xml的

<package name="struts2" extends="struts-default" namespace="/">    <!-- 为了防止action被spring和strtus2加载两次,class的值写成spring的bean的id的值即可。 -->        <action name="userAction" class="userAction"></action>    </package>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

这里面的class指定为对应的action在spring.xml的bean的id值就可以了。底层spring对很好的帮助我们处理。

第六步: Spring和Hibernate的整合

类比刚才的Strtus和Spring的整合,核心思想就是把创建对象的操作全部交给Spring来处理。那么Hibernate中关于数据源啊,SessionFactory啊这些,都配置在spring.xml文件中就行了。

原本在hibernate中的数据源配置在spring.xml中

<!-- dbcp数据连接池配置 -->    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"        destroy-method="close">        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>        <property name="url" value="jdbc:mysql://localhost:3306/ssh"></property>        <property name="username" value="root"></property>        <property name="password" value="mysql"></property>    </bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

SessionFactory也在spring.xml文件中

<!-- 让SessionFactory的创建也交给Spring来实现 -->    <bean id="sessionFactory"        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">        <!-- 把数据库的配置交给了spring的datasource了 -->        <property name="dataSource" ref="dataSource"></property>        <!-- 指定Hibernate的核心配置文件, -->        <property name="configLocations" value="classpath:hibernate.cfg.xml"></property>    </bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

第七步: 在dao层中使用HibernateTemplate

HibernateTemplate是一个微型的框架,类似于dbutils和jdbcTemplate或者我自己写过的DbHelper(https://github.com/guoruibiao/dbhelper)。

简化了底层操作,是spring封装了Hibernate的模块。

需要明确的是,在dao层中使用HibernateTemplate需要注入的支持,所以注入的具体实现还是要交给spring来处理。

按照处理客户端的具体的流程:action–service–daoimpl–hibernatetemplate。写出下面的注入配置就可以了。

<!-- 创建action的bean对象 -->    <bean id="userAction" class="com.hailstudio.action.UserAction"        scope="prototype">        <property name="userService" ref="userService"></property>    </bean>    <!-- 创建service相关 -->    <bean id="userService" class="com.hailstudio.service.UserService">        <property name="userDao" ref="userDaoImpl"></property>    </bean>    <!-- 创建dao相关 -->    <bean id="userDaoImpl" class="com.hailstudio.dao.UserDaoImpl">        <property name="hibernateTemplate" ref="hibernateTemplate"></property>    </bean>    <!-- 引入HibernateTemplate模板的支持 -->    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">        <!-- 通过构造函数或者setter注入的方式将sessionFactory传给模板对象 -->        <property name="sessionFactory" ref="sessionFactory"></property>    </bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

第八步: 配置事务的支持

我在这一点就忙活了好久,自认为代码这块没有问题了,但是一测试就会报错:没有active的session处理。查看了一些解决方案后原来是没有配置事务。在spring.xml使用下面的代码即可开启事务处理。

<!-- 开启事务管理器========然后开启注解 -->    <!-- 单纯配置好上面,无法完成持久化操作。必须要开启事务,否则只能为“只读”模式 -->    <bean id="transactionManager"        class="org.springframework.orm.hibernate5.HibernateTransactionManager">        <!-- 注入会话期工厂,可以点到源码中看到原因。sessionFactory中已经包含了DataSource -->        <property name="sessionFactory" ref="sessionFactory"></property>    </bean>    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

思路就是:配置事务管家,然后开启注解。开启注解是为了告诉框架在哪里开启事务。

通常来说会在service层中处理我们的业务逻辑,所以在service层开启事务是挺合适的啦。

如下:

package com.hailstudio.service;import org.springframework.transaction.annotation.Transactional;import com.hailstudio.dao.UserDao;@Transactionalpublic class UserService {    private UserDao userDao;    public void setUserDao(UserDao userDao) {        this.userDao = userDao;    }    public void service(int flag) {        System.out.println("User service !!!");        userDao.add(flag);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在UserService类上面添加@Transactional注解即可。

演示

至此,一个简答的SSH整合就算是结束了。下面简单的来演示一下效果。

访问action

访问action

后台打印数据

后台打印数据

对比数据库

对比数据库

总结

最后来回顾一下本文的主要内容。也就是一点点的搭建了整个SSH框架整合的过程。

总的来说,思路虽然还算是清晰,但是步骤也着实多了些。耐心不足的话很容易放弃。

而且对于spring的bean,其实还可以仅仅通过注解的方式实现。在spring.xml加上

<context:component-scan        base-package="com.hail.action,com.hail.dao,com.hail.service,com.hail.model" />
  • 1
  • 2
  • 1
  • 2

就行了,然后配合@component(@Controller, @Service, @Repository)注解就可以完成在xml中起相同作用的配置。

烦烦扰扰的配置了这么多,项目本身也变得越来越大。真的是不容易啊,不过一旦搭建好了环境,剩下的就只剩写业务代码了。也就没什么难度了。

还是怀念我的PHP啊,完成相同的功能,却是那么的简单。

0 0
原创粉丝点击