一、canal_clientedu:数据同步
可以不运行,用于Windows本地数据库和Linux数据库进行数据同步
二、common
1.common_utils:通用工具
JwtUtils:JWT工具类,token加密
MD5:密码加密
R:统一返回结果
ResponseUtil:
ResultCode:返回码
2.service_base
RedisConfig:redis配置
SwaggerConfig:Swagger配置
(1)exceptionhandler
ForestException
GlobalExceptionHandler
(2)handler
MyMetaObjectHandler
3.spring_security:权限管理
spring_security框架介绍
- Spring Security 基于 Spring 框架,提供了一套Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分
(1)用户认证:进入用户登录的时候,输入用户名和密码,查询数据库,输入用户名和密码是否正确,如果正确,就认证成功
(2)用户授权:登录了系统,登录用户可能是不同的角色,比如现在登录的用户是系统管理员,管理员操作所有功能,比如等普通用户,操作功能肯定比管理员少很多 - Spring Security本质上就是过滤器filter,多请求的路径进行过滤
(1)如果是基于Session,那么Spring-security会对cookie里的sessionid进行解析,找到服务器存储
的sesion信息,然后判断当前用户是否符合请求的要求。
(2)如果是token,则是解析出token,根据token得到身份信息,然后得到权限信息,将当前请求加入到Spring-security管理的权限信息中去
认证和授权实现思路
- 如果系统的模块众多,每个模块都需要就行授权与认证,所以我们选择基于token的形式进行授权与认证,用户根据用户名密码认证成功
- 然后获取当前用户角色的一系列权限值,并以用户名为key,权限列表为value的形式存入redis缓存中
- 根据用户名相关信息生成token返回,浏览器将token记录到cookie中,每次调用api接口都默认将token携带到header请求头中
- Spring-security解析header头获取token信息,解析token获取当前用户名,根据用户名就可以从redis中获取权限列表,这样Spring-security就能够判断当前请求是否有权限访问
代码结构说明
三、infrastructure
api_gateway:网关配置
什么是网关:客户端和服务端中间的一堵墙,可以起到的作用有:请求转发、负载均衡、权限控制等等
Spring Cloud Gateway核心概念
网关提供API全托管服务,丰富的API管理功能,辅助企业管理大规模的API,以降低管理成本和安全风
险,包括协议适配、协议转发、安全策略、防刷、流量、监控日志等贡呢。一般来说网关对外暴露
的URL或者接口信息,我们统称为路由信息。如果研发过网关中间件或者使用过Zuul的人,会知道网关的
核心是Filter以及Filter Chain(Filter责任链)。Sprig Cloud Gateway也具有路由和Filter的概念。
下面介绍一下Spring Cloud Gateway中几个重要的概念。
- 路由:路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组Filter组成。如果断言路由为真,则说明请求的URL和配置匹配
- 断言:Java8中的断言函数。Spring Cloud Gateway中的断言函数输入类型是Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定义匹配来自于httprequest中的任何信息,比如请求头和参数等。
- 过滤器:一个标准的Spring webFilter。Spring cloud gateway中的filter分为两种类型的Filter,分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理
GateWay Handler Mapping:访问之后做映射(路径)匹配
GateWay Web Handler:处理匹配
Filter:过滤
将网关在注册中心进行注册
四、service
1.service_acl:后台用户管理
2.service_cms:轮播图
3.service_edu:课程管理
EasyExcel
优势:一行一行读取到内存,避免了Apache poi、jxl全部读取的内存损耗
EasyExcel写操作
1.创建实体类,设置表头
2.设置写入路径
3.调用方法传入路径.实体类.sheet名.list数据
EasyExcel读操作
1.创建实体类,设置index列数,标记对应列的关系
2.创建读取操作监听器
3.调用方法,路径.实体类.new监听器
课程分类前端树状显示
4.service_msm:短信
阿里云短信发送需要企业用户才可申请,改为云市场短信服务
搜索短信
5.service_order:订单
微信支付
代码逻辑:
- 订单页面调用接口根据时间生成订单,传入订单号
- 根据订单号生成微信支付二维码
- 将map设置为生成二维码需要的参数
- 使用工具类发送httpclient请求,传递xml格式参数,微信支付提供的固定地址
- 得到发送请求的返回结果,将返回的xml格式参数转换为map集合
- 返回的map集合中携带二维码操作状态码和二维码地址
- 用户扫码
- 前端根据订单号向微信平台每隔3秒查询订单的支付状态,trade_state等于SUCCESS时支付成功
- 支付成功更新数据库订单状态,添加订单日志表,跳转到课程详情页面
6.service_oss:图片管理
代码逻辑
- 调用接口上传图片
- 拼接处理图片文件名
- 上传图片后返回文件路径
- 前端获取图片路径,调用接口存放到数据库
7.service_statistics:数据统计
8.service_ucenter:前台登录注册
前台登录注册流程图
前台拦截流程
- 调用接口登录返回token字符串
- 将返回的token字符串放到cookie里面
- 创建拦截器,判断cookie里面是否有token字符串,如果有放到header里面
- 根据header里的token值调用接口获取用户信息
- 把调用接口返回的用户信息(头像、用户名等)放到cookie里面
- 从cookie里面获取用户信息
- 之后访问其它模块的页面都需要由前台校验cookie里的token并进行拦截
WxApiController:微信扫码
- 因为本地测试,无法请求部署域名,改为请求本地wx.open.redirect_url=http://localhost:8160/api/ucenter/wx/callback地址,在该地址中进行信息处理获取用户信息String code, String state
- 拿code请求微信固定地址,获取access_token访问凭证和openid每个微信的唯一标识
- 拿access_token和openid请求微信固定地址,获取微信扫码人信息
- 根据openid判断数据库是否有该用户信息,有信息直接返回首页面,无信息添加信息
- 根据扫码人信息生成member对象存入数据库
- 返回到http://localhost:3000前台页面并附带JWT加密token
微信登录流程
配置文件
# 服务端口
server.port=8160
# 微信开放平台 appid
wx.open.app_id=wxed9954c01bb89b47
# 微信开放平台 appsecret
wx.open.app_secret=a7482517235173ddb4083788de60b90e
# 微信开放平台 重定向url
wx.open.redirect_url=http://localhost:8160/api/ucenter/wx/callback
逻辑流程
(需改为8160)
获取微信扫码人信息
9.service_vod:视频
使用步骤:
初始化操作,创建DefaultAcsClient对象
import com.aliyun.oss.ClientException;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;
public class InitVodCilent {
public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
String regionId = "cn-shanghai"; // 点播服务接入区域
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
return client;
}
}
视频播放
使用音视频播放获取视频播放凭证的代码
//根据视频id获取视频凭证
@GetMapping("getPlayAuth/{id}")
public R getPlayAuth(@PathVariable String id) {
try {
//创建初始化对象
DefaultAcsClient client =
InitVodCilent.initVodClient(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET);
//创建获取凭证request和response对象
GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
//向request设置视频id
request.setVideoId(id);
//调用方法得到凭证
GetVideoPlayAuthResponse response = client.getAcsResponse(request);
String playAuth = response.getPlayAuth();
return R.ok().data("playAuth",playAuth);
}catch(Exception e) {
throw new ForestException(20001,"获取凭证失败");
}
}
视频上传
@Override
public String uploadVideoAly(MultipartFile file) {
try {
//accessKeyId, accessKeySecret
//fileName:上传文件原始名称
// 01.03.09.mp4
String fileName = file.getOriginalFilename();
//title:上传之后显示名称
String title = fileName.substring(0, fileName.lastIndexOf("."));
//inputStream:上传文件输入流
InputStream inputStream = file.getInputStream();
UploadStreamRequest request = new UploadStreamRequest(ConstantVodUtils.ACCESS_KEY_ID,ConstantVodUtils.ACCESS_KEY_SECRET, title, fileName, inputStream);
UploadVideoImpl uploader = new UploadVideoImpl();
UploadStreamResponse response = uploader.uploadStream(request);
String videoId = null;
if (response.isSuccess()) {
videoId = response.getVideoId();
} else { //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
videoId = response.getVideoId();
}
return videoId;
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
注意事项:
- 引入依赖会有问题,解决方法后补参考:Cannot resolve com.aliyun:aliyun-sdk-vod-upload:1.4.11
- DefaultAcsClient中因依赖版本较晚只能String regionId = “cn-shanghai”; // 点播服务接入区域,cn-beijing会出现异常
运用技术
MybatisPlus
官方文档:https://baomidou.com/pages/24112f/#%E7%89%B9%E6%80%A7
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
Nacos
官方文档:https://nacos.io/zh-cn/docs/what-is-nacos.html
Nacos 是阿里巴巴推出来的一个新开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Spring Cloud相关基础服务组件
服务发现——Netflix Eureka (Nacos)
服务调用——Netflix Feign
熔断器——Netflix Hystrix
服务网关——Spring Cloud GateWay
分布式配置——Spring Cloud Config (Nacos)
消息总线 —— Spring Cloud Bus (Nacos)
常见的注册中心:
- Eureka(原生,2.0遇到性能瓶颈,停止维护)
- Zookeeper(支持,专业的独立产品。例如:dubbo)
- Consul(原生,GO语言开发)
- Nacos
相对于 Spring Cloud Eureka 来说,Nacos 更强大。Nacos = Spring Cloud Eureka + Spring Cloud Config
Nacos 可以与 Spring, Spring Boot, Spring Cloud 集成,并能代替 Spring Cloud Eureka, Spring Cloud Config
通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。
Nacos是以服务为主要服务对象的中间件,Nacos支持所有主流的服务发现、配置和管理。
Nacos主要提供以下四大功能:
1.服务发现和服务健康监测
2.动态配置服务
3.动态DNS服务
4.服务及其元数据管理
Nacos结构图