springboot前后端分离项目(图书+博客+聊天室)

springboot前后端分离项目(图书+博客+聊天室),第1张

springboot前后端分离项目(图书+博客+聊天室) 一、项目简介

基于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)前端

  1. Vue CLI4
  2. ElementUI
  3. axios

2)后端

  1. Spring Boot 2.1.3.RELEASE
  2. Apache Shiro
  3. Apache Log4j +Alibaba Druid(http://localhost:8443/druid/)
  4. Spring Data JPA
  5. Lombok

3)数据库

  1. MySQL 8.0.26

4)开发环境

  1. IDEA 2019.1

  2. JDK 1.8.0_191

  3. apache-maven-3.6.0

三、需求分析 1、功能分析

主要功能:博客、书架、聊天室。

聊天室是独立项目,无论在主页是否登录,都可以打开(但是打开后必须登录在聊天室中注册的新用户)。

未登录时,只能访问主页或者打开聊天室,对其他页面的访问会被拦截,然后跳转到登录页;

登录时,会进行角色认证:

  • 普通用户只能浏览博客和书架;
  • 管理员具有普通用户的一切权限,并且可以进行博客和书籍的管理(增删改查)。

登录后,默认记住用户登录状态30天(通过前端localstorage结合vuex+后端shiro实现);点击注销则会从前后端同时删除用户信息然后跳转到登录页。

注册会通过shiro对密码进行加盐加密,盐的值随机生成,加密算法使用md5,盐和加密后的密码都会保存在数据库中。

登录则是通过同样的加密方法对用户输入的密码加密,然后和数据库中加密后的密码进行对比,如果相同则允许用户登录。

聊天室使用了websocket允许用户互相发送消息以及群发消息,支持文本消息以及图片消息。

2、数据库设计 1)blc.sql

为什么mysql的varchar字符长度会被经常性的设置成255—— 不明其理的约定俗成

2)chatroom.sql

四、系统设计 项目结构

主页

前端项目运行后,会在浏览器自动打开http://localhost:8080/index
进入项目主页,此时为游客登录,点击博客、书架都会被拦截然后跳转到登录页

点击右上角的管理中心,可以选择注销和进入聊天室。
点击聊天室会打开新的界面并让我们登录(因为聊天室属于独立的项目,必须使用在聊天室中注册的账号进行登录)

登录

点击 博客 或者 书架,都会跳转到登录页,登录成功后,会跳转到我们之前点击但是被拦截的页面

在数据库的user表中的用户密码都是加密的
admin的密码:123456
张三的密码:zspwd

不同角色登录后,可以看到的导航栏选项不同,简单地说就是admin拥有更多权限。
admin:

normal:

点击注销,前端就会删除localstorage中的用户名,后端删除shiro中的session,然后跳转到登录页

注册

注册成功会跳转到登录页

同时对密码使用了加盐加密(盐值随机生成,加密算法使用md5,随机盐和加密后的密码都保存在数据库)

博客

点击具体的博客可以查看但是不可以编辑

书架

点击左侧的分类可以分类查看,也可以通过书名或者作者名搜索书籍,也实现了分页

鼠标悬停在图书封面,可以预览详细信息

博客管理

点击右上角的管理中心下的博客管理,可以对博客进行增删改查

博客编辑页面,支持快捷键(基本和大多数md编辑器一致)

这些工具中主要是这两个,分别是保存博客以及编辑摘要和封面
点击保存就会直接同步到数据库

点击编辑摘要就可以编辑摘要以及封面

图书管理

点击右上角的管理中心下的图书管理,可以对图书进行增删改查

聊天室

点击右上角的管理中心下的聊天室,可以打开聊天室的登录页

1) 登录

默认就会访问登录页,点击右上角“去注册”,会跳转带注册页,注册成功会跳转到登录页。登录成功会跳转到聊天页

2)注册
点击头像可以实现上传头像,之后所有头像会统一保存在D:testchatroom这个文件夹下,并且都会以用户的账号进行重命名。注册成功会跳转到登录页。

3)聊天
在输入框输入想要发送的文字信息,点击右下角的发送按钮即可发送。
点击按钮旁的向下箭头即可选择发送图片,点击图片可以在线预览全图。
左侧列表代表所有在线用户,点击就会跳转到对应的聊天窗口。
选择“所有人”,就会群发消息。

4)个人信息
点击导航栏的接收者昵称或者发送者昵称,都可以看到个人信息(从数据库获取),点击头像可以在线预览全图。

Druid

访问http://localhost:8443/druid,即可进入druid监控页面
输入用户名admin,密码123456进行登录

sql监控

URI监控

日志(保存在log/blc.log),相比于sql监控更加具体,包括参数及结果等(由于使用了jpa,所以自动生成的sql语句看起来都比较怪)

五、主要功能实现 1)注册
  • 流程:前端访问地址/register 进入注册页面,点击注册,后端先验证用户名是否存在,如果用户名可用则对密码进行加密后存入数据库。前端收到成功信息后跳转到/login,进入登录页面。

  • 加盐加密:在密码后面加一段随机的字符串(就是盐,由后端随机生成并且保存在数据库),然后再使用md5算法进行加密,生成的加密密码保存在数据库

2)登录
  • 流程:点击登录,进入后端/login。Shiro 通过 Realm 里我们重写的 doGetAuthenticationInfo 方法获取到了验证信息,再根据我们在配置类里定义的 CredentialsMatcher(HashedCredentialsMatcher),执行doCredentialsMatch,判断两个加密后的密码是否相等(数据库中取到的以及根据前端密码进行同样加密方法后生成的)。成功后会产生 session,并自动把 sessionId 设置到 cookie。前端收到后端返回的成功代码时,触发 store 中的 login() 方法,把 loginForm 对象中的username传递给 store 中的 user 对象(改变User对象时,会存进localstorage),再看用户是否在未登录时进行了路径的请求,有的话就进行跳转。
    点击右上角的按钮可以注销,会从前后端同时删除用户信息然后跳转到登录页。

3)页面访问拦截
  • 流程:为防止用户通过控制台输入代码绕过前端的 “全局前置守卫”,前端要带上 sesisonId 发送请求交由后端认证。
  • sessionId 生成方法:通过在后端的方法subject.login()产生 session,并自动把 sessionId 设置到 cookie。
  • 后端拦截器,如果检测不到用户登录的信息,就会拦截所有未过滤的路径请求:
  • 前端:

在main.js配置路由前置守卫,如果用户未登录则跳转到登录页

store/index.js(vuex):储存前端的全局变量(用户名)以及修改变量时执行的方法

4)角色认证

未登录时,只能访问主页;

登录时,进行角色认证:

  • 普通用户只能浏览博客和书架;
  • 管理员具有普通用户的一切权限,并且可以进行博客和书籍的管理(增删改查)。

登录后,默认记住用户登录状态30天(通过前端localstorage、vuex+后端shiro实现)。

原理是控制导航栏各选项的显示(v-if)

5)图片上传
  • 前端:ImgUpload组件

  • 后端:对前端传来的图片重命名为六位随机数+当前日期,然后把路径存在数据库,图片保存在D:test文件夹(使用了虚拟路径)

  • 虚拟路径:访问/api/file/实际上就是访问d:/test/

  • 为什么不直接存储绝对路径? 1、绝对路径不适合移植;2、目前大多数的主流浏览器禁止直接访问本地文件。

6)聊天室 WebSocket

建立了WebSocket之后服务器不必在浏览器发送request请求之后才能发送信息到浏览器。这时的服务器已有主动权想什么时候发就可以发送信息到服务器。而且信息当中不必在带有head的部分信息了与http的长链接通信来说,这种方式,不仅能降低服务器的压力。而且信息当中也减少了部分多余的信息。

springboot2.0集成webSocket - 简书 (jianshu.com)

SpringBoot集成WebSocket - 仅此而已-远方 - 博客园 (cnblogs.com)

为什么不使用HTTP 协议? 因为HTTP是单工通信,通信只能由客户端发起,客户端请求一下,服务器处理一下,太麻烦了。

TCP


来源:百度百科

实现方法
  • 后端:由WebSocket类来实现主要功能

引入依赖spring-boot-starter-websocket,即可使用几个固定的注解。
使用了多线程来保存每个用户的连接:(ConcurrentHashMap线程安全;避免了多个线程竞争同一把锁的情况,大大提高了性能。)

    private static Map clients = new ConcurrentHashMap();

发送消息:

item.session.getAsyncRemote().sendText(message);
  • 前端chatroom.html

html5规范中为websocket定义了一系列的API,可以直接使用。
建立连接:

this.webSocket = new WebSocket("ws://localhost:8888/websocket/" + this.sendUser);

发送消息:

 this.webSocket.send(JSON.stringify(message));

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5685960.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存