项目名称:blc management system(blc MS)
基于Vue CLI4 + SpringBoot开发的前后端分离项目。
基本功能:对博客和书籍进行增删改查,在聊天室点对点聊天或者群发消息,支持发送文本消息以及图片消息,查看用户个人信息,在线预览聊天图片和用户头像。
特色功能:用户密码加密,页面访问控制,用户权限管理,Druid后台监控。
参考项目:
https://github.com/Antabot/White-Jotter
https://github.com/Tellsea/springboot-learn/-/tree/master/springboot-websocket
本项目地址:
码云: https://gitee.com/jiyuzz/blc-ms
CSDN: https://blog.csdn.net/jiyuzzz/article/details/122242514
1)前端
2)后端
3)数据库
4)开发环境
IDEA 2019.1
JDK 1.8.0_191
apache-maven-3.6.0
主要功能:博客、书架、聊天室。
聊天室是独立项目,无论在主页是否登录,都可以打开(但是打开后必须登录在聊天室中注册的新用户)。
未登录时,只能访问主页或者打开聊天室,对其他页面的访问会被拦截,然后跳转到登录页;
登录时,会进行角色认证:
登录后,默认记住用户登录状态30天(通过前端localstorage结合vuex+后端shiro实现);点击注销则会从前后端同时删除用户信息然后跳转到登录页。
注册会通过shiro对密码进行加盐加密,盐的值随机生成,加密算法使用md5,盐和加密后的密码都会保存在数据库中。
登录则是通过同样的加密方法对用户输入的密码加密,然后和数据库中加密后的密码进行对比,如果相同则允许用户登录。
聊天室使用了websocket允许用户互相发送消息以及群发消息,支持文本消息以及图片消息。
为什么mysql的varchar字符长度会被经常性的设置成255—— 不明其理的约定俗成
前端项目运行后,会在浏览器自动打开http://localhost:8080/index
进入项目主页,此时为游客登录,点击博客、书架都会被拦截然后跳转到登录页
点击右上角的管理中心,可以选择注销和进入聊天室。
点击聊天室会打开新的界面并让我们登录(因为聊天室属于独立的项目,必须使用在聊天室中注册的账号进行登录)
点击 博客 或者 书架,都会跳转到登录页,登录成功后,会跳转到我们之前点击但是被拦截的页面
在数据库的user表中的用户密码都是加密的
admin的密码:123456
张三的密码:zspwd
不同角色登录后,可以看到的导航栏选项不同,简单地说就是admin拥有更多权限。
admin:
normal:
点击注销,前端就会删除localstorage中的用户名,后端删除shiro中的session,然后跳转到登录页
注册成功会跳转到登录页
同时对密码使用了加盐加密(盐值随机生成,加密算法使用md5,随机盐和加密后的密码都保存在数据库)
点击具体的博客可以查看但是不可以编辑
点击左侧的分类可以分类查看,也可以通过书名或者作者名搜索书籍,也实现了分页
这些工具中主要是这两个,分别是保存博客以及编辑摘要和封面
点击保存就会直接同步到数据库
点击右上角的管理中心下的聊天室,可以打开聊天室的登录页
1) 登录
默认就会访问登录页,点击右上角“去注册”,会跳转带注册页,注册成功会跳转到登录页。登录成功会跳转到聊天页
2)注册
点击头像可以实现上传头像,之后所有头像会统一保存在D:\test\chatroom这个文件夹下,并且都会以用户的账号进行重命名。注册成功会跳转到登录页。
3)聊天
在输入框输入想要发送的文字信息,点击右下角的发送按钮即可发送。
点击按钮旁的向下箭头即可选择发送图片,点击图片可以在线预览全图。
左侧列表代表所有在线用户,点击就会跳转到对应的聊天窗口。
选择“所有人”,就会群发消息。
4)个人信息
点击导航栏的接收者昵称或者发送者昵称,都可以看到个人信息(从数据库获取),点击头像可以在线预览全图。
访问http://localhost:8443/druid,即可进入druid监控页面
输入用户名admin,密码123456进行登录
日志(保存在log/blc.log),相比于sql监控更加具体,包括参数及结果等(由于使用了jpa,所以自动生成的sql语句看起来都比较怪)
流程:前端访问地址/register 进入注册页面,点击注册,后端先验证用户名是否存在,如果用户名可用则对密码进行加密后存入数据库。前端收到成功信息后跳转到/login,进入登录页面。
加盐加密:在密码后面加一段随机的字符串(就是盐,由后端随机生成并且保存在数据库),然后再使用md5算法进行加密,生成的加密密码保存在数据库
在main.js配置路由前置守卫,如果用户未登录则跳转到登录页
store/index.js(vuex):储存前端的全局变量(用户名)以及修改变量时执行的方法
未登录时,只能访问主页;
登录时,进行角色认证:
登录后,默认记住用户登录状态30天(通过前端localstorage、vuex+后端shiro实现)。
前端:ImgUpload组件
后端:对前端传来的图片重命名为六位随机数+当前日期,然后把路径存在数据库,图片保存在D:\test文件夹(使用了虚拟路径)
为什么不直接存储绝对路径? 1、绝对路径不适合移植;2、目前大多数的主流浏览器禁止直接访问本地文件。
建立了WebSocket之后服务器不必在浏览器发送request请求之后才能发送信息到浏览器。这时的服务器已有主动权想什么时候发就可以发送信息到服务器。而且信息当中不必在带有head的部分信息了与http的长链接通信来说,这种方式,不仅能降低服务器的压力。而且信息当中也减少了部分多余的信息。
springboot2.0集成webSocket - 简书 (jianshu.com)
SpringBoot集成WebSocket - 仅此而已-远方 - 博客园 (cnblogs.com)
为什么不使用HTTP 协议? 因为HTTP是单工通信,通信只能由客户端发起,客户端请求一下,服务器处理一下,太麻烦了。
引入依赖spring-boot-starter-websocket,即可使用几个固定的注解。
使用了多线程来保存每个用户的连接:(ConcurrentHashMap线程安全;避免了多个线程竞争同一把锁的情况,大大提高了性能。)
private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
发送消息:
item.session.getAsyncRemote().sendText(message);
html5规范中为websocket定义了一系列的API,可以直接使用。
建立连接:
this.webSocket = new WebSocket("ws://localhost:8888/websocket/" + this.sendUser);
发送消息:
this.webSocket.send(JSON.stringify(message));