Java实现小型博客系统
本项目基于SpringBoot、Dubbo、Zookeeper、Redis、MySQL实现了一个分布式博客系统。功能包括账号的增删改查、文章的增删改查、文章评论的增删改查、热点文章的存取、文章的点赞等。
项目地址:https://github.com/ZhangHZ9802/MyLittleBlogSystem-Java-
(看过我之前文章的朋友们应该能看出这是我对之前项目的重构。主要改变有:优化了前端的界面、优化了前后端的交互、取消了数据库的外键由应用层实现数据库的逻辑关系、禁止重复登录变成挤掉之前登录者、优化了数据库向上提供的方法、优化了数据库的存取等)
主要功能实现介绍:
项目整体展示
欢迎界面:
登录界面:
用户主界面:
文章界面:
评论和点赞界面(在文章界面内):
项目启动
项目是基于SpringBoot和Dubbo、Zookeeper实现的分布式项目,但当然也可以在一个主机上运行。项目的运行首先需要有Mysql数据库、Redis数据库和Zookeeper服务器的支持,MySQl数据库也需要提前建立好相应的库和表,建立过程见github。
启动时,需要先启动好Redis和Zookeeper服务器。首先启动provider-mysql,再启动provider-redis,最后启动客户端client即可正常运行。 访问localhost:8091即可进入博客。
项目的主要架构层次
本项目使用了三个服务器来实现后台。分别是client、provider-mysql和provider-redis。各个项目之间的联系如下:
主要实现功能:
- 账号:
a. 账号的注册、修改、删除
b. 账号的登录、登出
c. 账号防止重复登录
d. 不退出浏览器的时候可以延续之前的登录 - 文章:
a. 文章的撰写、存取
b. 文章的修改、删除 - 评论:
a. 评论的撰写、修改、删除 - 点赞:
a. 对文章的点赞、取消与统计
各个项目功能简介
api
定义了服务提供者provider分别提供的数据库功能的接口。
common
定义了远程方法调用时传递的公共对象类。
client
客户端提供前端页面与后端的交互,页面的跳转与内容的显示,通过Dubbo远程调用数据库的服务,获取并展示博客主要信息,并提供增删改的界面。
主要功能有:
- 接收并处理前端请求,调用数据库方法获取数据,返回页面给前端
- 拦截未登录情况下对除登录界面外的页面访问,拦截已经被挤掉的账号的请求(会检测redis中的userID和SessionID对,看当前用户的userID中存的SessionID是否为当前浏览器的sessionID,如果是则可以访问,不然则返回到登录界面)
- 监听所有HttpSession的消失事件(session消失则删除redis中记录的相关登录信息)。
相当于MVC三层架构的Controller层和View层。
provider-mysql
提供MySQL数据库的相关操作功能,实现账号、文章、评论的增删改查功能,并通过Dubbo将这些服务注册到Zookeeper上供客户端使用。
相当于MVC三层架构的Model层。
数据库
注意:这里的数据库之间没有使用外键,数据库之间的逻辑关系都是在应用层实现的。
(外键会使得本来就比较复杂的数据库更加错综复杂,难以维护;对数据库的性能有较大的影响,在高并发的时候尤为突出;容易出现死锁)
CREATE DATABASE zhz_blog;
CREATE TABLE user_account(user_id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,user_account VARCHAR(20) NOT NULL UNIQUE,user_password VARCHAR(20) NOT NULL
);
CREATE TABLE article_comments(comment_id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,comment_article_id INT NOT NULL,comment_owner VARCHAR(20) NOT NULL,comment_contents TEXT
);
CREATE TABLE user_articles(article_id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,article_name VARCHAR(50)NOT NULL,article_content TEXT,article_owner VARCHAR(20)
);
provider-redis
该项目提供Redis数据库的相关操作功能
同样通过Dubbo将这些服务注册到Zookeeper上供客户端使用。相当于Model层。
提供的功能包括:
- 对热点文章的缓存(在客户端请求文章内容时,先从Redis中寻找,如果没有找到则从MySQL中读取,并缓存到Redis中,为其设置一个随机的生存时间(30~60min)。当文章被修改或删除时,先修改数据库中内容,再将Redis缓存删除)
- 防止账户重复登录(在Redis中存userID和SessionID对,当同一个账号在另一个浏览器中登录时,会覆盖掉原有的SessionID。)
- 点赞功能(点赞与取消,文章点赞数的统计)
相关内容展示
前端页面的实现
前端主要使用Html和Thymeleaf实现。
一个典型的页面如下:
大部分的前端页面都是form表单进行请求与数据的传递,使用thymeleaf使得前端页面具有一定的动态性(如该页面中的callback和原账号),使用thymeleaf进行一些判断和循环遍历(在article页面中有,这里就不展示了)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>修改您的账号信息</title>
</head>
<style type="text/css">h2,form{text-align: center;}h2{margin-top: 300px;}input{margin: 5px 5px;}body{background-image: url("/images/ice.jpg");}
</style>
<body>
<h2>修改您的账号信息</h2>
<form action="/zhz/editAccount" method="post">注意:如果不想修改某项,则直接空缺即可。<br/>原账号:<input type="text" th:value="${userAccount}" readonly><br/>新账号:<input type="text" name="newUserAccount" placeholder="请输入您的新账号"><br/>原密码:<input type="password" name="userPassword" placeholder="请输入您的原始密码"><br/>新密码:<input type="password" name="newUserPassword1" placeholder="请输入您的新密码"><br/>新密码:<input type="password" name="newUserPassword2" placeholder="请再输入您的新密码"><br/><p th:text="${callback}"></p><input type="submit" value="确定"><input type="reset" value="重置">
</form></body>
</html>
账号的修改实现
数据库中不再有外键,数据库之间的逻辑关系需要由应用层的代码来实现。
(Redis数据库相关内容的联动不在这里考虑)
@Override@Transactional//添加事务public void updateUserAccount(String account, String newAccount, String newPassword) {//先改密码再改账号,不然找不到账号if (newPassword != null) {userAccountMapper.updateUserPassword(account, newPassword);}if (newAccount != null) {//删除账号信息userAccountMapper.updateUserAccount(account, newAccount);//修改相关文章内容articlesMapper.updateArticleOwner(account, newAccount);//修改文章评论相关内容commentsMapper.updateCommentOwner(account,newAccount);}}
小结
更多的内容大家可以下载我的代码运行看看。github地址:https://github.com/ZhangHZ9802/MyLittleBlogSystem-Java-
如果大家对我的项目感兴趣并有疑惑或者想要指出我的问题也欢迎留言或者私信我。