我的项目概述、环境搭建
课程内容
- 软件开发整体介绍
- 天穹外卖我的项目介绍
- 开发环境搭建
- 导入接口文档
- Swagger
我的项目整体成果展现:
治理端 - 外卖商家应用
用户端 - 点餐用户应用
当咱们实现该项目标学习,能够造就以下能力:
1. 软件开发整体介绍
作为一名软件开发工程师, 咱们须要理解在软件开发过程中的开发流程,以及软件开发过程中波及到的岗位角色,角色的分工、职责,并理解软件开发中波及到的三种软件环境。那么这一大节,咱们将从 软件开发流程、角色分工、软件环境 三个方面整体介绍一下软件开发。
1.1 软件开发流程
1). 第 1 阶段: 需要剖析
实现需要规格说明书、产品原型编写。
需要规格说明书,一般来说就是应用 Word 文档来形容以后我的项目的各个组成部分,如:零碎定义、应用环境、性能规格、性能需求等,都会在文档中形容。例如:
产品原型,个别是通过网页 (html) 的模式展现以后的页面展现什么样的数据, 页面的布局是什么样子的,点击某个菜单,关上什么页面,点击某个按钮,呈现什么成果,都能够通过产品原型看到。例如:
2). 第 2 阶段: 设计
设计的内容蕴含 UI 设计、数据库设计、接口设计。
UI 设计:用户界面的设计,次要设计我的项目的页面成果,小到一个按钮,大到一个页面布局,还有人机交互逻辑的体现。例如:
数据库设计:须要设计以后我的项目中波及到哪些数据库,每一个数据库外面蕴含哪些表,这些表构造之间的关系是什么样的,表构造中蕴含哪些字段。例如:
接口设计:通过剖析原型图,首先,粗粒度地剖析每个页面有多少接口,而后,再细粒度地剖析每个接口的传入参数,返回值参数,同时明确接口门路及申请形式。例如:
3). 第 3 阶段: 编码
编写我的项目代码、并实现单元测试。
我的项目代码编写:作为软件开发工程师,咱们须要对我的项目的模块功能分析后,进行编码实现。
单元测试:编码实现结束后,进行单元测试,单元测试通过后再进入到下一阶段。例如:
4). 第 4 阶段: 测试
在该阶段中次要由测试人员, 对部署在测试环境的我的项目进行功能测试, 并出具测试报告。
5). 第 5 阶段: 上线运维
在我的项目上线之前,会由运维人员筹备服务器上的软件环境装置、配置,配置结束后,再将咱们开发好的我的项目,部署在服务器上运行。
1.2 角色分工
在对整个软件开发流程相熟后,咱们还有必要理解一下在整个软件开发流程中波及到的岗位角色,以及各个角色的职责分工。
岗位 / 角色 | 对应阶段 | 职责 / 分工 |
---|---|---|
项目经理 | 全阶段 | 对整个我的项目负责,任务分配、把控进度 |
产品经理 | 需要剖析 | 进行需要调研,输入需要调研文档、产品原型等 |
UI 设计师 | 设计 | 依据产品原型输入界面效果图 |
架构师 | 设计 | 我的项目整体架构设计、技术选型等 |
开发工程师 | 编码 | 性能代码实现 |
测试工程师 | 测试 | 编写测试用例,输入测试报告 |
运维工程师 | 上线运维 | 软件环境搭建、我的项目上线 |
上述咱们解说的角色分工, 是在一个项目组中比拟规范的角色分工, 然而在理论的我的项目中, 有一些项目组因为人员配置缓和, 可能并没有专门的架构师或测试人员, 这个时候可能须要有项目经理或者程序员专任。
1.3 软件环境
作为软件开发工程师,在编码的过程中就不可避免地会接触多种软件环境,咱们次要来剖析在工作中常常遇到的三套环境,别离是: 开发环境、测试环境、生产环境。接下来,咱们别离介绍一下这三套环境的作用和特点。
1). 开发环境(development)
咱们作为软件开发人员,在开发阶段应用的环境,就是开发环境,个别内部用户无法访问。
比方,咱们在开发中应用的 MySQL 数据库和其余的一些常用软件,咱们能够装置在本地,也能够装置在一台专门的服务器中,这些应用软件仅仅在软件开发过程中应用,我的项目测试、上线时,咱们不会应用这套环境了,这个环境就是开发环境。
2). 测试环境(testing)
当软件开发工程师,将我的项目的功能模块开发结束,并且单元测试通过后,就须要将我的项目部署到测试服务器上,让测试人员对我的项目进行测试。那这台测试服务器就是专门给测试人员应用的环境,也就是测试环境,用于我的项目测试,个别内部用户无法访问。
3). 生产环境(production)
当我的项目开发结束,并且由测试人员测试通过之后,就能够上线我的项目,将我的项目部署到线上环境,并正式对外提供服务,这个线上环境也称之为生产环境。
** 开发环境 ** ** 测试环境 ** ** 生产环境 **
首先,会在开发环境中进行我的项目开发,往往开发环境大多数都是本地的电脑环境和局域网内的环境,当开发结束后,而后会把我的项目部署到测试环境,测试环境个别是一台独立测试服务器的环境,我的项目测试通过后,最终把我的项目部署到生产环境,生产环境能够是机房或者云服务器等线上环境。
2. 天穹外卖我的项目介绍
在开发天穹外卖这个我的项目之前,咱们须要全方位的来介绍一下以后咱们学习的这个我的项目。接下来,咱们将从我的项目简介、产品原型、技术选型三个方面来介绍天穹外卖这个我的项目。
2.1 我的项目介绍
本我的项目(天穹外卖)是专门为餐饮企业(餐厅、饭店)定制的一款软件产品,包含 系统管理后盾 和 小程序端利用 两局部。其中系统管理后盾次要提供给餐饮企业外部员工应用,能够对餐厅的分类、菜品、套餐、订单、员工等进行治理保护,对餐厅的各类数据进行统计,同时也可进行来单语音播报性能。小程序端次要提供给消费者应用,能够在线浏览菜品、增加购物车、下单、领取、催单等。
接下来,通过性能架构图来展现 治理端 和用户端 的具体业务功能模块。
1). 治理端性能
员工登录 / 退出 , 员工信息管理 , 分类管理 , 菜品治理 , 套餐治理 , 菜品口味治理 , 订单治理,数据统计,来单揭示。
2). 用户端性能
微信登录 , 收件人地址治理 , 用户历史订单查问 , 菜品规格查问 , 购物车性能 , 下单 , 领取、分类及菜品浏览。
2.2 产品原型
产品原型,用于展现我的项目的业务性能,个别由产品经理进行设计。
注意事项: 产品原型次要用于展现我的项目的性能,并不是最终的页面成果。
在课程材料的产品原型文件夹下, 提供了两份产品原型。
治理端原型图:
用户端原型图:
1). 治理端
餐饮企业外部员工应用。次要性能有:
模块 | 形容 |
---|---|
登录 / 退出 | 外部员工必须登录后, 才能够拜访系统管理后盾 |
员工治理 | 管理员能够在零碎后盾对员工信息进行治理,蕴含查问、新增、编辑、禁用等性能 |
分类管理 | 次要对以后餐厅经营的 菜品分类 或 套餐分类 进行治理保护,蕴含查问、新增、批改、删除等性能 |
菜品治理 | 次要保护各个分类下的菜品信息,蕴含查问、新增、批改、删除、启售、停售等性能 |
套餐治理 | 次要保护以后餐厅中的套餐信息,蕴含查问、新增、批改、删除、启售、停售等性能 |
订单治理 | 次要保护用户在挪动端下的订单信息,蕴含查问、勾销、派送、实现,以及订单报表下载等性能 |
数据统计 | 次要实现对餐厅的各类数据统计,如营业额、用户数量、订单等 |
2). 用户端
挪动端利用次要提供给消费者应用。次要性能有:
模块 | 形容 |
---|---|
登录 / 退出 | 用户须要通过微信受权后登录应用小程序进行点餐 |
点餐 - 菜单 | 在点餐界面须要展现出菜品分类 / 套餐分类, 并依据以后抉择的分类加载其中的菜品信息, 供用户查问抉择 |
点餐 - 购物车 | 用户选中的菜品就会退出用户的购物车, 次要蕴含 查问购物车、退出购物车、删除购物车、清空购物车等性能 |
订单领取 | 用户选完菜品 / 套餐后, 能够对购物车菜品进行结算领取, 这时就须要进行订单的领取 |
个人信息 | 在集体核心页面中会展现以后用户的根本信息, 用户能够治理收货地址, 也能够查问历史订单数据 |
2.3 技术选型
对于本我的项目的技术选型, 咱们将会从 用户层、网关层、应用层、数据层 这几个方面进行介绍,次要用于展现我的项目中应用到的技术框架和中间件等。
1). 用户层
本我的项目中在构建系统管理后盾的前端页面,咱们会用到 H5、Vue.js、ElementUI、apache echarts(展现图表)等技术。而在构建挪动端利用时,咱们会应用到微信小程序。
2). 网关层
Nginx 是一个服务器,次要用来作为 Http 服务器,部署动态资源,拜访性能高。在 Nginx 中还有两个比拟重要的作用:反向代理和负载平衡,在进行我的项目部署时,要实现 Tomcat 的负载平衡,就能够通过 Nginx 来实现。
3). 应用层
SpringBoot:疾速构建 Spring 我的项目, 采纳 “ 约定优于配置 ” 的思维, 简化 Spring 我的项目的配置开发。
SpringMVC:SpringMVC 是 spring 框架的一个模块,springmvc 和 spring 无需通过两头整合层进行整合,能够无缝集成。
Spring Task: 由 Spring 提供的定时工作框架。
httpclient: 次要实现了对 http 申请的发送。
Spring Cache: 由 Spring 提供的数据缓存框架
JWT: 用于对应用程序上的用户进行身份验证的标记。
阿里云 OSS: 对象存储服务,在我的项目中次要存储文件,如图片等。
Swagger:能够主动的帮忙开发人员生成接口文档,并对接口进行测试。
POI: 封装了对 Excel 表格的罕用操作。
WebSocket: 一种通信网络协议,使客户端和服务器之间的数据交换更加简略,用于我的项目的来单、催单功能实现。
4). 数据层
MySQL:关系型数据库, 本我的项目的外围业务数据都会采纳 MySQL 进行存储。
Redis:基于 key-value 格局存储的内存数据库, 访问速度快, 常常应用它做缓存。
Mybatis:本我的项目长久层将会应用 Mybatis 开发。
pagehelper: 分页插件。
spring data redis: 简化 java 代码操作 Redis 的 API。
5). 工具
git: 版本控制工具, 在团队合作中, 应用该工具对我的项目中的代码进行治理。
maven: 我的项目构建工具。
junit:单元测试工具,开发人员性能实现结束后,须要通过 junit 对性能进行单元测试。
postman: 接口测工具,模仿用户发动的各类 HTTP 申请,获取对应的响应后果。
3. 开发环境搭建
开发环境搭建次要蕴含 前端环境 和后端环境 两局部。作为服务端开发工程师,咱们课程学习的重心应该放在后端的业务代码上,前端的页面咱们只须要导入材料中的 nginx,前端页面的代码咱们只须要能看懂即可。
3.1 前端环境搭建
1). 前端工程基于 nginx
从材料中找到前端运行环境的 nginx,挪动到 非中文目录 下。
sky目录中寄存了治理端的前端资源,具体如下:
2). 启动 nginx,拜访测试
双击 nginx.exe 即可启动 nginx 服务,拜访端口号为 80
http://localhost:80
3.2 后端环境搭建
3.2.1 相熟我的项目构造
后端工程基于 maven 进行我的项目构建,并且进行分模块开发。
1). 从当天材料中找到后端初始工程:
2). 用 IDEA 关上初始工程,理解我的项目的整体构造:
对工程的每个模块作用阐明:
序号 | 名称 | 阐明 |
---|---|---|
1 | sky-take-out | maven 父工程,对立治理依赖版本,聚合其余子模块 |
2 | sky-common | 子模块,寄存公共类,例如:工具类、常量类、异样类等 |
3 | sky-pojo | 子模块,寄存实体类(Entity)、VO、DTO 等 |
4 | sky-server | 子模块,后端服务,寄存配置文件、Controller、Service、Mapper 等 |
对我的项目整体构造理解后,接下来咱们详细分析上述的每个子模块:
- sky-common: 模块中寄存的是一些公共类,能够供其余模块应用
剖析 sky-common 模块的每个包的作用:
名称 | 阐明 |
---|---|
constant | 寄存相干常量类 |
context | 寄存上下文类 |
enumeration | 我的项目的枚举类存储 |
exception | 寄存自定义异样类 |
json | 解决 json 转换的类 |
properties | 寄存 SpringBoot 相干的配置属性类 |
result | 返回后果类的封装 |
utils | 常用工具类 |
- sky-pojo: 模块中寄存的是一些 entity、DTO、VO
剖析 sky-pojo 模块的每个包的作用:
名称 | 阐明 |
---|---|
Entity | 实体,通常和数据库中的表对应 |
DTO | 数据传输对象,通常用于程序中各层之间传递数据 |
VO | 视图对象,为前端展现数据提供的对象 |
POJO | 一般 Java 对象,只有属性和对应的 getter 和 setter |
- sky-server: 模块中寄存的是 配置文件、配置类、拦截器、controller、service、mapper、启动类等
剖析 sky-server 模块的每个包的作用:
名称 | 阐明 |
---|---|
config | 寄存配置类 |
controller | 寄存 controller 类 |
interceptor | 寄存拦截器类 |
mapper | 寄存 mapper 接口 |
service | 寄存 service 类 |
SkyApplication | 启动类 |
3.2.2 Git 版本控制
应用 Git 进行我的项目代码的版本控制,具体操作:
1). 创立 Git 本地仓库
当 Idea 中呈现:
阐明本地仓库创立胜利。
2). 创立 Git 近程仓库
- 拜访 https://gitee.com/,新建仓库
- 点击 创立
3). 将本地文件推送到 Git 近程仓库
- 提交文件至本地仓库
疏忽以下类型文件
![](/img/bVc9sV4)
开始提交
两头呈现:点击 commit
- 增加 Git 近程仓库地址
复制近程地址:
增加地址: - 推送
胜利推送至近程仓库
3.2.3 数据库环境搭建
- 从材料中找到 sky.sql
通过该 sql 文件间接可创立数据库,所以不须要提前创立数据库,间接导入该文件执行即可。
- 执行 sky.sql 文件
执行实现后,共创立出 11 张表
每张表的阐明:
序号 | 表名 | 中文名 |
---|---|---|
1 | employee | 员工表 |
2 | category | 分类表 |
3 | dish | 菜品表 |
4 | dish_flavor | 菜品口味表 |
5 | setmeal | 套餐表 |
6 | setmeal_dish | 套餐菜品关系表 |
7 | user | 用户表 |
8 | address_book | 地址表 |
9 | shopping_cart | 购物车表 |
10 | orders | 订单表 |
11 | order_detail | 订单明细表 |
咱们目前先简略理解大略有哪些表, 每张表存储什么数据, 有一个印象。对于具体的表构造, 以及表构造中的字段, 能够参考资料中的《数据库设计文档》,同时在解说具体的性能开发时, 咱们也会再具体介绍。
3.2.4 前后端联调
后端的初始工程中曾经实现了 登录 性能,间接进行前后端联调测试即可
实现思路:
1.Controller 层
在 sky-server 模块中,com.sky.controller.admin.EmployeeController
/**
* 登录
*
* @param employeeLoginDTO
* @return
*/
@PostMapping("/login")
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {log.info("员工登录:{}", employeeLoginDTO);
// 调用 service 办法查询数据库
Employee employee = employeeService.login(employeeLoginDTO);
// 登录胜利后,生成 jwt 令牌
Map<String, Object> claims = new HashMap<>();
claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(),
jwtProperties.getAdminTtl(),
claims);
EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
.id(employee.getId())
.userName(employee.getUsername())
.name(employee.getName())
.token(token)
.build();
return Result.success(employeeLoginVO);
}
2.Service 层
在 sky-server 模块中,com.sky.service.impl.EmployeeServiceImpl
/**
* 员工登录
*
* @param employeeLoginDTO
* @return
*/
public Employee login(EmployeeLoginDTO employeeLoginDTO) {String username = employeeLoginDTO.getUsername();
String password = employeeLoginDTO.getPassword();
//1、依据用户名查询数据库中的数据
Employee employee = employeeMapper.getByUsername(username);
//2、解决各种异常情况(用户名不存在、明码不对、账号被锁定)if (employee == null) {
// 账号不存在
throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
}
// 明码比对
if (!password.equals(employee.getPassword())) {
// 明码谬误
throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
}
if (employee.getStatus() == StatusConstant.DISABLE) {
// 账号被锁定
throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
}
//3、返回实体对象
return employee;
}
3.Mapper 层
在 sky-server 模块中,com.sky.mapper.EmployeeMapper
package com.sky.mapper;
import com.sky.entity.Employee;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface EmployeeMapper {
/**
* 依据用户名查问员工
* @param username
* @return
*/
@Select("select * from employee where username = #{username}")
Employee getByUsername(String username);
}
注:能够通过断点调试跟踪后端程序的执行过程
3.2.5 nginx 反向代理和负载平衡
对登录功能测试结束后,接下来,咱们思考一个问题:前端发送的申请,是如何申请到后端服务的?
前端申请地址:http://localhost/api/employee/login
后端接口地址:http://localhost:8080/admin/employee/login
前端申请地址
后端接口地址
很显著,两个地址不统一,那是如何申请到后端服务的呢?
1). nginx 反向代理
nginx 反向代理,就是将前端发送的动静申请由 nginx 转发到后端服务器
那为什么不间接通过浏览器间接申请后盾服务端,须要通过 nginx 反向代理呢?
nginx 反向代理的益处:
- 进步访问速度
因为 nginx 自身能够进行缓存,如果拜访的同一接口,并且做了数据缓存,nginx 就间接可把数据返回,不须要真正地拜访服务端,从而进步访问速度。 - 进行负载平衡
所谓负载平衡, 就是把大量的申请依照咱们指定的形式平衡的调配给集群中的每台服务器。 - 保障后端服务平安
因为个别后盾服务地址不会裸露,所以应用浏览器不能间接拜访,能够把 nginx 作为申请拜访的入口,申请达到 nginx 后转发到具体的服务中,从而保障后端服务的平安。
nginx 反向代理的配置形式:
server{
listen 80;
server_name localhost;
location /api/{proxy_pass http://localhost:8080/admin/; #反向代理}
}
proxy_pass:该指令是用来设置代理服务器的地址,能够是主机名称,IP 地址加端口号等模式。
如上代码的含意是:监听 80 端口号,而后当咱们拜访 http://localhost:80/api/../.. 这样的接口的时候,它会通过 location /api/ {} 这样的反向代理到 http://localhost:8080/admin/ 上来。
接下来,进到nginx-1.20.2\conf
,关上 nginx 配置
# 反向代理, 解决治理端发送的申请
location /api/ {
proxy_pass http://localhost:8080/admin/;
#proxy_pass http://webservers/admin/;
}
当在拜访 http://localhost/api/employee/login,nginx 接管到申请后转到 http://localhost:8080/admin/,故最终的申请地址为 http://localhost:8080/admin/employee/login,和后盾服务的拜访地址统一。
2). nginx 负载平衡
当如果服务以集群的形式进行部署时,那 nginx 在转发申请到服务器时就须要做相应的负载平衡。其实,负载平衡从实质上来说也是基于反向代理来实现的,最终都是转发申请。
nginx 负载平衡的配置形式:
upstream webservers{
server 192.168.100.128:8080;
server 192.168.100.129:8080;
}
server{
listen 80;
server_name localhost;
location /api/{proxy_pass http://webservers/admin;# 负载平衡}
}
upstream:如果代理服务器是一组服务器的话,咱们能够应用 upstream 指令配置后端服务器组。
如上代码的含意是:监听 80 端口号,而后当咱们拜访 http://localhost:80/api/../.. 这样的接口的时候,它会通过 location /api/ {} 这样的反向代理到 http://webservers/admin,依据 webservers 名称找到一组服务器,依据设置的负载平衡策略 (默认是轮询) 转发到具体的服务器。
注:upstream 前面的名称可自定义,但要高低保持一致。
nginx 负载平衡策略:
名称 | 阐明 |
---|---|
轮询 | 默认形式 |
weight | 权重形式,默认为 1,权重越高,被调配的客户端申请就越多 |
ip_hash | 根据 ip 调配形式,这样每个访客能够固定拜访一个后端服务 |
least_conn | 根据起码连贯形式,把申请优先调配给连接数少的后端服务 |
url_hash | 根据 url 调配形式,这样雷同的 url 会被调配到同一个后端服务 |
fair | 根据响应工夫形式,响应工夫短的服务将会被优先调配 |
具体配置形式:
轮询:
upstream webservers{
server 192.168.100.128:8080;
server 192.168.100.129:8080;
}
weight:
upstream webservers{
server 192.168.100.128:8080 weight=90;
server 192.168.100.129:8080 weight=10;
}
ip_hash:
upstream webservers{
ip_hash;
server 192.168.100.128:8080;
server 192.168.100.129:8080;
}
least_conn:
upstream webservers{
least_conn;
server 192.168.100.128:8080;
server 192.168.100.129:8080;
}
url_hash:
upstream webservers{
hash &request_uri;
server 192.168.100.128:8080;
server 192.168.100.129:8080;
}
fair:
upstream webservers{
server 192.168.100.128:8080;
server 192.168.100.129:8080;
fair;
}
3.3 欠缺登录性能
问题:员工表中的明码是明文存储,安全性太低。
解决思路:
- 将明码加密后存储,进步安全性
- 应用 MD5 加密形式对明文明码加密
实现步骤:
- 批改数据库中明文明码,改为 MD5 加密后的密文
关上 employee 表,批改明码 -
批改 Java 代码,前端提交的明码进行 MD5 加密后再跟数据库中明码比对
关上 EmployeeServiceImpl.java,批改比对明码/** * 员工登录 * * @param employeeLoginDTO * @return */ public Employee login(EmployeeLoginDTO employeeLoginDTO) { //1、依据用户名查询数据库中的数据 //2、解决各种异常情况(用户名不存在、明码不对、账号被锁定)//....... // 明码比对 // TODO 前期须要进行 md5 加密,而后再进行比对 password = DigestUtils.md5DigestAsHex(password.getBytes()); if (!password.equals(employee.getPassword())) { // 明码谬误 throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR); } //........ //3、返回实体对象 return employee; }
4. 导入接口文档
接下来,就要进入到我的项目的业务开发了,而咱们的开发方式就是根本以后企业支流的前后端拆散开发方式,那么这种形式就要求咱们之前须要先将接口定义好,这样前后端人员能力并行开发,所以,这个章节就须要将接口文档导入到治理平台,为咱们前面业务开发做好筹备。其实,在实在的企业开发中,接口设计过程其实是一个十分漫长的过程,可能须要屡次开会讨论调整,甚至在开发的过程中才会发现某些接口定义还须要再调整,这种状况其实是十分常见的,然而因为我的项目工夫起因,所以抉择一次性导入所有的接口,在开发业务性能过程当中,也会带着大家一起来剖析一下对应的接口是怎么确定下来的,为什么要这样定义,从而造就同学们的接口设计能力。
4.1 前后端拆散开发流程
第一步:定义接口,确定接口的门路、申请形式、传入参数、返回参数。
第二步:前端开发人员和后端开发人员并行开发,同时,也可自测。
第三步:前后端人员进行连调测试。
第四步:提交给测试人员进行最终测试。
4.2 操作步骤
将课程材料中提供的我的项目接口导入 YApi。拜访地址:http://yapi.smart-xwork.cn/
1). 从材料中找到我的项目接口文件
2). 导入到 YApi 平台
在 YApi 平台创立出两个我的项目
抉择天穹外卖 - 治理端接口.json 导入
如果接口比拟多,这个过程会花一些工夫。
导入胜利
另一个用户端 json 文件也执行雷同操作。
5. Swagger
5.1 介绍
Swagger 是一种 API 文档主动生成工具,它能够帮忙开发人员疾速生成 API 文档,并提供在线 API 测试性能用于生成、形容、调用和可视化 RESTful 格调的 Web 服务(https://swagger.io/)。它的次要作用是:
- 使得前后端拆散开发更加不便,有利于团队合作
- 接口的文档在线主动生成,升高后端开发人员编写接口文档的累赘
- 功能测试
Spring 曾经将 Swagger 纳入本身的规范,建设了 Spring-swagger 我的项目,当初叫 Springfox。通过在我的项目中引入 Springfox,即可非常简单快捷的应用 Swagger。
knife4j 是为 Java MVC 框架集成 Swagger 生成 Api 文档的加强解决方案, 前身是 swagger-bootstrap-ui, 取名 knife4j 是心愿它能像一把匕首一样玲珑, 轻量, 并且性能强悍!
目前,个别都应用 knife4j 框架。
5.2 应用步骤
-
导入 knife4j 的 maven 坐标
在 pom.xml 中增加依赖<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> </dependency>
-
在配置类中退出 knife4j 相干配置
WebMvcConfiguration.java/** * 通过 knife4j 生成接口文档 * @return */ @Bean public Docket docket() {ApiInfo apiInfo = new ApiInfoBuilder() .title("天穹外卖我的项目接口文档") .version("2.0") .description("天穹外卖我的项目接口文档") .build(); Docket docket = new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo) .select() .apis(RequestHandlerSelectors.basePackage("com.sky.controller")) .paths(PathSelectors.any()) .build(); return docket; }
-
设置动态资源映射,否则接口文档页面无法访问
WebMvcConfiguration.java/** * 设置动态资源映射 * @param registry */ protected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); }
- 拜访测试
接口文档拜访门路为 http://ip:port/doc.html —> http://localhost:8080/doc.html
接口测试: 测试登录性能
思考:通过 Swagger 就能够生成接口文档,那么咱们就不须要 Yapi 了?
1、Yapi 是设计阶段应用的工具,治理和保护接口
2、Swagger 在开发阶段应用的框架,帮忙后端开发人员做后端的接口测试
5.3 罕用注解
通过注解能够管制生成的接口文档,使接口文档领有更好的可读性,罕用注解如下:
注解 | 阐明 |
---|---|
@Api | 用在类上,例如 Controller,示意对类的阐明 |
@ApiModel | 用在类上,例如 entity、DTO、VO |
@ApiModelProperty | 用在属性上,形容属性信息 |
@ApiOperation | 用在办法上,例如 Controller 的办法,阐明办法的用处、作用 |
接下来,应用上述注解,生成可读性更好的接口文档
在 sky-pojo 模块中
EmployeeLoginDTO.java
package com.sky.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(description = "员工登录时传递的数据模型")
public class EmployeeLoginDTO implements Serializable {@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("明码")
private String password;
}
EmployeeLoginVo.java
package com.sky.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "员工登录返回的数据格式")
public class EmployeeLoginVO implements Serializable {@ApiModelProperty("主键值")
private Long id;
@ApiModelProperty("用户名")
private String userName;
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("jwt 令牌")
private String token;
}
在 sky-server 模块中
EmployeeController.java
package com.sky.controller.admin;
import com.sky.constant.JwtClaimsConstant;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.entity.Employee;
import com.sky.properties.JwtProperties;
import com.sky.result.Result;
import com.sky.service.EmployeeService;
import com.sky.utils.JwtUtil;
import com.sky.vo.EmployeeLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* 员工治理
*/
@RestController
@RequestMapping("/admin/employee")
@Slf4j
@Api(tags = "员工相干接口")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@Autowired
private JwtProperties jwtProperties;
/**
* 登录
*
* @param employeeLoginDTO
* @return
*/
@PostMapping("/login")
@ApiOperation(value = "员工登录")
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {//..............}
/**
* 退出
*
* @return
*/
@PostMapping("/logout")
@ApiOperation("员工退出")
public Result<String> logout() {return Result.success();
}
}
启动服务:拜访 http://localhost:8080/doc.html