文章目录
项目介绍:
仿照CSDN,建立一个博客系统,普通用户可以通过浏览器实现对自己博客的增,删,查,改等操作;网站管理员可以实现网站内所有博客和用户的查,删、改等操作;
项目的功能详解:
1.在注册和登录页面可以进行用户的注册和登录
2.在首页界面会显示网站内的所有博客
3.在我的博客界面能够显示该用户的所有博客
4.在标签管理界面中,能够显示该用户所有的标签,并且能够实现新增标签、删除标签和修改标签等功能
5.在创造博客界面中,用户能够发布自己的文章
6.在用户管理界面中,普通用户能够实现销毁用户的功能,实现该功能后,用户的所有信息(博客,标签)全部会被删除
7.在首页中还实现搜索用户功能,进行搜索用户时,如果存在该用户,会显示他的所有博客信息
项目的实现:
整体框架:
采用MVC框架实现,因此我们分为前端页面交互模块、后端数据管理模块、后端业务处理模块
(百度解释:MVC(Model View Controller)是软件工程中的一种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。)数据交互格式:json
JSON 是一种轻量级的数据交换格式(key-value格式)。采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率
模块介绍:
前端页面交互模块:
前端页面主要使用 HTML、CSS、JS技术,实现与用户的交互页面,即浏览器界面
由于个人对前端知识知识初学阶段,无法构造整个前端交互模块,所以在Amaze UI网站中,寻找了一个交互页面,自己在此基础上进行修改,达到与用户进行交互的目的。后端业务管理模块:
后台业务管理模块主要功能是正确处理浏览器发送来的请求。主要分为两类请求,一是从后端数据管理模块获取数据,并发送至前端交互模块;二是从前端交互模块获取信息,发送至后台数据管理模块,使之永久保存
后端业务处理模块,我们使用了第三方开源库cpp-httplib,该库是一种Header-only模式的库,即定义和实现都在头文件当中,我们在使用的时候,也比较方便,也需要包含头文件httplib.h。
在进行注册路由的时候,我们采用RESTful 规范(每一个URI代表1种资源;客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;),使得业务处理模块结构简单,清晰,可扩展性较强。会话模块:
会话模块嵌套于业务处理模块中,会话模块主要用于表示一个用户,当一个用户执行登录操作成功之后,会话模块要对其产生一个唯一的session进行标记,随着应答返回给浏览器;这样我们就可以唯一标识一个用户,并且知道该用户的权限。
后端数据处理模块:
后端的数据我们使用Mysql数据库进行存储,Mysql数据库是一种关系型数据库,由于性能高,成本低,可靠性好等特点,被广泛使用。
为了安全,我们在业务处理模块和数据库之间,封装了一层,用于两者之间的交互。日志模块:
该模块主要用于记录服务端的运行状态,当业务处理模块和数据处理模块之间出现问题时,日志模块要对其进行记录,方便我们查看问题。
模块设计:
后端数据处理模块:
我们要存储的内容主要是用户信息,文章信息,而我们还需要对文章进行分类,所以还需要存储标签信息,所以我们需要设计三张表,用于存储信息。
数据库表设计:
用户信息表
信息 Value 用户ID user_id(主键) 用户名 user_name(唯一键) 用户密码 user_password 博客信息表
信息 Value 博客ID blog_id(主键) 用户ID user_id(外键) 标签ID tag_id(外键) 博客标题 title 博客内容 content 最后提交时间 last_post_time 标签 信息表
信息 Value 用户ID user_id(外键) 标签ID tag_id(主键) 标签名称 tag_name 数据库的封装层:
class userTable{
public:
userTable(MYSQL* mysql)
:_mysql(mysql)
{}
//新注册一位用户
bool Insert(const Json::Value& user);
//注销某位用户
bool Delete(const int user_id);
//更新指定用户的信息
bool Update(const int user_id,Json::Value& user);
//获取所有用户信息
bool Get_all(Json::Value* out_user);
//获取指定用户信息
bool Get_one(const int user_id,Json::Value* user_blog);
//登录
bool Login(Json::Value& user,Json::Value* out_user)
private:
MYSQL* _mysql;
};
class tagTable{
public:
tagTable(MYSQL* mysql)
:_mysql(mysql)
{}
//添加一个标签
bool Insert(const Json::Value& tag);
//删除指定的标签
bool Delete(const int tag_id);
//修改指定的标签
bool Update(const int tag_id,Json::Value& tag);
//获取数据库中所有的标签
bool Get_all(Json::Value* out_tag);
//获取指定某个标签
bool Get_one(const int tag_id,Json::Value* out_tag);
private:
MYSQL* _mysql;
};
class blogTable{
public:
blogTable(MYSQL* mysql)
:_mysql(mysql)
{}
//写添加一个博客
bool Insert(const Json::Value& blog);
//删除指定的博客
bool Delete(const int blog_id);
//修改指定的博客
bool Update(const int blog_id,Json::Value& blog);
//获取数据库中所有的博客
bool Get_all_blog(Json::Value* out_blog);
//获取指定用户的博客
bool Get_user_blog(const int user_id,Json::Value* out_blog);
//获取属于某个指定标签的博客
bool Get_tag_blog(const int tag_id,Json::Value* out_blog);
//获取指定某篇博客
bool Get_one_blog(const int blog_id,Json::Value* out_blog);
private:
MYSQL* _mysql;
};
后端业务处理模块:
采用httplib库搭建http服务器的流程:
实例化一个Server的对象
给Server对象注册请求处理路由,即针对不同的请求调用相应的回调处理函数
搭建TCP服务器开始监听
收到请求连接之后,建立连接,创建一个线程就处理该连接发起的请求
初始化mysql操作句柄,实例化出数据库表的对象,调用回调处理函数
线程的处理逻辑:
接收HTTP请求的头部信息,解析头部信息;
根据解析的头部信息中的Content-Length,获取指定长度的正文信息
实例化Request和Response对象,将解析的请求信息填充到Request对象中,从请求处理路由表中获取对应的回调处理函数
回调处理函数执行完毕后,获取完整的Response对象,组织http响应,发送给客户端
日志模块:
日志模块主要用于检测后台代码是否正常运行,我们将日志分成5个等级:
INFO、WARNING、 ERROR、 FATAL、 DEBUG
由于我们比较关注服务端的运行情况,所以我们将日至登记为INFO的输入到一个文件,其余四类放到一个文件;
日志文件的存储信息: 时间 日志等级 对应信息 产生该信息的文件 行号
具体效果如下所示:
会话模块:
我们在此模块中主要的目的是用于唯一标识用户和辨别用户权限,我们采用MD5码作为session返回给浏览器,用于表示用户