- 系统技术选型介绍
2.1 Spring框架简介
Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。
控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。
Spring框架由七个定义明确的模块组成(图1.1)。
正在上传…重新上传取消
图2.1 Spring框架
2.2 Spring Boot框架概述
Spring Boot是一个基于Spring框架的开源Java框架,用于创建独立的、生产级的Spring应用。Spring Boot旨在简化Spring应用的创建和部署。它自动配置Spring和第三方库,使得你可以开始编写应用,而不需要过多地关心配置的问题。Spring Boot的特点包括创建独立的Spring应用、自动配置、嵌入式的Tomcat、Jetty或Undertow来直接创建可运行的应用,以及对生产就绪的特性的提供,如指标、健康检查和外部化配置。
2.3 持久层框架概述
持久层框架是用于管理数据库和应用程序之间交互的工具或技术。它们简化了数据访问和存储的过程,使开发者可以更专注于业务逻辑的编写,而不是数据库查询和交互。在Java世界中,常见的持久层框架包括JPA(Java Persistence API)、Hibernate、MyBatis等。这些框架提供了对象关系映射(ORM),以及数据访问对象(DAO)等功能,从而简化了对数据库的操作。
2.4 RESTful概述
RESTful是一种软件架构风格,主要用于设计网络应用的接口。REST即Representational State Transfer,是一组约束条件和原则,用来设计如何使用HTTP来创建、读取、更新或删除数据。一个RESTful的Web服务通常可以通过一个基于HTTP的接口提供访问。RESTful服务的特点包括无状态性、客户端-服务器结构、可缓存、统一接口等。
2系统设计
校园互助配送快递平台构建是为了满足用户在校园快递物流管理的需求,为更有效合理地构建系统,需要结合用户深入分析各业务,从而完成系统功能建模,初步确定系统各功能内容。本节先对系统用户进行分析,然后结合用户通过用例图,完成业务功能建模。
信息化系统存在不同的用户类型,不同的用户类型的权限不同,系统各功能需要站在用户角度进行分析,所以需要完成系统各用户类型及权限梳理,为后续功能建模做用户类型支撑。基于SSM架构的校园互助配送快递平台可分为四类角色,本节将大致分析各角色类型以及相关权限内容,详细如表所示:
表 2‑1系统角色类型及权限明细表
序号 | 角色类型 | 角色说明 | 角色权限 | 备注 |
1 | 学生用户 | 本网站主要的使用对象和服务对象 | 浏览和查看快递公告、提交快件信息、查看订单信息等内容 | |
2 | 快递用户 | 负责快递物流传输以及数据提交执行用户 | 执行快件出入库和配送,查看快递,创建以及处理快递订单 | |
3 | 龙门镖局用户 | 负责对快递物流进行统筹整合的管理用户 | 对快递配送情况进行统筹管控,查看订单及配送情况 | |
4 | 管理员用户 | 对系统进行系统级别的管理操作 | 对用户进行管理,发布编辑系统公告信息 | 最高权限 |
校园互助配送快递平台系统需要深入了解各用户的应用场景,合理化梳理各用户在不同的业务场景下的需求内容,本节结合各用户类型梳理各业务,完成系统各用户功能建模。
(1)注册登录模块
校园快递物流网站面向的用户较多,尤其面向较大数量的学生用户,其实系统的重要的使用对象,而学生本身具有较高流动性,为更有效地提供相关快递物流信息化服务,本网站为学生用户提供注册功能,学生用户通过注册模块即可完成用户注册。而龙门镖局用户以及快递员用户相对固定,在系统运行过程中会涉及到订单处理内容,因此,不能进行注册,由系统用户进行添加管理。
登录功能则是信息化系统的基本功能模块之一,对用户进行鉴权,并实现用户信息关联以及用户操作关联,为用户提供信息化服务。
注册登录模块的用例图如下图所示:
正在上传…重新上传取消
图 2‑1注册登录模块用例图
(2)用户信息管理模块
校园互助配送快递平台的用户数量较多,用户类型和权限不同,为方便学生用户使用,提升体验感,增加用户粘性,学生用户注册时不需要审核,但在实际的运行过程中,为更更有效对用户进行管控,需要对违反用户管理要求的用户或者冗余无效用户进行删除管理。另一方面,用户管理模块还可以协助用户进行密码重置等操作。
用户管理用户面向系统管理用户进行设计,实现本系统的用户的有效管控,其用例图如下图所示:
正在上传…重新上传取消
图 2‑2用户管理模块用例图
(3)快递订单信息管理模块
订单是校园快递物流管理的基本载体,每个订单对应着一个快件,记录着每个快件的流转情况以及收发情况。订单管理是本系统网站的重要功能模块。
订单管理模块面向系统各用户设计,不同用户的在订单管理模块中处理的业务不同。学生用户在订单管理模块中进行订单查询、订单下单创建等操作,而快递员用户则可以进行订单查询、订单处理、订单创建操作,龙门镖局用户则可以进行订单查询操作,系统管理用户可进行订单查询操作。
订单管理模块用例图如下图所示:
正在上传…重新上传取消
图 2‑3订单管理模块用例图
(4)代取件信息管理模块
针对校园快递物流中,存在代取件的情况,本校园互助配送快递平台系统为用户创建代取件模块,支撑代取件信息化管控需求。学生用户可进行代取件管理操作,包括送货管理、代取件信息管理、代取件信息添加以及代取件在线接单等操作。代取件的用户范围较广,为了进一步提升代取件的服务效率和服务质量,代取件还为用户提供评价的功能,用户可以对代取件的用户进行评价,完成对代取件服务评价闭环。代取件信息管理模块面向学生用户进行设计,代取件模块用例图如下图所示:
正在上传…重新上传取消
图 2‑4代取件模块用例图
(5)快递用户管理模块
快递用户在本系统应用中占据重要地位,其使用频次较高,角色和用户相对稳定,在现实的快递物流管理过程中,直接接触到大量的快递物流内容,为确保快递用户的信息真实可靠,实现快递用户有效管控,快递用户信息由系统管理用户进行添加以及编辑。
快递用户管理针对系统管理用户进行设计,实现对快递用户管控,快递用户管理模块的用例图如下图所示:
正在上传…重新上传取消
图 2‑5快递用户管理模块用例图
(6)公告管理模块
为了更高效通知系统内各用户重要信息,校园快递物流网站需要构建起相关公告管理平台,及时推送重要的公告消息。公告消息涵盖了重要的快递变动情况、快递异常情况以及重要公告内容。
公告管理模块主要针对系统管理用户进行公告信息发布,包括公告编辑、公告查询,而其他用户可进行公告浏览。
公告管理模块用例图如下图所示:
正在上传…重新上传取消
图 2‑6公告管理模块用例图
(7)龙门镖局信息管理模块
龙门镖局与快递用户存在着一定差异,龙门镖局是校园内的专属快递配送机构,接收学生用户订单及配送。在详细的信息管理内容上存在着不同,为了有效区分,构建龙门镖局信息管理模块,专门进行相关信息管理。
龙门镖局信息管理模块用例图如下图所示:
正在上传…重新上传取消
图 2‑7龙门镖局信息管理模块用例图
(8)龙门镖局代取件管理模块
龙门镖局作为校园专门的配送机构,负责接收和处理用户配送请求以及代收取件请求,其自身具有一定专业性,在代取件场景下发挥更重要的作用。在龙门镖局代取件管理模块中,龙门镖局用户可进行代取件送货管理以及我的代取件信息管理两部分内容,本模块针对龙门镖局用户进行设计,其模块用例图如下图所示:
正在上传…重新上传取消
图 2‑8龙门镖局代取件管理模块用例图
(9)反馈管理模块
校园互助配送快递平台系统运行过程中,可能存在一些关于系统运行情况以及快递流转情况的疑问,作为最高权限的管理用户可对全局运行拥有更深的了解。为了提高系统内各用户的使用感知,本系统构建反馈管理功能模块,构建起用户与系统管理用户沟通反馈的桥梁。用户可通过本模块进行信息反馈,而管理用户则可通过本模块进行回复。
反馈管理模块的用例图如下图所示:
正在上传…重新上传取消
图 2‑9反馈管理模块的用例图
(10)管理员用户管理模块
管理员用户同样存在着相关用户管理的需求,在此不展开赘述,系统管理用户模块用例图如图2-10所示:
正在上传…重新上传取消
图 2‑10系统管理用户模块用例图
管理员
1用户,管理员,快递员管理。
1.1查看:分页查看所有信息
1.2基本操作:涉及信息的增,删,改等基本操作
1.3查询:根据ID搜索。
2订单,代取件订单管理
1.1查看:分页查看所有信息
1.2基本操作:增,删,改等基本操作
1.3查询:根据ID搜索订单
3公告信息管理
3.1查看公告:分页查看所有公告
3.2发布公告:发布新的公告,所有人可见
4反馈管理
3.1查看反馈:分页查看所有反馈信息
快递员
1创建订单:创建新入库的订单,用户可见
2基本操作:涉及订单的删、改等基本操作
3查看公告:查看公告的详细信息
龙门镖局
1 查看订单:分页查看所有订单信息
2 配送订单:点击配送按钮,完成配送
3查看公告:查看公告的详细信息
用户
1 代取件订单
1.1查看信息:分页查看自己的代取件订单。
1.2发布代取件订单:创建新的代取件订单
1.3接单:接取他人发布的代取件
1.4打分:对完成的代取件订单进行打分,评分过低
1.5评价:对完成的代取件订单进行评价
2其他
2.1查看订单:分页查看自己的代取件订单。
2.2查看公告:查看公告的详细信息
2.3发布反馈:发布仅有管理员可见的反馈
校园物流网站主要是针对校园快递最后一公里的配送问题研发的,实现了取件快速认证身份,校内快递送货上门快速下单等,方便学生取快递的过程。
本系统的用户类型较多,不同用户的功能操作业务不同,为了提升用户体验,在用户访问时,通过CAS权限控制技术,实现不同用户访问的不同的用户界面,避免用户超越权限访问内容,减少用户误操作。因此,本系统将分为三个用户界面,分别为管理员模块界面,快递模块界面和用户模块界面。管理员可以对其他用户和订单进行管理。管理员和用户可以进行登录后并使用网站。
功能模块结构图如图所示。
正在上传…重新上传取消
图 2‑11模块结构图
数据库:MySQL
服务器:Tomcat6.0
开发软件:MyEclipse8.6
Jdk:Java1.6
-
- E-R图设计
在该系统中,管理员管理快递员与用户,发布公告。快递员配送订单后,用户接受订单后可以发布代取件订单,一个用户可以发布或接取多个订单。具体E-R图如下图所示。
正在上传…重新上传取消
图 2‑12 E-R图
上面的E-R图中,1:1和1:n代表了数据库表之间1对1和1对多的关系。展示了管理员可以对各个用户进行管理,快递员可以配送订单,用户收到订单后可以发布代取件订单也可以进行向龙门镖局下单。管理员可以发布公告,而用户可以发布反馈。
根据系统需求和各模块功能设计,在数据库设计中,设计了张数据表,分别为权限系统8张,分别为管理员、快递员、用户和龙门镖局。设计订单、代取件订单表和龙门镖局订单各1张,以及公告表、反馈表各1张。由于该互助配送快递平台后续还会有更多功能和模块,因此在表的设计中还需要保证它的可扩展性。
数据库的E-R图设计后,就可以将上面的数据库概念转化为实际数据模型,及数据库的逻辑结构。
数据库实体属性和字段属性如下图所示。
(1)管理员表存放管理员信息,如下表所示。
表 2‑2管理员表
名称 | 类型 | 长度 | 是否允许空 | 是否主键 |
id | int | 11 | 否 | 是 |
username | varchar | 50 | 是 |
|
userpwd | varchar | 50 | 是 |
|
identity | varchar | 50 | 是 |
|
(2)快递员表存放各站点的工作人员信息,如下表所示。
表 2‑3快递员表
名称 | 类型 | 长度 | 是否允许空 | 是否主键 |
id | int | 11 | 否 | 是 |
loginname | varchar | 50 | 是 | |
pwd | varchar | 50 | 是 | |
realname | varchar | 50 | 是 | |
address | varchar | 50 | 是 | |
sex | varchar | 50 | 是 | |
tel | varchar | 50 | 是 | |
age | int | 11 | 是 | |
zhiwei | varchar | 50 | 是 | |
xueli | varchar | 50 | 是 | |
bumen | varchar | 50 | 是 | |
status | varchar | 50 | 是 |
(3)用户表存放使用该网站系统的用户信息,如下表所示。
表 2‑4用户表
名称 | 类型 | 长度 | 是否允许空 | 是否主键 |
id | int | 11 | 否 | 是 |
loginname | varchar | 50 | 是 |
|
pwd | varchar | 50 | 是 |
|
realname | varchar | 50 | 是 |
|
address | varchar | 50 | 是 |
|
sex | varchar | 50 | 是 |
|
tel | varchar | 50 | 是 |
|
age | int | 11 | 是 |
|
(4)代取件订单表存放代取件订单信息,如下表所示。
表 2‑5代取件订单表
名称 | 类型 | 长度 | 是否允许空 | 是否主键 |
id | int | 11 | 否 | 是 |
orderno | varchar | 50 | 是 |
|
content | varchar | 500 | 是 |
|
userid | int | 11 | 是 |
|
content | varchar | 500 | 是 |
|
username | varchar | 50 | 是 |
|
userphone | varchar | 50 | 是 |
|
shijian | varchar | 50 | 是 |
|
status | int | 11 | 是 |
|
yname | varchar | 50 | 是 |
|
yphone | varchar | 50 | 是 |
|
yid | int | 11 | 是 |
|
pingjia | varchar | 50 | 是 |
|
pingjia2 | varchar | 50 | 是 |
|
pingfen | int | 11 | 是 |
|
pingfen | int | 11 | 是 |
|
(5)公告表存放公告内容标题等信息,如下表所示。
表3- 1公告表
名称 | 类型 | 长度 | 是否允许空 | 是否主键 |
id | int | 11 | 否 | 是 |
biaoti | varchar | 255 | 是 |
|
neirong | varchar | 8000 | 是 |
|
shijian | varchar | 50 | 是 |
|
type | int | 11 | 是 |
|
(6)快递订单表存放用户收到的订单信息,如下表所示。
表 2‑6快递订单表
名称 | 类型 | 长度 | 是否允许空 | 是否主键 |
id | int | 11 | 否 | 是 |
orderno | varchar | 50 | 是 |
|
userid | int | 11 | 是 |
|
content | varchar | 500 | 是 |
|
username | varchar | 50 | 是 |
|
userphone | varchar | 50 | 是 |
|
shijian | varchar | 50 | 是 |
|
status | int | 11 | 是 |
|
(7)反馈表用来存放用户发布的反馈信息,如下表所示。
表 2‑7反馈表
名称 | 类型 | 长度 | 是否允许空 | 是否主键 |
id | int | 11 | 否 | 是 |
biaoti | varchar | 255 | 是 |
|
neirong | varchar | 8000 | 是 |
|
shijian | varchar | 50 | 是 |
|
userid | int | 11 | 是 |
|
(8)龙门镖局表用来存放龙门镖局工作人员的信息,如下表所示。
表 2‑8龙门镖局表
名称 | 类型 | 长度 | 是否允许空 | 是否主键 |
id | int | 11 | 否 | 是 |
loginname | varchar | 50 | 是 |
|
pwd | varchar | 50 | 是 |
|
tel | varchar | 50 | 是 |
|
zhiwei | varchar | 50 | 是 |
|
status | varchar | 50 | 是 |
|
系统进行详细设计时,需要结合各功能模块内容,进行相关类设计,包括了控制类、接口类和实体类等内容。本系统的整体类图如下图4-1所示:
正在上传…重新上传取消
图 3‑1校园快递物流管理系统整体类图
本系统模块设计了管理员管理AdminUserAddit、学生用户信息管理StudentUserAddit、龙门镖局信息管理LongmenEscortUserAddit和快递用户管理CourierUserAddit四个针对不同用户的管理模块,在实际类设计上,通过继承成员编辑类,实现对相关用户管理类的快速设计和实现,而不同的用户编辑类由于用户的编辑的内容不同,有相应的私有类支撑相关编辑,用户基本信息数据由用户数据实体类UserMessage进行保存,在完成用户编辑后,通过用户数据库的数据接口UserDatabaseInterface,实现对用户数据编辑后的数据进行更新同步。
系统整体的控制由主控制类CampusExpressmain实现对系统各功能模块控制,其检测用户输入的操作指令以及数据,调用及触发各功能模块,实现其功能的调用实现。公告管理类由NoticeCotrol进行控制,与公告实体类以及公告编辑接口,共同完成对系统公告的处理。在此各类就不一一展开论述。
用户登录,涉及到界面和数据库操作。用户登录时需到数据库中进行匹配,成功则可以进入网站页面。
用户登录时序图如下图所示。
正在上传…重新上传取消
图 3‑2用户登录时序图
用户发布代取件订单时序图。用户代取件列表,页面会自动加载出用户已发布的代取件订单。用户可以搜索自己的代取件订单,如果尚未发布,可以点击添加,进入代取件页面,填写完成后,出现新的代取件订单信息。用户发布代取件订单时序图如图4.3所示。
正在上传…重新上传取消
图 3‑3用户查看代取件订单时序图
快递员添加订单后,用户可以看到自己的订单。用户取件后,快递员和用户都可以看到订单状态变为已取件。取件时序图如下图所示。
正在上传…重新上传取消
图 3‑4订单查看时序图
用户发布订单后,其他用户可以查看并接单,接单后该订单变成已接单状态。发布订单的用户做收货评价后,另一方也可评价。接单时序图如下图所示。
正在上传…重新上传取消
图 3‑5接单时序图
由于该系统为互助配送快递平台,为保证系统的安全性,用户需登录后方可进行操作。未注册用户需进行注册,用户的登陆流程图如下图所示。
用户时需选择用户身份,如未注册则需注册后则登录,用户登录后可以进行代取件、订单模块的操作。
正在上传…重新上传取消
图 3‑6用户登陆流程图
管理员无需且不能注册,只能由其他管理员添加。管理员需对用户进行管理,添加快递员以及其他管理员,并发布公告。其登录流程图如下图所示。
正在上传…重新上传取消
图 3‑7管理员登录流程图
各校园快递站点需要对订单进行管理,需要检查订单并与实际比对。
快递员配送快递到站点后,站点收到快递,确认订单后,快递入库以方便取件,然后创建并发布订单。如果在发现订单出现问题,可以对订单进行修改。同时会向用户发送信息通知。用户可以登录查看自己的订单,并前去取件。在每晚工作结束后,会再次检查所有的订单,尤其是未完成的订单,对需要调整编号及描述的订单进行调整。
其管理流程图如下图所示。
正在上传…重新上传取消
图 3‑8站点管理流程图
由于校园快递中快递员不可以送货上门,所以所有快递都会先配送至校园取件点,再由学生前去取件。取件点如菜鸟驿站等接受快递,编号入库,并在快递架上归置整齐。学生收到快递信息后前去取件点验证身份后收取快递并确认收货。进行评价后流程结束。流程图如下图所示。
正在上传…重新上传取消
图 3‑9普通用户取件流程图
代取件用户前往菜鸟驿站取件的流程同上图,完整代取件流程如图4-10所示。
正在上传…重新上传取消
图 3‑10用户代取件流程图
搭建基于SSM的互助配送快递平台首先需要搭建SSM环境。Spring MVC 用于 Web 层,相当于 Controller,处理请求并作出响应;MyBatis 作为持久层的框架,可以自由的控制 SQL,更加简捷地完成数据库操作;Spring 的依赖注入可以减少代码的耦合,可以装配 Bean,另外其 AOP、事务管理尤其方便,同时,Spring 可以将各层进行整合。SSM框架相比于SSH更轻量灵活,也更符合敏捷开发的需求。[13]
在设计并建立数据库后,首先建立了所需的包并导入了项目所用的jar包。框架结构图如下图所示。
正在上传…重新上传取消
图 4‑1项目结构图
首先需要下载相应的jar包,除了这三大框架所需的jar包外,还需要一些框架中jar包依赖的jar包,以及一些插件所需要的jar包。
在com.gssm.entity中建立了所需的实体类,并自建get和set方法,以及构造方法。接下来配置mybatis文件。
Mybatis的XML映射文件在com.gssm.sqlmap包中,以UserMapper.xml为例,其中的
<!--
1.方法描述:删除数据
2.参数:主键id
-->
<delete id="delete" parameterType="java.lang.String">
delete from t_user where id=#{id}
</delete>
这个语句被称为delete,接受一个java.lang.String类型的参数,无返回值。MyBatis的强大特性之一便是动态MySQL,在UserMapper中同样提供了可以根据不同条件搜索的语句,这使得管理员通过不同关键字来搜索用户。
<!-- 查询时条件 -->
<sql id="User_where">
<if test="id != null" >
and id = #{id}
</if>
<if test="loginname != null" >
and loginname = #{loginname}
</if>
<if test="pwd != null" >
and pwd = #{pwd}
</if>
<if test="realname != null" >
and realname = #{realname}
</if>
……
</sql>
在mybatis配置文件中,指定了com.gssm.Entity的别名。且为了方便, 使用了PageHelper插件,并在mybatis-config.xml中进行配置。
接下来进行spring的配置。
<!-- 自动扫描 -->
<context:component-scan base-package="com.gssm.dao" />
<context:property-placeholder location="classpath:jdbc.properties"/>
配置数据库链接核心代码如附录1所示,数据库的名字是db_ssmwuliumm_g。
进行Spring和Mybatis的整合。配置SqlSessionFactory的代码如下。
<!-- 创建SqlSessionFactory,同时指定数据源 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
日志文件
log4j.properties
# Direct log messages to console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
# Root logger option
log4j.rootLogger=debug,console
下面整合SpringMVC。
<context:component-scan base-package="com.gssm.controller" />
在xml中配置后,spring可以自动去扫扫描base-package指定下的有@Controller下的java类,并注册成bean。
开启了SpringMVC的注解模式。
<!-- 扩充了注解驱动,可以将请求参数绑定到控制器参数 -->
<mvc:annotation-driven/>
加入对静态资源的处理。
<!-- 当在web.xml 中 DispatcherServlet使用 <url-pattern>/</url-pattern> 映射时,能映射静态资源 -->
<mvc:default-servlet-handler/>
<!-- 静态资源映射 -->
<mvc:resources mapping="/static/**" location="/WEB-INF/static/"/>
配置jsp。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>
用户登录功能是采用form提交的形式进行登陆验证,在输入用户名和密码后,通过form的post,提交方式,提交到服务器端,服务器端接受到数据,在数据库中查找,查找出这个用户,登录成功,如果查询出来没有,登录失败。
登录界面如下图所示。
正在上传…重新上传取消
图 4‑2登陆界面
用户登录功能主要代码见附录2。
登录后,通过usertype属性,判断显示的是哪个界面。
<c:if test="${sessionScope.userType==1}">
如该行代码中userType=1则是管理员登录。
环境搭建时,com.gssm.entity中建立User.java包,并对数据库进行了连接。
下面创建sql映射文件,
<mapper namespace="com.gssm.entity.User">
<!-- 实体类与数据库映射字段部分 start -->
配置resultMap属性,进行表字段类与实体类的映射。
<resultMap id="ResultMapUser" type="com.gssm.entity.User">
<result property="id" column="id"/>
……
</resultMap>
<!-- 实体类与数据库映射字段部分 end -->
下面声明数据库字段,用于后续的MyBatis的动态查询。
<!-- 声明数据库字段 -->
<sql id="User_field">
<!--判断是否是最后一个元素,如果不是最后一个添加,-->
id,
……
</sql>
<!-- 实体类属性 -->
<sql id="User_insert">
<!--判断是否是最后一个元素,如果不是最后一个添加,-->
#{id},
#{loginname},
……
</sql>
#{id}告知MyBatis创建一个预处理语句参数,可以节省时间以及防止SQL注入,提升安全性。
下面就可以进行添加。
<insert id="insert" parameterType="com.gssm.entity.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO t_user (
<include refid="User_field" />
) VALUES (
<include refid="User_insert" />
)
</insert>
其中用户的id或者说主键为自动生成。<include refid =” ”>则是为了使sql语句较为简洁。
删除则是直接根据用户id即主键删除。
<delete id="delete" parameterType="java.lang.String">
delete from t_user where id=#{id}
</delete>
查询同样相同。
<select id="load" resultMap="ResultMapUser" parameterType="java.lang.String">
select <include refid="User_field" />
from t_user
where id=#{id}
</select>
下面在com.gssm.dao中建立BaseDaoImpl.java。
public int insert(T entity) {
return this.getSqlSession().insert(getClz().getName()+".insert",entity);
}
写UserController.java,连接页面请求和服务层。
@RequestMapping(value = "/list.action")
public String list(User user, Model model, HttpServletRequest request, HttpServletResponse response, HttpSession session) {
Pager<User> pagers = userDao.findByEntity(user);
model.addAttribute("pagers", pagers);
return "admin/user/user_list";
最后编写jsp页面调用。
用户信息后台管理模块对用户信息进行管理,包括删除,添加查询等操作,界面如图5.3所示。
正在上传…重新上传取消
图 4‑3用户管理
添加界面如下图所示。
正在上传…重新上传取消
图 4‑4用户信息添加
快递订单管理模块可以对快递订单在线下载功能,在线删除、修改,界面如下图所示。
正在上传…重新上传取消
图 4‑5订单界面
快递人员管理是对物流的种类信息进行管理,如下图所示。
正在上传…重新上传取消
图 4‑6用户管理界面
-
- 代取件信息管理
在校园中,经常遇到,今天的课程全在南区,但快递却在北区的菜鸟驿站,一来一回要花费半小时。以及,有些时候,学生会收到一些非常重的快递,但并不是每次都能找到同学来搬。在这种情况下开发了代取件功能。
用户收到菜鸟驿站的快递短信通知后,登陆网站,写上自己的快递基本信息,如大概重量,以及自己的宿舍楼层,以及报酬等,愿意接单的其他用户会在进入网站时看到此条信息,接单并联系送货的时间。在送达后会进行互相评分并进行评价。
查看代取件订单时如下图所示
正在上传…重新上传取消
图 4‑7代取件查看界面
下单代取件时如下图所示。
正在上传…重新上传取消
图 4‑8代取件下单界面
其主要实现代码如下所示
当该代取件订单无人接单时,用户接单。用户接单时触发dqordedit事件,将代取件数据库中的代取人id修改为接单者的id。用户可凭借此代取件订单前去站点进行代取件。
<c:if test="${sessionScope.userType == 2 && Dqorder.status == 0 && Dqorder.userid != sessionScope.user.id}">
<button type="button" class="btn btn-info btn-xs" οnclick="DqorderEdit(${Dqorder.id})"><span class="icon-edit text-blue"></span>接单</button>
管理员可以发布或修改公告,所有用户可见。公告管理界面如下图所示。
正在上传…重新上传取消
图 4‑9公告管理界面
分页功能的使用会使得界面更加友好,而自己写分页功能时,效率较低,故采用了mybatis的PageHelper插件。
首先引入jar包并在mybatis-config.xml中进行参数配置,
<plugin interceptor="com.gssm.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
引入后开始进行分页功能的实现。
以UserMapper.xml为例,定义了sql标签后,添加如下方法
<!--
1.方法描述:查询分页。
2.参数:实体类
-->
<select id="findByEntity" resultMap="ResultMapUser" parameterType="com.gssm.entity.User">
select <include refid="User_field" />
from t_user where 1=1
<include refid="User_where" />
order by id desc
</select>
下面在service层中添加分页的接口(BaseDaoImpl.java)。
接口类
public Pager<T> findByMap(Map<String, Object> params) {
return findByMap(getClz().getName()+".findByMap", params);
}
实现类代码在附录3。
下面是要在前台展示分类结果。
在上文进行分页查询后,将结果以json方式传至前台,前台生成表格。添加json的依赖包后,在Controller中建立基类将数据转至json。然后对spring-mvc和spring中进行配置。[14]
编写controller层
/**
* 分页查询 返回list json(通过对象)
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/findByObj.json", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST)
@ResponseBody
public String findByObjByEntity(User user, Model model, HttpServletRequest request, HttpServletResponse response) {
// 分页查询
Pager<User> pagers = userDao.findByEntity(user);
JSONObject jsonObject = JsonUtil2.getJsonObject();
jsonObject.put("pagers", pagers);
jsonObject.put("obj", user);
return jsonObject.toString();
最后编写前台页面文件。
通过规范化严格的系统测试,制定合理科学的测试用例,充分测试系统各子模块及整体的运行情况及运行性能效果,对存在的问题进行科学的修复,直至系统能够满足各项需求,达到上线实施的要求。
系统测试需要利用科学的方法和流程执行系统测试,首先需要充分了解系统情况和测试周期要求,合理化制定本系统的测试计划,然后针对性制定测试用例,有序分批次地展开系统功能测试以及性能测试,对存在问题进行修复迭代,直至各项测试结果满足系统所需。在测试系统功能运行效果时,主要采用黑盒测试,根据预期的运行要求,输入相关测试用例,比较最后输出与预期输出是否一致,从而判别该功能是否满足要求。在测试系统性能时,采用白盒测试方法,已知系统的功能满足要求,通过多次测试,获得其运行性能,从而判定其运行性能是否达到系统要求。。
选择的测试环境为:
- 操作系统:Windows10
- 软件:IDEA8.6
- 服务器:Tomcat6.0
根据系统详细设计,设计了如下表所示的功能测试表。
表 5‑1功能测试表
正在上传…重新上传取消
根据对系统各个模块进行功能测试,系统运行正常,基本满足系统详细设计的功能要求。
在权限管理中,管理员可以对用户进行管理,也可以创建新的管理员,用户登录系统后受到权限限制,保证了系统的安全性。
订单管理模块中,站点可以创建订单,用户可以查看订单,方便用户了解自己的快递情况。
代取件模块方便学生用户在较忙的时候请求龙门镖局或其他用户代拿快递,极大地方便了学生生活。
此外,系统对一些错误的输入都能识别,具有较高的安全性,可以投入使用。
基于SSM框架的校园互助配送快递平台系统的性能测试达到了起初的设计要求,在系统用户数达到100,并发用户数达到20时,一般浏览数据页面的时间小于3秒,用户注册等内容提交时间小于4秒,快件处理数据更新的时间小于10秒,用户登录小于2秒,公告信息提交发布时间小于5秒。
表 5‑2性能测试规格表
参数项目 | 技术参数 | 技术参数要求 |
1、项目规模 | 系统用户数 | >100 |
并发用户数 | >20 | |
2、响应时间 | 一般浏览数据页面 | <3秒 |
快件处理数据更新 | <10秒 | |
用户注册等内容提交 | <4秒 | |
用户登录 | <2秒 | |
公告信息提交发布 | <5秒 |
在功能测试方面,经过多轮迭代测试,对各轮测试的功能实现问题进行针对性修复,在第三轮测试及迭代后,系统功能趋于完善,能够达到系统对功能的各项要求,满足系统功能需求。
在性能测试方面,通过模拟并发式用户访问,系统各模块可有效的承载相应的访问量,并得到预期的性能结果,满足系统的性能需求。
综上所述,本系统通过了本轮测试,可执行相关系统部署,准备推动上线实施。
本章遵循软件系统测试规范,确立测试目的和测试方法,,有针对性的制定测试用例,并分别采用黑盒测试和白盒测试进行系统功能测试和性能测试。在功能测试过程中,经过多轮的系统迭代和回归测试,系统各功能模块都达到了预期要求,满足系统功能需求。在性能测试中,通过模拟访问,有效测试出本系统的各项功能承载及响应能力,其同样也满足预期的性能需求。基于SSM框架的校园互助配送快递平台系统通过了本轮系统测试,将进行系统部署,推动上线实施。
结论
虽然本网站的开发已经趋近完成,但是仍有很多地方需要修改及完善,让系统更加完美。
(1)与各个校园的管理系统对接,以求能够更好地进行用户管理,使得收取配送流程更加方便。
(2)建立对快递员更加系统的管理,并优化配送流程以提高配送效率。
这门课程设计给了我一个很好的锻炼机会,提高了用学过的知识技能来解决实际问题的能力,对SSM框架等技术有了更深的了解。
由于基础不牢,实际进度与预估相差甚远,常常困于一些简单的问题中。在制作过程中受到了很多老师同学的帮助,最终完成了项目。
我最大的体会是软件的需求分析非常重要,由于本网站并未投入使用,有许多本来设计的功能无法完成,从而打乱了脚步。以及遇到困难绝不放弃,同时善于查找资料或请教前辈。这样就能更快地掌握所需的知识。
参考文献
[1] 校园快递行业发展报告(2016)[EB/OL].
http://b2b.toocle.com/detail--6364227.html.
[2] 刘仁军,何锌,汪琪. 武汉高校校园快递服务现状调查分析[J].物流工程与管理,2015,37(03):145-150.
[3] 徐伟.基于模糊综合评价的校园快递服务质量研究[J].物流工程与管理,2015,37(07):70-74.
[4] 李淑艳,黄浩文,林森茂. 高校校园快递“最后一公里”配送现状与对策研究——以广东交通职业技术学院为例[J]. 物流科技,2016,39(08):36-37.
[5] 李嘉冀,柴菁敏.浅谈校园快递物流现状及未来发展[J/OL].现代营销(下旬刊),2017(11):226-227.
[6] 李海东,马达威. 校园快递“最后一公里”配送现状调查分析[J]. 经济研究导刊,2017(31):40-42.
[7] 朱艾,冯耀东,李莉. 高校校园快递服务模式问题及改进策略[J]. 商场现代化,2017(21):64.65.
[8] 常青平. 校园快递存在问题及新模式探讨[J]. 物流科技,2014,37(11):136-137.
[9] 宁鹏飞,黄堯群,廖王雨. 浅析高校快递包装回收状况及解决方案——以广州工商学院为例[J]. 价值工程,2017,36(26):101-102.
[10] SSH和SSM对比总结[EB/OL]
www.w3school.com.cn/tags/tag_term_hypertext.asp.
[11] (英国)福塔.MySQL必知必会[M].刘晓霞,钟鸣.北京:人民邮电出版社,2009.
[12] MyBatis 分页插件 - PageHelper [EB/OL]
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md/Mybatis-PageHelper/blob/master/README_zh.md
[13]王进.B/S 模式下的三层架构模式[J].软件导刊,2011,10(03):30-31.
[14] SSM 框架——详 细 整 合 教 程 ( Spring+SpringMVC+MyBatis ) [EB/OL].http://blog.csdn.net/gebitan505/article/details/44455235/.
[15] 赵瑞莲.软件测试[M].北京:高等教育出版社
链接数据库核心代码
<!-- 自动扫描 -->
<context:component-scan base-package="com.gssm.dao" />
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置DataSource数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="jdbc:MySQL://localhost:3306/db_ssmwuliumm_g?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
登录功能核心代码,以用户登录为例。
if (userType == 0)//
{
Admin admin = new Admin();
admin.setUsername(userName);
admin.setUserpwd(userPw);
Pager<Admin> pagers = adminDao.findByEntity(admin);
if (pagers.getTotal() == 0) {
request.setAttribute("msg", "用户名或者密码错误!");
return "login";
} else {
admin = (Admin) pagers.getDatas().get(0);
session.setAttribute("userType", 0);
session.setAttribute("admin", admin);
return "admin/index";
}
}
if (userType == 1)//用户登录
{
Yuangong user = new Yuangong();
user.setLoginname(userName);
user.setPwd(userPw);
Pager<Yuangong> pagers = yuangongDao.findByEntity(user);
if (pagers.getTotal() == 0) {
request.setAttribute("msg", "用户名或者密码错误!");
return "login";
} else {
user = (Yuangong) pagers.getDatas().get(0);
session.setAttribute("userType", 1);
session.setAttribute("yuangong", user);
return "admin/index";
}
}
实现类
public Pager<T> findByMap(String sqlId, Map<String, Object> params) {
/**
* 执行分页
*/
Integer pageSize = SystemContext.getPageSize();
Integer pageOffset = SystemContext.getPageOffset();
if(pageOffset==null||pageOffset<0) pageOffset = 0;
if(pageSize==null||pageSize<0) pageSize = 15;
String order = SystemContext.getOrder();
String sort = SystemContext.getSort();
Integer pageNum = null;
if(pageOffset == 0){
pageNum = 1;
}else{
pageNum = pageOffset/pageSize+1;
}
PageHelper.startPage(pageNum, pageSize);
List<T> datas = this.getSqlSession().selectList(sqlId, params);
Pager<T> pages = new Pager<T>(datas);
return pages;
}