SSH框架在Web项目开发中的设计与实现
2018-10-18
(广州医科大学 信息技术教研室,广州 511436)
0 引言
随着Web技术在互联网上的发展,为解决web大型应用开发的复杂性和提高效率等,许多轻量级的web框架技术应运而生,著名的有Struts2,Spring、Hibernate、MyBatis等[1]。在这些框架中,许多框架专注于为某一层提供解决方案,例如表示层或持久层。Spring框架致力于简化Java EE应用程序的开发[2],将很多高质量的开源框架整合在一起,为企业应用开发提供一个全面的解决方案,降低企业开发的难度,提高开发效率。以购书网站后台管理系统的用户管理为例,阐述基于Spring整合Spring MVC和Hibernate的SSH框架在Java Web项目开发中的应用。
1 MVC设计模式
MVC(Model-View-Controller)是软件工程中的一种软件设计模式,把软件系统分为模型(Model)、视图(View)和控制器(Controller)3个部分[3]。图1显示MVC设计模式的关系模型。Model模型用于封装与业务逻辑相关的数据和处理方法;视图View是数据的呈现,与用户交互的界面,其组件一般是JSP或HTML;控制器Controller是接收请求,调用Model实现业务,调用View显示数据,最终完成用户请求。MVC设计模式将包含业务数据的模块与显示模块的视图解耦,不仅使得代码复用性和组织性更好,而且使Web应用的配置性和灵活性更好。
图1 MVC关系模型
2 Spring MVC
Spring MVC是一个实现了MVC设计模式的Web表示层框架,即用MVC设计模式的思想,将web层进行职责解耦,目的就是简化web开发。Spring MVC提供了构建 Web 应用程序的全功能 MVC 模,有清晰的角色划分,包括前端控制器(DispatcherServlet)、映射处理器(HandlerMapping)、映射适配器(HandlerAdapter)、视图解析器(ViewResolver)、控制器(Controller)、验证器(Validator)、命令对象(Command Object)、表单对象(Form Object)等,其中DispatchServlet是SpringMVC的核心组件。SpringMVC的工作流程如图2所示,Dispatcher Servlet接收到请求后,将请求委派为映射处理器,映射处理器和映射适配器根据请求所带的URL信息进行匹配选择控制器,然后请求发送给选中的控制器。控制器在完成逻辑处理后,通常产生一些需要返回给浏览器显示的信息,这些信息称为模型(Model),并且需要用界面友好的视图(通常是JSP)来显示[4]。控制器把模型数据和用于渲染输出的逻辑视图名,连同请求一起发送回DispatcherServlet。DispatcherServlet使用视图解析器将逻辑视图名匹配为一个特定的物理视图,然后将模型数据交付给物理视图来渲染输出。
图2 Spring MVC工作流程
Spring MVC虽然和Struts2功能相似,但Struts2是类级别的控制拦截,一个Action类对应一个请求URL上下文,而Spring MVC是方法级别的拦截,一个方法对应一个请求URL的上下文。
3 Spring
Spring是一个轻量级的企业级开源框架,是为了解决企业级应用程序开发的复杂性而创建[5]。Spring框架的核心是一个IoC容器,在这基础上提供了大量实用的服务,将很多高质量的开源项目集成起来。Spring框架大约由20个功能模块组成,这些模块分为7个部分:分别是CoreContainer、DataAccess/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation及Test,如图3所示。
图3 Spring框架结构
Spring的核心是控制反转IoC和AOP面向切面编程技术[6],Spring核心容器定义了创建、配置和管理Bean的方式,管理各个Bean对象之间的依赖关系,能够有效避免由于硬性编码所造成的耦合度过于紧密的状况;AOP功能可以轻松实现业务逻辑与系统服务(例如日志、事务等)的分离,使开发人员更加专注于业务逻辑实现。Spring是一个全面的解决方案,实现了表现层、业务层和持久层的整合,其主要目标是让现有的技术更加易用,绝不做重复实现,只是对现有方案提供支持,使之更易用。
4 Hibernate
Hibernate是一个优秀的Java持久层解决方案,是当今主流的对象—关系映射(ORM,Object Relational Mapping)工具[7]。Hibernate的工作流程如图4所示。
图4 Hibernate工作流程
Configuration首先读取并解析配置文件hibernate.cfg.xml,创建SessionFactory,SessionFactory是单例模式,只创建一次;接着SessionFactory创建Session接口,Session接口提供了操作数据库的各种方法:save()、delete()、load()等,Session方法是非线程安全,每次执行一次数据库事务,都需要创建Session对象;如果是增删改操作,则由Session对象开启一个事务对象Transaction,保证数据库操作的完整性如果数据库操作正常则提交事务,否则回滚;如果是查询操作,则由Session创建一个Query接口对象来执行查询,查询不需要开启事务。数据库访问结束,需要关闭Session对象,如果开启Transaction对象,也要关闭。在查询中,Query接口用于HQL查询,HQL(Hibernate Query Language)是Hibernate中最常用的一种面向对象的查询语言,可以理解继承、多态和关联之类的概念[8]。
Hibernate的优势在于数据库操作对象化,使用数据库方言机制和HQL查询语言,无须关心数据库类型,便于移植[9];Hibernate封装了JDBC,还封装了底层数据库事务处理,极大提高了开发效率;为了减少访问物理数据库的次数,还使用了缓存机制,从而提高了程序的运行性能。
5 SSH的系统结构
这里的SSH是Spring MVC、Spring和Hibernate的简称,这是当前主流的Web应用项目架构。Java EE经过多年的发展,已经形成一套成熟的系统结构,系统一般分为四层:表示层、控制层、业务层和数据持久层。在SSH框架下,其系统的程序结构如图5所示。
图5 SSH系统的程序结构
表示层一般为JSP页面,返回用户请求响应;控制层由Spring MVC框架负责,转发请求并调用业务层方法处理请求;业务层即Service层,是系统架构中体现核心价值的部分,它主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计上[10]。业务层处在控制层和持久层中间,对持久层而言,它是调用者,对控制层而言,它是被调用者。数据持久层由Hibernate框架实现。
在图5中,来自客户端的Request请求被由DispatcherServlet前端控制器接收,DispatcherServlet把请求派发给Controller控制器,Controller调用业务方法Service来实现业务,如需要访问数据库,业务类就调用Dao(Data Access Object,数据访问对象)数据操作类访问数据库。而Dao类则需要使用Hibernate的SessionFactory(会话工厂)提供的Session会话来实现具体操作,Session通过Connection来实现增删改擦操作,而Connection由数据源(DataSource)来提供。
Controller、Service、Dao都纳入Spring容器管理,Session由SessionFactory创建并管理,Connection由DataSource创建并管理,所以也需要把SessionFactory和DataSource加入Spring容器管理。
6 基于SSH框架的购书网站后台管理系统的设计与实现
6.1 系统功能模块设计
购书网站主要包括两个部分:前台部分和后台管理部分。前台部分主要服务于普通用户,用户可以查看图书信息,登录,注册,购买和进行个人信息管理、购物车管理、下单等操作;后台管理模块则是管理员对书店进行业务管理,其后台系统的基本功能模块设计如图6所示。
图6 购书网站后台管理的基本功能结构
6.2 SSH框架整合
首先进行系统的SSH框架整合,整合工作主要是Spring与Hibernate整合和Spring与SpringMVC的整合,整合以后,所有实例对象纳入Spring容器管理。整合分三步:
第一步,整合Spring和Hibernate。在Spring配置文件applicationContext.xml中,把外部导入的Properties属性文件、Hibernate的数据源对象、sessionFactory对象、事务管理等配置进来,Hibernate.cfg.xml就不再需要。接下来配置持久类映射文件的路径和Dao以及Service。为了简化配置工作,Dao和Service可以采用注解方式注入Spring容器。为了使用注解,需要在配置文件中加入两个配置,见下列代码。
上述配置的代码,可以自动扫描com.*包下的所有注解类。
第二步,Spring整合Spring MVC。需要单独使用一个配置文件springMVC.xml,该文件放在src下或WEB-INF下均可。Spring MVC的配置文件通常有三个常用的配置,分别是:
1)
2)
3)
此外,spring MVC的配置文件还需要配置视图解析器ViewResolover,表示把用户响应指定给某个表现层技术,例如JSP、JSTL,XLST和velocity等,通常设定为JSP。如果使用JSP,则配置的视图解析器是InternalResourceViewResolver;如果JSP页面需要使用JSTL标签,则增加
第三步,在Web.xml中配置Spring监听器ContextLoaderListener和SpringMVC的核心DispatcherServlet,以及其他一些参数,例如过滤器filter和上下文参数context-param。这样Spring MVC就可以监听来自客户端的请求,并把请求转发给DispatcherServlet处理。
6.3 系统实现
后台管理系统的功能主要是与后台数据库交互进行管理业务数据,与后台数据库的交互主要是数据库增加、修改、删除和查询等操作。所以这里以用户管理为例,主要讲述在SSH框架下用户管理功能的实现。
6.3.1 持久化类实体层
使用Hibernate来实现数据访问持久化,首先要建立持久化类以及配置持久化类和数据库表的一一映射关系。本系统的用户管理涉及两个数据表:User用户表和Role角色表,因此先创建与数据库表字段一一对应的持久化类User和Role,然后配置持久化类与数据库表之间的映射关系。在Hibernate中,有两种方式来实现该映射关系,一种是使用映射配置文件,即建立User.hbm.xml,还在改文件中表与表之间的关联关系;另一种是使用注解方式。本文采用注解来实现数据库表与持久类的映射关系,以及User持久化类和Role持久化类之间多对一关联关系。具体见如下代码:
@Entity //声明User类为POJO类
@Table(name="user") //和User数据库表建立映射关系
public class User {
//省略其他属性和注解
@ManyToOne(cascade=CascadeType.ALL,optional=true) //多对一关系的注解
@JoinColumn(name="role_id") //User表的外键role_id
private UserRole userRole=new UserRole();
//省略属性的getter/setter方法
}
与创建hbm.xml映射配置文件相比,使用注解可以减少代码工作量,其他相关注解的说明在此不再赘述。
6.3.2 Dao数据访问层
用户管理模块的Dao数据访问层是通过Hibernate直接访问数据库,定义并实现用户增加、修改、删除、查询和修改角色等Dao方法。系统面向接口编程,采用基于泛型
首先编写泛型的BaseDao
图7 基于泛型Dao的类图
由于Spring框架提供了对Dao组件的支持,支持用HibernateTemplate模板进行数据库持久化访问,所以在BaseDaoImpl
public abstract class BaseDaoImpl
protected SessionFactory sessionFactory;
private Class
public BaseDaoImpl(){
//当BaseDaoImpl
entityClass=(Class
}
public void save(T instance){
getHibernateTemplate().save(instance); }
//省略其他方法
}
使用HibernateTemplate的好处显而易见,只要传进实体类,不需要编写太多的SQL语句,就可以进行数据库持久化操作,再加上泛型的使用,便大大提高了程序的开发效率。
6.3.3 业务逻辑层
用户管理的业务逻辑层主要是实现与用户和角色相关的业务逻辑操作,包括复杂的业务流程处理,也可以调用底层的Dao方法来实现之。在业务逻辑层的实现上,系统也采用泛型模式建立泛型接口的BaseService
public interface BaseService
//声明增删改查的业务方法。
public void save(T instance);
public List
//省略其他方法
}
public abstract class BaseServiceImpl
private BaseDao
public void setBaseDao(BaseDao baseDao) {
this.baseDao = baseDao;
}
public void save(T instance) {
baseDao.save(instance);//实现save方法
}
//省略其他方法
}
public interface IUserService extends BaseService
//声明独有的方法
public void login(){ }
}
@Service("userService")
public class UserService extends BaseServiceImpl
@Autowired
private UserDao userDao;
public void setUserDao(UserDao userDao) {
//为泛型父类注入具体的userDao
super.setBaseDao(userDao);
this.userDao = userDao;
}
public void login() {
//代码略
}
}
在复杂大型的实际应用中,还可以把泛型的Dao和Service独立成一个核心包,其他的模块例如用户管理、订单管理等可以直接继承核心包里的泛型BaseDao和泛型BaseService,这样项目的程序结构更加清晰明了。基于泛型接口的Dao层和Service层搭建好,具体Dao实现类和Service实现类的代码量少很多,很大程度上降低了程序员的工作量,使程序员集中精力解决业务逻辑问题,加快系统的开发速度。
6.3.4 Web控制层
Web控制层由Spring MVC负责。系统为用户管理模块编写了一个UserController控制器类,包括用户的登录、注册、用户增加、修改、查询、角色修改等业务请求处理方法。来自客户端的用户请求由Spring MVC核心——DispatcherServlet接收,并把请求派发到Controller控制器的相应的处理用户请求的方法上,该方法调用业务逻辑层的Service方法来处理用户请求,然后把ModelAndView返回给DispatcherServlet。由于DispatcherServlet已经配置在Web.xml中,开发人员只需编写Controller类即可。UserController类的部分代码示例如下:
@Controller //注册为控制器类
//表示“/user”路径下的所有URL请求都交由UserController处理
@RequestMapping(value="/user")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private UserRoleService userRoleService;
//表示“/user/admin”的URL请求交给gotoadmin方法处理。
@RequestMapping(value="/admin")
public String gotoadmin() {
return "admin-index";
}
}
编写Controller类,一是需要声明所需要的Service接口,二是通过注解注册Controller类和请求地址映射及参数绑定。其中注解@Controller来将该类注册为Controller类,注解@RequestMapping来处理请求地址映射,注解@PathVariable或@RequestParam等进行参数绑定,三是编写具体操作方法,至此可实现控制层功能。
6.3.5 表示层
Spring MVC 有一个标签库,其标签库的jar包为spring.jar,需要加入项目库文件中。使用Spring MVC标签可以将请求参数绑定到命令对象上,由于系统已经在Spring MVC的配置文件中的配置了JSP作为视图响应技术,可以容易地使用Spring MVC标签或JSTL标签进行含有数据绑定的JSP页面开发。
本系统采用Bootstrap作为前端响应技术。Bootstrap是目前很受欢迎的前端开发工具,内置很多漂亮的样式,代码非常简洁,易于修改,具有灵活的响应式栅格系统和良好的浏览器兼容性支持,可以支持桌面浏览器和移动浏览器,本系统采用Bootstrap框架,就实现了后台运行一份代码,用户就可以根据需要随时在移动端、PC端进行交易。图8展示了桌面浏览器的用户管理界面。图9展示了移动端的图书列表界面。
图8 桌面端的后台用户管理
图9 移动端图书管理界面
7 结束语
本文介绍了Spring MVC、Spring和Hibernate的工作原理和特点,Spring MVC充当web层的控制器,Spring容器管理SpringMVC和Hibernate,进行业务逻辑处理,Hibernate负责与后台数据库进行交互实现持久层。以及介绍了基于SSH框架的购物网站后台管理基本模块的设计,并以后台系统的用户管理模块为例,简要阐述了在SSH框架下的Web项目开发的设计与实现。基于SSH架构的Web应用程序会具有良好的扩展性和复用性,能充分体现基于MVC设计模式的三层体系结构的特点和优点,并且层与层之间的高度解耦,使系统更加容易更新与维护,适应快速变化的用户需求。