1 后台管理系统
1.1 搭建环境
- 使用 Maven 作为构建管理和依赖管理工具。
- 使用 SpringMVC 作为 Web 层框架。(普通请求、Ajax请求)
- 普通请求: 返回响应体通常为一个页面
- Ajax 请求: 返回响应体通常为一个 JSON 数据
- 使用 MyBatis 作为持久化层框架。mybatis框架技术总结(PageHelper)
- 使用 MyBatis 的 PageHelper 插件实现数据的分页显示。(Admin 数据、Role 数据)
- 使用 Spring 提供的容器管理项目中的组件。( Controller、Service、Mapper、Intercept、ExceptionHandler) Spring技术总结(容器)
- 借助 SpringMVC 提供的异常映射机制实现项目中错误消息的统一管理。(基于注解、基于 XML)
- 前端技术:Boostrap 作为前端样式框架、使用 layer 作为弹层组件、使用 zTree 在页面上显示树形结构
1.2 管理员登录
-
使用自定义拦截器检查登录状态
-
请求到达Controller前先经过自定义拦截器LoginInterceptor
-
在重写的方法preHandle中判断Session是否包含Admin,不包含抛出LoginInterceptException异常,进入统一异常处理类处理。
-
登陆流程
-
前端发送“/admin/do/login.html”请求,将loginAcct和userPswd参数传递给AdminController。
-
Controller调用Service层方法getAdminByLoginAcctAndPassword,Service层对userPswd进行了MD5 密码加密后处理。
-
验证成功后为避免表单重复提交重定向回管理员中心页面"redirect:/admmin/to/main/page.html"
-
退出登录
-
MD5加密流程
-
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
-
byte[] output = messageDigest.digest(source.getBytes());
-
String encoded= new BigInteger(1, output).toString(16). toUpperCase();
-
全局异常处理类异常处理
-
Service层对loginAcct和userPswd匹配后抛出自定义异常LoginFailedException,经全局异常处理类跳转回登陆页面
-
未登录访问资源,经全局异常处理类跳转回登陆页面
1.3 管理员维护
-
采用普通请求,实现CRUD功能。提供了显示页面、新增页面,修改页面。
-
显示功能:使用 MyBatis 的 PageHelper 插件实现分页,在页面上使用了 Pagination 实现数字页码
-
提供了关键词搜索功能,并在页面显示。通过对请求消息头信息的判断在给出异常处理结果时实现了普通请求和Ajax请求的兼容
-
在数据库表中给 loginacct 字段添加唯一约束, 在保存了重复的 loginacct 时触发异常, 从而保证登录账号的唯一
-
提供了给管理员分配角色功能
1.4 角色维护
-
以 Ajax 交互方式实现数据的增删改查操作,使用模态框实现角色数据的增删改。
-
提供了给角色分配权限的功能
1.5 菜单维护
-
使用 zTree 在页面上显示树形结构,并结合 zTree 提供的 API 显示自定义图标
-
对树形节点进行增删改查操作
1.6 权限控制
-
思路:给 Admin 分配 Role,给 Role 分配 Auth
-
使用 SpringSecurity 接管项目的登录、 登录检查、 权限验证
-
SpringSecurity代码实现流程
-
加依赖,在web.xml配置DelegatingFilterProxy。
-
创建User类的子类SecurityAdmin,将管理员信息和角色权限信息封装进SecurityAdmin类
-
创建UserDetailsService接口的实现类CrowdUserDetailsService,重写loadUserByUsername方法,在方法体内查询数据库的管理员及其权限信息,封装到SecurityAdmin返回。
-
创建WebAppSecurityConfig配置类,继承WebSecurityConfigurerAdapter父类,添加@Configuration、@EnableWebSecurity、@EnableGlobalMethodSecurity(prePostEnabled = true)注解
-
重写定制请求的授权规则方法configure(HttpSecurity security)和定义认证规则方法configure(AuthenticationManagerBuilder builder)。
-
总结
-
让 SpringSecurity 在初始化时不要查找 IOC 容器, 而是在第一次请求时查找;查找的 IOC 容器也改成了查找 SpringMVC 的 IOC 容器(也就是由 DispatcherServlet的父类 FrameworkServlet 初始化的 IOC 容器)。TODO:改源码或者改配置扫描浮点包
-
登陆检查是SpringSecurity内置的,自己不用实现。
2 前台会员系统
2.0 搭建环境
-
微服务工程,使用SpringBoot创建
-
创建mysql provider工程,使用到mysql技术
-
创建redis provider工程,使用到redis技术
-
创建authentication consumer工程,会员登录注册,权限控制功能(短信接口,SpringSession)
-
创建project consumer工程,项目管理功能(OSS服务)
-
创建order consumer工程,订单工程
-
创建pay consumer工程,支付功能(支付宝接口)
-
SpringCloud管理工程
-
创建eureka注册中心工程
-
创建zuul网关工程
-
辅助层
-
创建entity工程,定义实体类(VO,PO)
-
创建API工程,调用远程的mysql和redis接口,为consumer工程提供service功能,使用到Feign技术,feign内置了Ribbon
-
使用原有的util工程
TODO:SpringBoot技术总结(Thymeleaf、SpringSession)
SpringCloud技术总结(Eureka、Feign、Ribbon、Zuul)
2.1 实体类工程详解
-
VO:View Object 视图对象
-
用途 1: 接收浏览器发送过来的数据
-
用途 2: 把数据发送给浏览器去显示
-
PO:Persistent Object 持久化对象
-
用途 1: 将数据封装到 PO 对象存入数据库
-
用途 2: 将数据库数据查询出来存入 PO 对象。所以 PO 对象是和数据库表对应, 一个数据库表对应一个 PO 对象
-
DO:Data Object 数据对象
-
用途 1: 从 Redis 查询得到数据封装为 DO 对象
-
用途 2: 从 ElasticSearch 查询得到数据封装为 DO 对象
-
用途 3: 从 Solr 查询得到数据封装为 DO 对象。从中间件或其他第三方接口查询到的数据封装为 DO 对象
-
DTO:Data Transfer Object 数据传输对象
-
用途 1: 从 Consumer 发送数据到 Provider
-
用途 2: Provider 返回数据给 Consumer
2.2 Eureka注册中心工程、Zuul网关工程
(1) eureka的properties.yml配置
只需要配置端口号,名称,注册中心url即可
server: port: 1007 spring: application: name: atguigu-crowd-eureka eureka: instance: hostname: localhost client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
(2) zuul的properties.yml配置
server: port: 1017 spring: application: name: atguigu-crowd-zuul redis: host: 127.0.0.1 session: store-type: redis eureka: client: service-url: defaultZone: http://localhost:1007/eureka/ zuul: ignored-services: "*" sensitive-headers: "*" routes: //路由转发,根据请求url,跳转至相应的微服务工程 crowd-portal: service-id: atguigu-crowd-auth path: /** crowd-project: service-id: atguigu-crowd-project path: /project/** crowd-order: service-id: atguigu-crowd-order path: /order/** crowd-pay: service-id: atguigu-crowd-pay path: /pay/** ribbon: ReadTimeout: 10000 ConnectTimeout: 10000
(3) CrowdAccessFilter类
-
创建CrowdAccessFilter类继承父类ZuulFilter,重写父类4个方法
-
shouldFilter()方法来判断请求资源是否应该被拦截
-
run()表示执行拦截,进行登录检查
-
filterType()返回“pre”,表示在到达目标微服务前执行拦截
2.3 authentication consumer工程,用户登录注册
(1) properties.yml配置
server: port: 1011 spring: application: name: atguigu-crowd-auth thymeleaf: prefix: classpath:/templates/ suffix: .html redis: host: 127.0.0.1 session: store-type: redis eureka: client: service-url: defaultZone: http://localhost:1007/eureka/ short: message: app-code: 0dd300edf0944d9cae335dedbf21c94f host: http://dingxin.market.alicloudapi.com path: /dx/sendSms method: POST tpl_id: TP1711063
(2) 注册功能
-
流程:
-
发送验证码,调用第三方接口发送验证码,将手机号与验证码以key-value的形式调用redis远程接口保存到redis。
-
注册对比验证码,使用 BCryptPasswordEncoder 实现带盐值的加密密码,调用mysql远程接口将用户信息保存到数据库。
-
短信服务 TODO
(3) 登陆功能
-
使用 SpringSession 解决分布式环境下 Session 不一致问题,使用 Redis 作为 SpringSession 的 Session 库
-
添加依赖
-
在配置文件中配置:session.store-type=redis
-
在 Zuul 中使用 ZuulFilter 实现登录状态检查,在 Zuul 中配置访问各个具体微服务的路由规则。
2.4 project consumer工程
(1) yml配置文件
server: port: 1012 spring: application: name: atguigu-crowd-project thymeleaf: prefix: classpath:/templates/ suffix: .html redis: host: 127.0.0.1 session: store-type: redis eureka: client: service-url: defaultZone: http://localhost:1007/eureka/ aliyun: oss: //阿里云OSS相关配置 access-key-id: access-key-secret: bucket-domain: bucket-name: end-point:
(2) 发布项目
-
流程
-
阅读并同意协议
-
确认项目及发起人信息,需要上传图片。接收数据封装到ProjectVO对象。
-
添加回报,采用Ajax请求,也需要上传图片。回报信息封装到ReturnVO对象,添加到ProjectVO对象对象属性中。
-
添加收款账号及法人信息。接收数据封装到MemberConfirmInfoVO对象中,添加到ProjectVO对象对象属性中。
-
提交,后台审核。将ProjectVO对象传递给Mysql远程接口,保存到多个数据库表中
-
数据库
-
t_project:存储项目信息
-
t_project_tag:项目与标签关联表,多对多关系
-
t_project_type:项目与类型关联表,多对多关系
-
t_project_item_pic:项目图片表,一对多关系
-
t_tag:标签信息表
-
t_type:类型信息表
-
t_return:回报信息表
-
OSS 对象存储服务
使用阿里云 OSS 对象存储服务保存用户上传的图片
(3) 展示项目
调用Mysql远程接口获取项目信息封装到DetailProjectVO中,前页面端显示
2.5 支持项目(Order工程、Pay工程)
(1) Pay工程yml配置文件
server: port: 1014 spring: application: name: atguigu-crowd-pay thymeleaf: prefix: classpath:/templates/ suffix: .html redis: host: 127.0.0.1 session: store-type: redis eureka: client: service-url: defaultZone: http://localhost:1007/eureka/ ali: pay: alipay-public-key: //阿里云公钥 app-id: 2021000117639310 charset: utf-8 gateway-url: https://openapi.alipaydev.com/gateway.do merchant-private-key: //商家私钥 notify-url: http://mdpe3u.natappfree.cc/pay/notify return-url: http://localhost:1017/pay/return sign-type: RSA2
(2) 订单支付
-
流程
-
项目详情页点支持进入订单页。获取项目信息封装到OrderProjectVO对象中。
-
确认回报内容,输入回报数量。获取回报数量封装到OrderProjectVO对象中。
-
输入收货地址发票金额等信息,点击付款,生成订单。给支付宝接口发送请求
-
支付宝接口方法