前言:为巩固之前学习的知识,同时锻炼自己的代码能力,项目经验,熟悉前后端交互方式等,特此完成一个博客平台系统。(总之,为了学习,为了进步)
博客平台:本项目实现了一个简单的博客系统,其主要功能包括用户登录,用户注册,用户修改头像,发布博客,查看博客详情,编辑博客,发布博客等功能,有助于用户学习和记录知识等。该项目大致分为两个模块:用户模块,博客模块,下面主要从这两个模块开始介绍本项目。
一、数据库设计
1. 创建数据库 java_blog_spring
2. 创建两张表 user 表和 blog 表;
其中 user 表中的字段及其含义为
{
id int(11)(用户id,主键 自增);user_name varchar(128)(用户名,unique,not null);password varchar(128)(用户密码,not null);github_url varchar(128)(用户github地址);deleteFlag tinyint(4)(删除字段,1表示已删除,0表示未删除);create_time datetime(表示创建时间);update_time datetime(表示更新时间);photo varchar(256)(用户头像地址)
}
blog表中的字段及其含义为
{
id int(11)(用户id,主键 自增);title varchar(200)(博客标题);content text(博客正文);user_id int(11)(博客作者 id);deleteFlag tinyint(4)(删除字段,1表示已删除,0表示未删除);create_time datetime(表示创建时间);update_time datetime(表示更新时间);
}
二、全局处理
1. 统一数据格式返回
方便前后端交互,方便前端对后端的响应进行处理。
1)自定义结果实体类Result,其属性包括 code(业务码),errMsg(错误信息),data(接口响应的数据,泛型);其静态方法有 success(T data),在请求成功时可调用,参数data,表示给前端返回的数据内容;fail(String errMsg),在请求非法时可调用,参数 errMsg,表示非法请求的错误信息。其中,Result 类中的属性 code 通过自定义枚举类来实现,保证 code 值的正确性。
2)自定义响应通知类,实现 ResponseBodyAdvice 接口,并重写其 supports 方法和 beforeBodyWrite方法,supports方法:判断是否要执行beforeBodyWrite方法,true为执行,false不执行;beforeBodyWrite方法:对response方法进行的具体操作处理,如果返回的结果已经时Result类时,需直接返回,另外,如果返回的结果时String类型,需通过ObjectMapper进行特殊处理。
2. 拦截器
1)自定义登录拦截器实现 HandlerInterceptor 接口,并重写 preHandle方法,表示是否应该对请求进行拦截。
2)自定义配置类实现 WebMvcConfigurer 接口,并重写 addInterceptors 方法,表示拦截哪些请求,重写 addResourceHandlers,指向静态资源的路径,(例如上传图片时会用到)。
3. 全局异常处理
自定义异常处理类,实现处理全局异常的方法,并添加 @ExceptionHandler 注解,使得在发生相应异常时,自动调用该方法来进行处理。
三、用户模块
用户模块的实现在 UserController 类中
1. 登录功能
1)前端页面
2) 后端实现
使用 JWT 令牌(Json Web Token)存储用户登录信息;后端首先校验用户信息的合法性,当校验成功时,为该用户生成令牌,将用户的 id 存储在 token 中(方便后续获取用户信息),并设置过期时间,客户端将令牌存储在 Local Storage 中;后续客户端的请求都会带着令牌,服务器会校验令牌,来决定是否拦截用户的请求。
2. 注册功能
1)前端页面
2)后端实现
使用 MD5 算法加密、UUID 加盐共同加密用户的密码,保证用户密码的安全性。服务器首先判断用户注册信息的合法性,用户名不能重复,两次密码需输入一致等;判断合法后,将用户的密码和UUID 生成的随机盐值,使用 MD5 算法进行加密后,存储在数据库中。
3. 获取当前登录用户信息(接口)
服务器根据用户的请求中的 token 是否存在判断用户登录状态,并根据 token 获取到存储在 token中的 登录用户 id,根据 id 从数据库中获取用户信息,并返回给前端。
4. 获取博客作者信息(接口)
服务器首先根据博客 id 在数据库中查询该博客对应的作者 id(在博客模块中实现),在判断作者 id 合法后,在数据库中,根据作者 id 获取作者信息并返回给前端。
5. 上传用户头像
1)前端页面(非常丑,还是不要看了,以实现功能为主(bushi)),通过 form 表单来实现图片的上传。
2)后端实现
使用 Spring 框架下的 MultipartFile 类实现,设置图片的存储地址 filePath ,如果没有则创建一个,通过getContentType 方法获取图片类型和图片后缀名,通过 UUID 生成随机图片名拼接图片后缀名作为新的图片名 filename,通过 transferTo 方法将图片传输到 filePath/filename 下,即保存图片到指定目录,并通过 token 获取到用户 id,通过 id 将 filename 存储在数据库中,并返回成功与否的响应给前端。
四、博客模块
博客模块的实现在 BlogController 类中
1. 获取博客列表
1)前端页面
2)后端实现
服务器直接从数据库中查询所有博客信息,并返回给前端,前端将每个博客信息拼接为相应的html 片段,并显示在页面上。
2. 查看博客详情
1)前端页面
2)后端实现
后端根据前端传来的博客 id(通过 location.search 获取url中的参数),获取博客详情对象,然后拿到博客作者的 id,再通过 token 获取当前登录用户id,判断 id 是否一致,若一致,则说明当前用户是当前博客的作者,即当前用户具有对当前博客的编辑和删除权限,通过设置 该对象中的属性 isAuthor 为 true,来提供响应的编辑和删除的接口,最后返回该对象给前端。
3. 发布博客
1)前端页面
2)后端实现
后端接收一个 blogInfo 对象,并判断该对象的合法性(某个属性为空等),然后通过 token 获取到当前登录用户的 id,并设置为该对象的作者 id,然后将该对象插入到数据库中,将插入的结果返回给前端。
4. 修改博客
1)前端页面
2)后端实现
首先需要前端将原博客信息显示到页面上,通过查看博客详情接口;然后后端对前端请求中传递的 blogInfo 对象进行合法性校验,此时就不需要再设置博客的作者 id 了,因为只能是博客作者编辑博客,直接更新数据库中对应的博客信息,并将结果返回给前端。
5. 删除博客
采用逻辑删除,服务器创建一个 blogInfo对象,并将前端传来的博客 id 设置为该对象的博客 id,再将 deleteFlag属性设置为 1,表示已删除, 最后将删除的结果返回给前端。
五、项目源码
java_R: 学习java之路 - Gitee.comhttps://gitee.com/rcnhtin/java_-r/tree/master/project/blog_spring