,, ,2
(1.咸阳师范学院 计算机学院,陕西 咸阳 712000;2.西安电子科技大学 智能感知与图像理解教育部重点实验室,西安 710071)
Java EE是以Java为主进行企业级应用开发的技术平台,由于Java EE具有跨平台、稳定性高、兼容性好、技术自由搭配度高等特点,所以一直受到企业级应用开发的青睐。近年来,为了进一步解决传统Java EE开发所具有的组件依赖性高、开发难度大、部署与维护困难、用户交互性差等问题,出现了以Struts2、Hibernate、Spring、MyBaties为主的轻量级框架,目的是为了简化Java EE服务器端的开发过程。在客户端出现了Ext JS、BootStrap、Easy UI等JavaScript框架,目的是为了提高Web应用的富客户端体验。文献[1-2]研究了Struts2+Spring+Hibernate为主的Java EE应用开发方式,并应用到高校实验室管理和煤炭企业生产统计管理系统的设计开发中,阐述了其中的核心技术。文献[3-5]主要以Struts2框架为研究对象,讨论了在Java EE控制层的具体实现过程。文献[6]提出了以Hibernate框架为对象关系映射(object relation mapping,ORM)实现方式的数据持久化层的设计方式。文献[7-8]研究了Ext JS框架与服务器端轻量级框架的整合,并以动态树和地图信息加载为例具体描述了Ext JS的应用。
虽然上述学者的研究成果在某个系统设计过程中进行了实验验证,但笔者认为还存在两个主要问题:1)Struts2的高危安全漏洞。由于目前Struts2在国内经融、政务、大中型互联网公司、高校等领域的应用中广泛存在,Struts2存在的远程代码执行漏洞[9]爆出后,对相关领域带来了不少的损失。虽然Apache官方给出了漏洞的解决方案,但是用户逐渐丧失了对Struts2的信任,这种情况在2017初Struts2再次爆出高危漏洞后尤为明显;2)Ext JS的执行效率问题。虽然Ext JS 框架提供了功能强大的客户端组件,能够简化Java EE客户端的开发,但是它是一个重量级的前端框架,在某些复杂页面下,加载速度和执行效果不尽如人意。
本文在前人研究基础上,以Easy UI、Spring MVC、Spring、Hibernate等框架为基础,提出了一个基于ES2SH框架的Java EE应用架构。该架构利用Easy UI创建表示层,Spring MVC创建控制层,采用JSON作为表示层与控制层之间传输数据的格式。利用Hibernate创建数据持久层,通过Spring管理控制层与业务层、业务层与持久层之间组件的依赖关系,采用可扩展标记语言(extensible markup language,XML) 文件+注解的方式进行Spring MVC、Spring和Hibernate的集成。将该架构应用到高等院校目标考核管理系统的设计与实施中,详细描述了该架构应用的关键技术,为以该整合框架应用到其他领域的应用开发提供了一定的借鉴。
Easy UI是一组基于JQuery和超文本标记语言(HyperText Markup Language,HTML)5的用户接口(user interface,UI)插件集合体,只需要一些简单的HTML标签(不需要过多的JavaScript和层叠样式表(cascading style sheets,CSS)),即可设计出功能丰富且美观的UI界面。具有良好的浏览器兼容性、开源、轻量级、易于掌握等优点[10]。Spring MVC是Spring框架中用于实现Web功能的模块,它根据DispatcherServlet和配置文件,实现视图、控制器和模型之间的分离[11]。Spring 利用控制反转容器(Inversion of Control,IOC)创建并管理对象之间的依赖关系;通过面向方面编程(aspect oriented programming,AOP)实现业务逻辑与公共服务逻辑相分离。Hibernate是基于Java数据库连接(Java DataBase Connectivity,JDBC)的ORM框架,能实现对象与数据库表之间的映射[12-13],通过Hibernate查询语言(hibernate query language,HQL)以简化复杂结构化查询语言(structure query language,SQL)的编写,提高数据库开发效率。
在上述框架原理上,建立满足MVC模式的5层Java EE分层架构模型,如图1所示。表示层由Easy UI、视图组件构成,发送的请求统一由Spring MVC的前端控制器DispatcherServlet接收,根据配置文件将请求转发到某个具体的Controller组件。Controller调用Service组件执行
业务逻辑,以ModelAndView组件返回逻辑视图,DispatcherServlet调用ViewResovler解析出物理视图并填充Model需要显示的数据响应客户端请求。业务逻辑层通过Service接口向Controller组件提供服务,具体的业务逻辑处理和计算由Service对象完成,Service对象由Spring IOC容器管理。数据持久层由数据访问对象(data access object,DAO)模式与Hibernate框架搭建,DAO接口定义持久化逻辑并作为业务逻辑层访问的入口,DAO对象封装Hibernate通过映射文件完成持久化对象(persistent object,PO)与数据存储层之间的交互,DAO对象由Spring IOC容器管理。数据存储层负责存储应用系统所需要长久保存的数据以及之间的关联关系。
图1 整合ESMSH框架的Java EE架构
目标责任考核是高等院校行政管理的一项重要工作,通过制定、落实、执行、监督、分析各二级学院、职能部门的各项工作任务和进展情况,针对不足找出差距,提出改进措施,从而推动学校又快又好的发展。通过分析目标考核工作的具体流程,结合上述ESMSH框架设计了目标考核管理信息系统,主要包括基础数据、教工信息管理、指标管理、报表管理、信息查询和系统维护等模块。其中基础数据包括教育教学、科学研究、师资队伍建设、党团建设、学生工作5个大方面覆盖的所有基本数据。例如教育教学包括教务任务、课程设计、毕业设计、教学竞赛、教改项目、教学获奖、大学生科研训练、教育实习基地、“互联网+”大赛等相关数据。教工信息管理是指教工对自己基本信息的维护,包括工作经历、职称变动、部门调动、岗位聘任结果、个人荣誉、密码修改等操作。指标管理实现对指标的增、删、改、查。指标是考核的一个观测点,分为一级指标、二级指标和三级指标。例如“英语四级通过率”是一个三级指标,属于“教学质量”这个二级指标,对应的一级指标是“教育教学”。报表管理实现对目标任务下达情况、按指标按部门实现指标完成情况、年度考核结果等数据实现导出显示。信息查询主要针对各二级学院领导查看本单位目标任务完成情况。职能部门领导按照分管的一级指标查看二级学院的完成情况。校领导按照各种组合条件(以学院、工号、学位、职称、聘任岗位、指标等)查看任务完成情况。系统维护实现数据库的备份与还原、系统公告的发布、权限角色信息的管理、相关参数的配置等。
3.2.1 利用泛型DAO+Hibernate实现持久层
持久层的功能是利用Hibernate框架完成关系数据与对象的转换,以面向对象方式访问关系数据库。主要是通过XML形式的映射文件或在POJO形式的实体类中添加注解,实现对象属性与对应表的字段、对象之间的依赖关系与对应数据表之间的主、外键约束之间进行映射[14]。具体实现包括两个核心步骤:第一,创建泛型DAO接口及其实现类。由于每个实体类的持久化操作都具有相似的代码,为了提高代码的复用率,定义一个泛型的DAO接口-BaseDAO,其中定义所有持久化对象基本的CRUD方法[15]。BaseHibernateDAO为BaseDAO的实现类,该类继承HibernateDaoSupport实现BaseDAO中的所有方法。HibernateDaoSupport是Spring支持Hibernate的DAO工具,通过其关联的HibernateTemplate模板类可以在无需打开或关闭Session对象的情况下,实现数据库的CRUD操作,提高了持久层的开发效率。第二,创建并配置每个实体类对应的DAO接口及其实现类。某个实体类的DAO接口继承BaseDAO接口,只需定义该实体类特有的持久化方法,实现类继承BaseHibernateDAO完成特有的持久化方法,最后利用@Repository注解将DAO在Spring IOC容器中进行配置。上述操作需要的类图如图2所示。
图2 持久层类图关系
3.2.2 利用Spring IOC+AOP实现业务层
业务层完成系统的核心逻辑,包括两类:与业务计算相关的逻辑和与业务计算正交的公共逻辑(例如日志、权限等)。对于业务计算逻辑采用接口分离原则进行设计,首先定义Service逻辑接口定义组件的业务功能,作为控制层Controller组件的调用入口;定义ServiceImp提供该组件的实现并依赖持久层的若干DAO 组件获取业务计算需要的持久化数据,DAO 对象由Spring IOC创建并注入。然后通过@Service注解将Service组件纳入Spring IOC容器管理。最后通过声明式注解为业务逻辑方法添加事务控制。启用声明式事务需要在Spring配置文件中添加如下代码:
针对与业务计算正交的公共逻辑采用AOP方式实现。将每个公共逻辑作为一个切面而定义,对于需要公共逻辑的业务逻辑采用正交织入的方式执行,这样便于公共逻辑的修改与维护,节省代码量。目标考核系统中的登录验证、权限验证、日志记录等操作都采用AOP的方式来实现,以权限验证为例进行说明。首先,在基于角色的访问控制(role-based access control,RBAC)理论[16]基础上定义教师账户类、部门账户类、角色类、权限类。系统所设计的登录帐户包括教师账户和部门账户两种类型,教师账户对应教师角色具有教师信息管理模块的所有权限;部门账户对应教师以外的相应角色,具有教师信息管理模块以外的其它相应权限。这样设计的优点有两个:(1)减少了教师账户的角色数量,从而也就减少了教师账户的权限数,便于操作与管理;(2)部门账户不再和某个具体的教师关联,同一部门里的任何一个教工只要知道部门账户,就可以执行相关的功能,便于考核工作的开展。然后,通过实现HandlerInterceptor接口定义拦截器,重写preHandle方法,该方法在执行Controller之前执行。具体的权限验证流程如图3所示,对应的代码如下所示:
图3 preHandle方法执行流程图
public class PermissionInterceptor implements HandlerInterceptor
{ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
User user=(User)request.getSession().getAttribute("user");
String currentURL=getURL(request);
if (user == null) {
if("user/userController_login".startsWith(currentURL))
return true;
else {
response.sendRedirect("login.jsp");
return false;
} }
// 用户登录后判断权限
else {
//对退出操作对应的Controller进行放行 if("user/userController_loginOut".startsWith(currentURL))
return true;
else {
if(user instanceof UserVO) {
UserVO loginedUser=(UserVO)user;
if (loginedUser.hasPermission(currentURL)) {
//用户拥有权限就放行
return true;
} else {
//如果没有权限就拦截
response.sendRedirect("noPermission.jsp");
return false; } }
else {
// 如果当前登录用户是部门账户,则判断
部门账户的权限,判断逻辑同上。
………………….
}
}}
3.2.3 利用Spring MVC实现控制层
控制层充当MVC模式中的控制器,负责接收表示层数据交由业务层进行数据处理,根据请求结果调用对应的视图数据进行响应。具体实现过程包括以下步骤:首先在web.xml文件中配置前端控制器,由Web容器在启动时创建前端控制器实例,它负责给Controller分派表示层请求,并执行视图解析。然后定义spring-mvc.xml文件,完成注解扫描、处理器映射器、处理器适配器、视图解析器的配置。注解可以简化XML的配置,处理器映射器和处理器适配器负责映射前端控制器转发给controller的映射策略。视图解析器负责解析Controller返回的ModelAndView组件,形成特定形式的视图组件。执行顺序如图4所示[17]。最后创建Controller组件调用业务层组件。本系统采用无侵入式定义,将控制器当作普通的JavaBean,通过@Controller对控制器进行标注,在相关方法上标注@RequestMapping并注明访问该方法的URL后缀。
图4 Spring MVC执行流程
3.2.4 利用Easy UI+JSP实现表示层
表示层为用户提供交互操作并展示Web应用的界面。为提高用户交互体验,便于模块化开发,本架构以Easy UI+JSP作为表示层开发的核心组件。首先,在JSP页面引入Easy UI核心JS文件和CSS文件,包括jquery.min.js、jquery.easyui.min.js、中文提示信息库、核心UI文件和图标文件等。然后,根据模块功能定义独立的JS文件,在该文件定义定义各种EasyUI函数,这样可以分离HTML与JavaScript代码,便于开发与维护。以招生就业处管理员给各二级学院下达综合指标目标任务的页面为例,如图5所示。左侧通过树形控件显示当前登录用户的权限菜单,右侧主要通过加载Datagrid控件以二维表格形式显示各二级学院对应招生就业工作三级指标的任务分值、年份以及审核状态。表格中的数据是在用户点击相应权限菜单后,利用Ajax请求异步访问Web服务器获取的,并且在返回表示层前,控制层通过jackson序列化Java对象为标准JSON格式。为了提高用户的可操行,设置Datagrid单元格为可编辑性,在一个页面中即可完成对各二级学院按三级指标下达任务数据,点击“保存”按钮将数据传送到服务器端保存。按钮触法事件对应的JavaScript代码如下所示。
图5 目标任务下达页面
function accept(){
var ids=""; //修改行的指标:指标值
var index = editIndex;
if (endEditing()){
(' dg').datagrid('acceptChanges').datagrid('unselectAll');} //表字段取出放入数组中
var data = (" dg").datagrid('getData');
for(var item in data.rows[index]){
if(item!="ejxy" && item!="status" && item!="year"){
ids+=item+":"+data.rows[index][item]+",";
}}
.post("assignTask_StudentPartyWork_update",{"ids":ids},function(data){
if(data!=null){
(" dg").datagrid('reload','assignTask_StudentPartyWork_viewJson');
}
},'json');}
在对Easy UI、Spring MVC、Spring和Hibernate框架分析的基础上,提出基于ESMSH框架的Java EE应用架构。将该架构应用到目标考核管理系统的开发实践中,阐述了架构实现的核心技术。以ESMSH架构所实现的目标考核管理系统已在咸阳师范学院各职能部门、二级学院和全体教师之间展开运行,已顺利完成了2016、2017年度的目标考核工作,全面提升了学校目标考核工作的信息化水平,取得了较好的满意度,表明本文所提出的Java EE架构稳定、可靠。下一步准备在该架构基础上引入微服务思想,细化基础数据部分,并为学校的其他业务工作服务。