5 系统关键技术的实现
一、技术路线:
开发语言:Java
前端技术:JavaScript、VUE.js(2.X)、css3
数据库:MySQL 5.7
数据库管理工具:Navicat或sqlyog
开发工具:IDEA或Ecplise
二、项目介绍:
https://www.bilibili.com/video/BV1i34y1c7A8/
三、运行截图:
本节主要针对系统模块实现中技术难点要点的阐述,会具体展示实现功能点的代码,并对涉及到的技术框架做简单的说明。主要包含系统架构的配置、初始化监听器的实现、控制层Action的设计,持久层BaseDao的设计,以及各个模块中使用到的技术要点例如分页实现,Json数据的封装等。
5.1 系统架构的搭建
系统的架构的组织结构,直接决定一个软件产品的性能,以及在开发中的重构程度以及开发效率等。一个好的系统架构,能在很大程度上决定这个产品的性能以及开发走势。本系统采用MVC设计思想,结合SSH做了组合和优化。
5.1.1 服务器启动WEB.XML的环境配置
web.xml是部署整个项目的入口,系统架构的开始定义在这个文件中。在本系统中使用了struts2和spring框架,以及在本系统中定义的一个用于数据初始化的监听器。都在这个文件中定义入口。下面展示配置方式。
1 spring的配置
此处配置了spring的ApplicationContext对象和session懒加载的监听器
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
classpath:applicationContext*.xml
OpenSessionInViewFilter
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
OpenSessionInViewFilter
*.action
2 struts拦截器的配置
struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
struts2
/*
3 数据初始化监听器
cn.itcast.oa.listener.InitServletContextListener
5.1.2 Struts的环境配置
Struts.xml文件中主要配置的是各个模块中的所请求的action的映射关系,以及本系统设置的几个全局拦截器。
/WEB-INF/jsp/roleAction/list.jsp
/WEB-INF/jsp/roleAction/addUI.jsp
/WEB-INF/jsp/roleAction/editUI.jsp
/WEB-INF/jsp/roleAction/setPrivilegeUI.jsp
roleAction_list
5.1.3 数据库连接及初始化数据
在spring环境中,可以设置dataSourse属性用于数据库的连接,为了松耦合,本系统并未将数据库连接写进spring配置文件中,为而是独立写在一个属性文件中,在spring文件中使用导入的方式,将属性文件中的连接关键属性引入。
1 spring配置文件的引入方式
2 数据库连接属性文件
jdbcUrl= jdbc\:SQL Server\:///rxq
driverClass= com.SQL Server.jdbc.Driver
username= root
password= 123
5.1.4初始化监听器
在一个系统初始化阶段,需要一些必备的数据,例如管理员账号的设置,以及系统基本的菜单权限的设置等。本监听器实现的就是这个功能,在服务器启动期间,对系统进行初始化,设置菜单权限,建立管理员账户。
public void contextInitialized(ServletContextEvent sce) {
ServletContext application = sce.getServletContext();
// 得到Service的实例对象
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(application);
PrivilegeService privilegeService = (PrivilegeService) ac.getBean("privilegeServiceImpl");
// 准备所有顶级权限的集合(顶级菜单)
List topPrivilegeList = privilegeService.findTopList();
application.setAttribute("topPrivilegeList", topPrivilegeList);
System.out.println("-- 已准备好顶级权限的数据 --");
// 准备所有权限URL的集合
List allPrivilegeUrls = privilegeService.getAllPrivilegeUrls();
application.setAttribute("allPrivilegeUrls", allPrivilegeUrls);
System.out.println("-- 已准备好所有权限的URL数据 --");
}
5.1.5控制层基础搭建
控制层是应用程序和页面前台交互的第一层。对于有开发经验的开发者而言,控制层的结构决定了与页面交互的简便性。一个合理的控制层结构,能有效减少对于重复请求的处理代码,进而达到应用程序的简洁性,也能提高开发效率。本系统为此设计了baseAction以及其之类,分析请求的相似性,对常用请求进行封装压缩。在处理请求时即很好的实现了代码复用,又实现了松耦合。
1 在baseAction中获取当前系统用户,以便在整个系统的请求action中都能在其作用域内。
/**
* 获取当前登录的用户
*
* @return
*/
protected User getCurrentUser() {
return (User) ActionContext.getContext().getSession().get("user");
}
2 分页属性
// 页码默认为第1页
protected int pageNum = 1;
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
3 所以的业务逻辑实体在baseAction中定义,并采用spring注入方式初始化。
//定义service的
@Resource
protected RoleService roleService;
@Resource
protected DepartmentService departmentService;
@Resource
protected UserService userService;
@Resource
protected PrivilegeService privilegeService;
4 创建ModelDrivenBaseAction 继承子baseAction,在ModelDrivenBaseAction中采用泛型方式生成各个业务逻辑中不同的业务实体。
public abstract class ModelDrivenBaseAction extends BaseAction implements ModelDriven {
protected T model;
public ModelDrivenBaseAction() {
try {
// 得到model的类型信息
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
Class clazz = (Class) pt.getActualTypeArguments()[0];
// 通过反射生成model的实例
model = (T) clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public T getModel() {
return model;
}
}
5.1.6持久层基础搭建
持久层是应用程序和数据库交互的桥梁,所有的业务逻辑在这一层次实现对数据库表的操作。本系统的持久层采用hibernate框架作为介质。为了方便使用持久层,本系统为持久层设计了同样的baseDao类,其余所有dao接口皆实现与这个公用的接口,实现接口中的方法。在不同模块中,有相似的操作动作,即可以使用接口中的方法实现,避免了在各个子模块中写入相似性很大的代码。
BaseDaode 实现:
void save(T entity);
void delete(Long id);
void update(T entity);
T getById(Long id);
List getByIds(Long[] ids);
List findAll();
PageBean getPageBean(int pageNum, HqlHelper hqlHelper);
}
不难发现,在baseDao中设计的接口,都是各个模块中经常性使用的。在设计接口的时候,采用泛型设计,通配兼容各个子模块。
5.1.7应用程序各请求基本入口部署
本系统在应用程序入口层设置一个全局的HomeAction,用于接收布局信息。分别对应页面框架布局中的顶层、左边栏、右边栏以及底层的框架。
public String index() throws Exception {
return "index";
}
public String top() throws Exception {
return "top";
}
public String bottom() throws Exception {
return "bottom";
}
public String left() throws Exception {
return "left";
}
public String right() throws Exception {
return "right";
}
5.2 系统实现界面描述
5.2.1 密码MD5加密
MD5是目前市场上比较流行和安全的加密方式。为了系统的安全性,避免使用明文密码。本系统采用对用户密码进行MD5加密后保存在数据库中。
String passwdMD5 = DigestUtils.md5Hex("1234");
model.setPassword(passwdMD5); // 默认密码为1234,应使用MD5摘要
在以上的实现中,对明文密码进行加密,然后将加密后的密码保存于数据库中。在用户登录的时候,也是将用户传过来的页面明文密码进行加密后与数据库密码比对。
5.2.2 用户登录密码校验
用户登录的时候,从页面输入明文密码,后台接收明文密码。在与数据库密码校验的时候,先对明文密码MD5加密后与数据库密码比对,得出结果。
public User getByLoginNameAndPassword(String loginName, String password) {
return (User) getSession().createQuery(//
"FROM User u WHERE u.loginName=? AND u.password=?")//
.setParameter(0, loginName)//
.setParameter(1, DigestUtils.md5Hex(password))// 要使用MD5的摘要
.uniqueResult();
}
图5-1系统用户登录的实现界面图
图5-2系统登录的流程图
5.2.3管理员功能模块描述
管理员成功登陆以后可以进行学生管理、自行车管理、订单管理、类型管理。
图5-3管理员功能列表图
图5-4系统用户管理界面图
图5-5自行车管理实现界面图
图5-6管理员订单管理界面图
5.2.4前台功能模块描述
学生租户进入系统后就可以查看自行车信息,支持分类查看和搜索查看,
图5-7查看自行车信息
用户在选择好自行车进行租赁时需要输入租用日期和归还日期,方便管理员管理,同时系统会自动计算租金价格。
如下图所示为车辆租用的界面:
图5-8车辆租用的界面
用户的租车详细信息会在我的订单中显示出来,如下图是我的订单界面图:
图5-9我的订单的界面
22