ssh整合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ssh整合相关的知识,希望对你有一定的参考价值。

 

 

1.三大框架的整合原理:

技术分享

  spring与struts2整合就是将action对象交给spring容器负责创建

  spring与hibernate整合就是将sessionFatory交给spring来维护

2.导包

hibernate

技术分享

持久化规范

技术分享

数据库驱动

技术分享

struts2

技术分享

struts2整合spring需要的插件包

技术分享

这个插件包一旦导入,那么struts2在启动时就会自动寻找spring容器,找不到就抛出异常

spring的基本包:

core|beans|context|expression|logging|log4j

aop包:

spring-aop|spring-aspect|aop联盟|aopweaving

hibernate和事务:

spring-jdbc|spring-tx|c3p0|spring-orm

标签库:

standard.jar,  jstl-1.2.jar

3.首先单独配置spring容器

  在src下创建一个名为:applicationContext.xml的xml文件
  在文件中书写一个<beans></beans>
  在配置spring容器时要导入xml文件的约束,一共四个,分别是:beans,context,aop,tx约束
  约束导入完成后的xml视图中的design应该是下面这个样子的:

技术分享

在web.xml文件中配置一个监听器,让spring随web项目的启动而创建

 <!-- 配置spring随web项目启动而创建 -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

在web.xml文件中配置spring文件的位置

<!-- 配置spring文件的位置 -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

4.单独配置struts2

  首先配置struts2的主配置文件
  在src下创建一个名为struts.xml的配置文件,这个是struts2的主配置文件
  在struts2-core-2.3.24.jar包下找到struts-default.xml文件把

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

配置到struts.xml中

然后在web.xml中配置struts2的核心过滤器

<!-- 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>

5.整合spring和struts2

  在struts.xml文件中配置让struts的action对象交给spring容器管理
首先在struts2-spring-plugin-2.3.24.jar中找到struts-plugin.xml文件

<constant name="struts.objectFactory" value="spring" />

放到struts.xml文件中

然后就像:

<struts>
    <constant name="struts.objectFactory" value="spring" />
    <package name="ssh" namespace="/" extends="struts-default">
</struts>

做完了这一步,下面分为两种情况:

第一种是spring负责创建action以及组装(推荐)

假设现在有一个userAction类,
然后在struts.xml文件中配置这个类

<struts>
    <constant name="struts.objectFactory" value="spring" />
    <package name="ssh" namespace="/" extends="struts-default">
    <action name="UserAction" class="userAction" method={1}>
        <result name="success" type="redirect">/index.jsp</result>
    </action>
</struts>

注意:用这种方式是在class属性中填写spring中action对象的BeanName,
这种方式完全 由spring管理action的声明周期
不过它需要手动组装依赖属性


接下来在applicationContext.xml文件中将userAction注入spring容器

<bean name="userAction" class="com.learn.web.action.UserAction" scope="prototype">
        
</bean>

需要注意的是:action对象的作用范围一定是多例的,这才符合struts2的架构

第二种是struts2自己创建action,spring负责组装依赖属性

<action name="UserAction_*" class="com.learn.web.action.UserAction" method={1}>
        <result name="success" >/index.jsp</result>    
</action>

这种方式不推荐

6.单独配置hibernate

首先准备一个实体类

public class User {
    /*
     * CREATE TABLE `sys_user` (
      `user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT ‘用户id‘,
      `user_code` varchar(32) NOT NULL COMMENT ‘用户账号‘,
      `user_name` varchar(64) NOT NULL COMMENT ‘用户名称‘,
      `user_password` varchar(32) NOT NULL COMMENT ‘用户密码‘,
      `user_state` char(1) NOT NULL COMMENT ‘1:正常,0:暂停‘,
      PRIMARY KEY (`user_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
     */
    private Long user_id;
    private String user_code;
    private String user_name;
    private String user_password;
    private Character user_state;
    public User(Long user_id, String user_code, String user_name, String user_password, Character user_state) {
        super();
        this.user_id = user_id;
        this.user_code = user_code;
        this.user_name = user_name;
        this.user_password = user_password;
        this.user_state = user_state;
    }
    
    public User(String user_name, String user_password) {
        super();
        this.user_name = user_name;
        this.user_password = user_password;
    }

    public User() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Long getUser_id() {
        return user_id;
    }
    public void setUser_id(Long user_id) {
        this.user_id = user_id;
    }
    public String getUser_code() {
        return user_code;
    }
    public void setUser_code(String user_code) {
        this.user_code = user_code;
    }
    public String getUser_name() {
        return user_name;
    }
    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }
    public String getUser_password() {
        return user_password;
    }
    public void setUser_password(String user_password) {
        this.user_password = user_password;
    }
    public Character getUser_state() {
        return user_state;
    }
    public void setUser_state(Character user_state) {
        this.user_state = user_state;
    }
    @Override
    public String toString() {
        return "User [user_name=" + user_name + ", user_password=" + user_password + "]";
    }
    
}

然后配置这个实体类的hibernate文件

  在实体类的当前包下创建xml文件名为:User.hbm.xml的xml文件
  在这个xml文件中配置orm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping SYSTEM 
     "hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.learn.domain">
    <!-- 配置与数据库对应到表名 -->
     <class name="User" table="sys_user">
     <!-- 配置与数据库对应的主键 -->
         <id name="user_id" >
             <generator class="native"></generator>
         </id>
         <!-- 配置除主键外的各个字段 -->
        <property name="user_code"  ></property>
        <property name="user_name"  ></property>
        <property name="user_password"  ></property>
        <property name="user_state"  ></property>
     </class>
</hibernate-mapping>

然后配置主配置文件
在src下创建名为hibernate.cfg.xml的xml文件
然后在这个文件中配置
在这里配置数据库的基本配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
    "hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <!-- 
        #hibernate.dialect org.hibernate.dialect.mysqlDialect
        #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
        #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
        #hibernate.connection.driver_class com.mysql.jdbc.Driver
        #hibernate.connection.url jdbc:mysql:///test
        #hibernate.connection.username gavin
        #hibernate.connection.password
         -->
             <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
             <property name="hibernate.connection.url">jdbc:mysql:///hibernate_01</property>
             <property name="hibernate.connection.username">root</property>
             <property name="hibernate.connection.password">root</property>
             <!-- 方言 -->
             <property name="hibernate.dialect">org.hibernate.dialect.MySQLMyISAMDialect</property>
             <!-- 线程绑定 -->
             <property name="current_session_context_class">thread</property>
             
             <!-- 将hibernate生成的sql语句打印到控制台 -->
             <property name="hibernate.show_sql">true</property>
             <!-- 将hibernate生成的sql语句格式化(语法缩进) -->
            <property name="hibernate.format_sql">true</property>
            <!-- 
            ## auto schema export  自动导出表结构. 自动建表
            #hibernate.hbm2ddl.auto create        自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
            #hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
            #hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
            #hibernate.hbm2ddl.auto validate    校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
             -->
            <property name="hibernate.hbm2ddl.auto">update</property>
            <!-- 引入orm元数据
            路径书写: 填写src下的路径
             -->
            <mapping resource="com/learn/domain/Customer.hbm.xml" />
            <mapping resource="com/learn/domain/User.hbm.xml"/>
            <mapping resource="com/learn/domain/LinkMan.hbm.xml"/>
        </session-factory>
</hibernate-configuration>

7.整合spring和hibernate

  其实就是将sessionFactory对象交给spring容器管理
  在这里也分成两种方案,第一种方案是:

在spring配置中放置hibernate配置信息

<bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="hibernateProperties">
            <props>
                <!-- hibernate的必选配置 -->
                <!-- <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
                <prop key="hibernate.connection.url">jdbc:mysql:///hibernate_01</prop>
                <prop key="hibernate.connection.username">root</prop>
                <prop key="hibernate.connection.password">root</prop> 
                因为配置了c3p0连接池,直接找 连接池要连接,所以这四个配置可以注解掉了
                -->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLMyISAMDialect</prop>
                <!-- 可选配置 -->
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
        <!-- 引入orm元数据,指定orm元数据所在的包路径,spring会自动读取包中的所有配置信息 -->
        <property name="mappingDirectoryLocations" value="classpath:com/learn/domain"></property>
    </bean>    

 

第二种方案就是将sessionFactory配置到spring容器中,仍然使用外部的hibernate.cfg.xml配置信息

  <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
    </bean>

8.spring整合c3p0

  首先要配置db.properties,在src下创建db.properties文件,在里面配置数据库的信息,就是把原本要在hibernate中

配置的数据库的信息配置到这个文件中

jdbc.jdbcUrl=jdbc:mysql:///ssh
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=root

然后就是将这个文件引入spring连接池中

<!-- 读取db.properties配置文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 配置c3p0连接池到spring容器 -->
    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>


在引入文件过后,就需要给连接池注入sessionFacory

  <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!-- 将连接池注入sessionFactory中 ,注入之后hibernate就会通过连接池获得连接-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

9.配置spring的aop事务

  在配置aop事务之前先配置核心事务管理器

<bean name="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <!-- 注入sessionFactory -->
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

aop事务的配置分为注解配置和xml配置.首先说xml文件配置

配置通知

  <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
                <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
                <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
                <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
                <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
                <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
                <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
                <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
            </tx:attributes>
        </tx:advice>

配置织入

    <aop:config>        
            <!-- 配置切点 -->
            <!-- <aop:pointcut expression="execution(* com.learn.service.impl.*ServiceImpl.*(..))" id="txPc"/> -->
            <!-- 配置切面 -->
            <!-- <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/> -->
        </aop:config>

第二种使用注解配置首先要开启注解事务

<tx:annotation-driven transaction-manager="transactionManager"/>

然后在service类中使用注解

@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
public class UserServiceImpl implements UserService {

10.扩大session的作用范围

  扩大session的作用范围是因为在使用懒加载时出现no-session问题

扩大session的作用范围非常简单,就在配置struts核心过滤器前面配置如下filter

<filter>
     <filter-name>openSessionInView</filter-name>
     <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
 </filter>
 <filter-mapping>
     <filter-name>openSessionInView</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>

注意:任何filter都要在struts2的filter之前,因为struts的filter一旦交给struts的流程运行了,是不会放行的


















以上是关于ssh整合的主要内容,如果未能解决你的问题,请参考以下文章

全栈编程系列SpringBoot整合Shiro(含KickoutSessionControlFilter并发在线人数控制以及不生效问题配置启动异常No SecurityManager...)(代码片段

Java的SSH框架整合

SSH整合总结(OA项目)

dwr与ssh框架整合教程

SSH 框架整合(maven版本 xml配置方式)

Memcached的配置,SSH项目中的整合(com.whalin),Memcached工具类,Memcached的代码调用