资讯专栏INFORMATION COLUMN

ssh(Spring+Struts2+hibernate)整合

tulayang / 1830人阅读

摘要:需求整合框架做一个保存用户的业务,业务比较简单,重在框架整合。

需求:整合ssh框架做一个保存用户的业务,业务比较简单,重在ssh框架整合。
创建数据库和表

CREATE DATABASE ssh01;
USE DATABASE;
表由Hibernate创建,可以看配置是否成功

一:导入jar包

Hibernate需要jar

   Hibernate基本jar
   mysql驱动  
   c3p0连接池
   日志包
   jpa

Struts需要jar
Struts2基本jar

Spring需要jar

   Ioc(6个):beans,context,expression,core+两个日志
   Aop(4个):
       spring-aop-4.2.4.RELEASE
       spring整合aspect
       aspectj:com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
       aop联盟:com.springsource.org.aopalliance-1.0.0.jar
   spring声明式事务:
       spring-jdbc-4.2.4.RELEASE.jar
       spring-tx-4.2.4.RELEASE.jar

Spring整合web

   spring-web-4.2.4.RELEASE.jar

Spring整合Hibernate

   spring-orm-4.2.4.RELEASE.jar

Spring整合Struts2

   struts2-spring-plugin-2.3.24.jar
   **注意**
       Spring整合Struts2包先不要导入,因为如果导入在项目启动的时候,
       会在ServetContext中查找spring工厂,会报错,抛出下面异常
   
You might need to add the following to web.xml: 
            
                org.springframework.web.context.ContextLoaderListener
            
        17:46:11,396 ERROR Dispatcher:42 - Dispatcher initialization failed
        java.lang.NullPointerException

在配置ContextLoaderListener监听器在项目启动的时候创建spring容器的时候导入

最后:去除重复的jar struts2基本Jar和Hibernate基本Jar中都有
javassist-3.18.1-GA.jar,删除一个低版本的,否则在使用的时候会出现问题。

二:需要的配置文件

Hibernate需要的配置文件

   Hibernate.cfg.xml:src路径下

    
        
        com.mysql.jdbc.Driver
        jdbc:mysql:///ssh01
        root
        root
        
        
        
        org.hibernate.dialect.MySQLDialect
        
        
        true
        
        true
        
        update
        
        
        org.hibernate.connection.C3P0ConnectionProvider
        
        
        
    

jdbc.properties:(对数据库参数的封装) src下

jdbc.driver=com.mysql.jdbc.Driver;
jdbc.url=jdbc:mysql://localhost:3306/ssh01
jdbc.username=root
jdbc.password=root

log4J.properties日志文件 src下

Customer.hbm.xml 需要保存客户实体的映射文件


    
        
        
            
            
        
        
        
        
        
        
        
    

Struts需要的配置文件

   web.xml:配置Struts核心过滤器

      Struts2
      org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  
  
      Struts2
      /*
  
  struts2.xml:配置action 位置src下

    
    
        
            /success.jsp
        
    

applicationContext.xml src下(待会配置)

三:创建service,dao,domain,action

创建Customer实体类,以及实体类对应的映射文件映射文件看上面)

 伪代码(为属性提供get/set方法)
public class Customer implements Serializable{
    private static final long serialVersionUID = 1L;
    private Long cust_id;
    private String cust_name;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_phone;
    private String cust_mobile;

CustomerService,CustomerServiceImpl

    将customerService对象交给spring容器管理
    service需要调用dao层的方法,进行属性注入
public class CustomerServiceImpl implements CustomerService {
    //创建dao,并提供set方法,进行属性注入
    private CustomerDao customerDao;
    public void setCustomerDao(CustomerDao customerDao) {
        this.customerDao = customerDao;
    }
    @Override
    public void save(Customer customer) {
        customerDao.save(customer);
    }
}

创建CustomerDao,CustomerDaoImpl
将CustomerDao对象交给spring容器管

public class CustomerDaoImpl implements CustomerDao {
    @Override
    public void save(Customer customer) {
        //获取session对象,来操作数据库
        Configuration config = new Configuration().configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.openSession();
        Transaction tx = session.beginTransaction();
        session.save(customer);
        tx.commit();
        session.close();
    }
}

创建CustomerAction并在struts.xml中进行配置(struts.xml文件)

public class CustomerAction extends ActionSupport implements ModelDriven {
    private static final long serialVersionUID = 1L;
    //使用ModelDriven模型驱动进行数据封装,必须手动来创建对象
    private Customer customer = new Customer();
    @Override
    public Customer getModel() {
        return customer;
    }
    /*
     * 创建CustomerService对象调用service层的方法
     * 因为action是由struts2创建service交给spring容器管理所以不可以直接注入
     */
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 
    CustomerService customerService = (CustomerService) context.getBean("customerService");
    //保存用户的方法
    public String save(){
        customerService.save(customer);
        return SUCCESS;
    }
}

在spring容器中管理CustomerService,CustomerDao


    
    
    
        
    

创建save.jsp

客户名称:
客户等级:
客户来源:
客户行业:
客户电话:
          

三:测试

在浏览器输入http://localhost/ssh01/save.jsp输入数据,点击提交,
数据库表创建成功,数据成功保存

这样,最简单最原始的ssh框架整合完成。

问题一:在CustomerAction中的获取service

解决方案:

使用监听器,当项目启动的时候监听ServletContext对象的创建,
当ServletContext对象创建的时候加载applicationContext.xml文件,
创建spring工厂初始化bean将spring容器放置在ServletContext域对象中

spring为我们提供了ContextLoaderListener,在web.xml文件中配置该监听器,
它会加载applicationContext.xml,创建spring工厂,
并存放在ServletContext域对象中
    

代码实现

在web.xml中进行配置

      contextConfigLocation
      classpath:applicationContext.xml
  
  
      org.springframework.web.context.ContextLoaderListener
  
在CustomerService中获取service
ServletContext servletContext = ServletActionContext.getServletContext();
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
CustomerService customerService = (CustomerService) context.getBean("customerService");

问题二:Action由struts2容器管理,service是交给spring容器管理,不能直接注入
    如何在action中注入service

解决方案:spring整合struts
前提:导入struts-spring-plugin.jar,在项目启动的时候创建spring工厂,
    放置到context域中
    
方式一:Action还是struts创建,Spring负责为Struts中的Action注入匹配的属性
//由spring容器为action进行属性注入
    private CustomerService customerService;
    public void setCustomerService(CustomerService customerService) {
        this.customerService = customerService;
    }
原因:为什么直接导入struts2-spring-plugin.jar包就可以直接注入?
在default.properties配置有中struts.objectFactory.spring.autoWire = name
Spring负责为Struts中的Action注入匹配的属性,根据属性的名称注入(默认,可以修改)

方式二:将action交给spring容器来管理,
    action是多例的,所以需要配置scope="prototype"属性
    修改applicationContext.xml和struts.xml文件

    
        
    
    修改struts文件:
    
        
            /success.jsp
        
    

问题三

在dao层,使用Hibernate操作数据库,需要加载Hibernate.cfg.xml配置文件
获取SessionFactory(类似于DataSource数据源)然后获取到session对象
(类似于Connection连接对象,SessionFactory:是重量级并且线程安全的,
所以在项目中只存在一份即

解决方案
    将SessionFactory交给spring容器管理:单例
sessionFactory是一个接口,在这里我们使用它的实现类LocalSessionFactoryBean
选择Hibernate5的,因为我们使用的Hibernate是5.0.7版本的



在applicationContext.xml中配置

        
        
使用spring提供的HibernateTemplate在dao层操作数据库,将HibernateTemplate交给
spring容器来管理,并注入到dao层

在applicationContext.xml中进行配置
配置Hibernate模板需要注入SessionFactory,因为模板是对Hibernate的包装,底层还是
使用session来操作数据库,所以需要获取到session对象,通过SessionFactory对象
    
        
            
            
        
        
    
    
        
        
    
修改之后dao层的代码如下
public class CustomerDaoImpl implements CustomerDao {
    //注入HibernateTemplate来操作数据库
    private HibernateTemplate hibernateTemplate;
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }
    @Override
    public void save(Customer customer) {
        hibernateTemplate.save(customer);
    }
}
这样直接运行程序,会抛出异常,异常信息为:
Write operations are not allowed in read-only mode (FlushMode.MANUAL):
    Turn your Session into FlushMode.COMMIT/AUTO or remove "readOnly" 
    marker from transaction definition.
问题:只读模式下(FlushMode.NEVER/MANUAL)写操作不被允许:
把你的Session改成FlushMode.COMMIT/AUTO或者清除事务定义中的readOnly标记

spring会将获取到的session绑定到当前线程中,
为了确保在一个请求中service层和dao层使用的是一个session对象
只有受spring声明式事务的方法才具有写权限。否则在操作的会抛出上面异常

所以还需要在applicationContext.xml中配置spring的声明式事务

    
    
        
         
    
    
    
        
            
            
            
            
        
    
    
    
        
        
        
    
这样一个纯xml配置整合ssh框架就完成了!!!

在实际的开发中都是注解+xml来完成的。现在我们来对代码进行优化。
在实际的开发中:
    我们自定义bean的创建和注入通过注解来完成(CustomerService等)
    非自定义的bean交给xml文件配置(例如数据源dataSource和SessionFactory)
    
    
优化一:去除struts.xml文件(action的配置使用注解来完成)
使用注解的方式配置action必须导入jar包struts2-convention-plugin-2.3.24.jar
在CustomerAction上面添加注解:
@Namespace("/")
@ParentPackage("struts-default")
public class CustomerAction extends ActionSupport implements ModelDriven {
    private static final long serialVersionUID = 1L;
    //使用ModelDriven模型驱动进行数据封装,必须手动来创建对象
    private Customer customer = new Customer();
    @Override
    public Customer getModel() {
        return customer;
    }
    //由spring容器为action进行属性注入
    private CustomerService customerService;
    public void setCustomerService(CustomerService customerService) {
        this.customerService = customerService;
    }
    //保存用户的方法
    @Action(value="customer_save",results={@Result(name="success",location="/success.jsp")})
    public String save(){
        customerService.save(customer);
        return SUCCESS;
    }
}

优化二:所有的自定义bean都使用注解的方式进行配置,
去除applicationContext中的自定义bean
必须在applicationContext中开启组件扫描

   在applicationContext中开启组件扫描
   
   

   CustomerAction中的代码
   @Namespace("/")
   @ParentPackage("struts-default")
   @Controller("customerAction")
   public class CustomerAction extends ActionSupport implements ModelDriven{
       @Autowired
       private CustomerService customerService;
   }

   CustomerServiceImpl中配置注解的代码
   @Service("customerService")
   public class CustomerServiceImpl implements CustomerService {
   @Autowired
   private CustomerDao customerDao;

   CustomerDaoImpl中注解的代码
   @Repository("customerDao")
   public class CustomerDaoImpl implements CustomerDao {
   //注入HibernateTemplate来操作数据库
   @Autowired
   private HibernateTemplate hibernateTemplate;

优化三:spring的声明式事务使用xml+注解的方式进行配置
减少applicationContext.xml文件中的配置代码

要在applicationContext中开启事务注解支持

事务是在service层进行控制的,在service层上加上事务注解
可以去除applicationContext中配置增强和aop配置的代码
@Service("customerService")
@Transactional
public class CustomerServiceImpl implements CustomerService

优化四:去除持久化类的映射配置文件,使用注解进行代替

其它字段和属性名相同,可以省略@Column
@Entity
@Table(name="cst_customer")
public class Customer implements Serializable{
    private static final long serialVersionUID = 1L;
    //oid
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
去除持久化类的映射配置文件之后,在Hibernate.cfg.xml文件中
引入持久化类映射文件的代码需要修改:


Customer.hbm.xml文件已经去除,修改为

优化五:去除Hibernate.cfg.xml

在前面applicationContext.xml中将SessionFactory交给spring容器管理的时候

    
    

指定了核心配置文件,现在需要手动的配置数据库参数以及Hibernate的一些基本配置
如是否显示sql语句,是否格式化sql语句,mysql方言配置等

最终:只留下了applicationContext.xml配置文件



    
    
    
    
    
    
    
        
        
        
        
        
    
    
    
        
        
        
        
            
                org.hibernate.dialect.MySQLDialect
                true
                true
                update
            
        
        
        
            
                com.itheima.domain
            
        
    
    
    
        
        
    
    
    
    
        
         
    

这样,以xml+注解结合方式整合ssh框架就完成了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67535.html

相关文章

  • 慕课网_《基于SSH实现员工管理系统之框架整合篇》学习总结

    时间:2017年08月16日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学源码:无学习源码:https://github.com/zccodere/s... 第一章:课程介绍 1-1 课程介绍 课程目录 1.ssh知识点回顾 2.搭建ssm开发环境 3.struts2整合spring 4.spring整合hibernate 5.案例:使用ssh框架开发...

    icattlecoder 评论0 收藏0
  • 纳税服务系统【总结】

    摘要:要是使用到日历的话,我们想到使用这个日历类上面仅仅是我个人总结的要点,如果有错误的地方还请大家给我指正。 纳税服务系统总结 纳税服务系统是我第一个做得比较大的项目(不同于javaWeb小项目),该项目系统来源于传智Java32期,十天的视频课程(想要视频的同学关注我的公众号就可以直接获取了) 我跟着练习一步一步完成需求,才发觉原来Java是这样用来做网站的,Java有那么多的类库,页面...

    ispring 评论0 收藏0
  • Java3y文章目录导航

    摘要:前言由于写的文章已经是有点多了,为了自己和大家的检索方便,于是我就做了这么一个博客导航。 前言 由于写的文章已经是有点多了,为了自己和大家的检索方便,于是我就做了这么一个博客导航。 由于更新比较频繁,因此隔一段时间才会更新目录导航哦~想要获取最新原创的技术文章欢迎关注我的公众号:Java3y Java3y文章目录导航 Java基础 泛型就这么简单 注解就这么简单 Druid数据库连接池...

    KevinYan 评论0 收藏0
  • 学Java编程需要注意的地方

    摘要:学编程真的不是一件容易的事不管你多喜欢或是多会编程,在学习和解决问题上总会碰到障碍。熟练掌握核心内容,特别是和多线程初步具备面向对象设计和编程的能力掌握基本的优化策略。   学Java编程真的不是一件容易的事,不管你多喜欢或是多会Java编程,在学习和解决问题上总会碰到障碍。工作的时间越久就越能明白这个道理。不过这倒是一个让人进步的机会,因为你要一直不断的学习才能很好的解决你面前的难题...

    leanxi 评论0 收藏0
  • SSH(Struts2+Hibernate+Spring)开发策略

    摘要:首先是应该了解框架技术的运行流程在此我给大家介绍一种常见的开发模式,这对于初学者来说应该也是比较好理解的。 很多小伙伴可能一听到框架两个字就会马上摇头,脑子里立刻闪现一个词---拒绝,其实我也不例外,但我想告诉大家的是,当你真正掌握它时,你会发现**SSH**用起来是那么顺手,因为它对于开发web应用真的很方便,下面就我个人经验和大伙儿谈谈如何利用**SSH框架技术**来进行*w...

    reclay 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<