欢迎光临
我们一直在努力

案例综合练习-博客系统

完整代码  gitee:优今夏/项目仓库

项目介绍

使用SSM框架实现一个简单的博客系统

共5个页面

  • 用户登录
  • 博客发表页
  • 博客编辑页
  • 博客列表页
  • 博客详情页
  • 功能描述

    用户登录成功后,可以查看所有人的博客,点击<<查看全文>>可以查看该博客的正文内容,如果该博客作者为当前登录用户,可以完成博客的修改和删除操作,以及发表新博客

    页面预览

    用户登录

    博客列表页

    博客详情页

    博客发表/修改页

    1. 项目公共模块

    项目分为控制层(Controller),服务层(Service),持久层(Mapper)各层调用关系如下

    1.1 统一返回结果实体类

    1.2 统一返回结果

    1.3 定义项目异常

    1.4 统一异常处理


    数据准备

    2. 业务代码

    2.1 持久层

    Mapper

    2.2 实现博客列表

    约定前后端接口

    [请求]
    /blog/getList GET

    [响应]
    {
    "code": 200,
    "errMsg": null,
    "data": [{
    "id": 1,
    "title": "第⼀篇博客",
    "content": "111我是博客正⽂我是博客正⽂我是博客正⽂",
    "userId": 1,
    "updateTime": "2024-08-22 11:27:03"
    },
    …..
    ]
    }

    实现服务器代码

    1.定义接口返回实体

    日期的返回格式有两种方法实现


    2.实现Controller

    3. 实现Service

    实现客户端代码

    测试

    2.3 实现博客详细

    约定前后端接口

    [请求]
    /blog/getBlogDetail?blogId=1

    [响应]
    {
    "code": 200,
    "errMsg": null,
    "data": {
    "id": 1,
    "title": "第⼀篇博客",
    "content": "111我是博客正⽂我是博客正⽂我是博客正⽂",
    "userId": 1,
    "updateTime": "2024-08-22 11:27:03"
    }
    }

    实现服务器代码

    参数校验: jakarta。validation

    这个接口中,blogId不能为空,可以借助校验. @NotNull , jakarta.validation 帮我们完成参数校验,免去繁琐的串 javax.validation 是JavaBeanValidationAPI的包名,这个API允许开发者通过注解 (如 @NotBlank , @Null 等)来声明对象的验证规则,然后在运行时自动验证这些对象.

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>


    将 BlogInfo 转为 BlogInfoResponse 的操作封装起来


    实现客户端代码

    测试

    2.4 实现登录

    分析

    传统思路:

    • 登录页面把用户名和密码提交给服务器
    • 服务器端验证用户密码是否正确,并返回校验结果给后端
    • 如果密码正确,则在服务器端创建  Session ,通过Cookie 把sessionId 返回给浏览器

    问题:

    • 服务器重启,Session丢失
    • Session 存储在内存中(耗费服务器资源)
    • 集群环境下无法直接使用Session

    原因分析:

    开发项目,在企业中很少会部署在一台机器上,容易发生单点故障(单点故障:一旦这台服务器挂了,整个应用就无法访问了)所以通常情况下,一个Web应用会部署在多个服务器上,通过Nginx等进行负载均衡。此时,来自同一个用户的请求会被分发到不同的服务器上

    此时需要另一种方案:令牌技术

    令牌是一个用户身份的标识,本质是一个字符串

    优点:

    • 解决了集群环境下的认证问题
    • 减轻了服务器的存储压力

    JWT令牌

    令牌本质就是一个字符串,他的实现方式有很多,我们采用一个JWT令牌来实现

    官网:JSON Web Tokens – jwt.io

    JWT令牌生成和校验

    1. 引入依赖

    <!– https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api –>
    <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
    </dependency>

    <!– https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl –>
    <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
    </dependency>

    <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <!– or jjwt-gson if Gson is preferred –>
    <version>0.11.5</version>
    <scope>runtime</scope>
    </dependency>

    2. 使用Jar包中提供的API来完成JWT令牌的生成和校验

    约定前后端接口

    [
    请求]
    /user/login

    [参数]
    {
    "userName": "test",
    "password": "123456"
    }

    [响应]
    {
    "code": 200,
    "errMsg": null,
    "data": {
    "userId": 1,
    "token":
    "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiemhhbmdzYW4iLCJpZCI6MSwiaWF0IjoxNzI0OTE5NjgyL
    CJleHAiOjE3MjQ5MjE0ODJ9.5hwKlAh2jPPBNn3uPja4JTGguZNB3QrpRoPqCep7qME"
    }
    }
    //验证成功, 返回token, 验证失败返回 ""

    实现服务器代码

    创建JWT工具类:可以生成token和解析

    创建请求和响应实体类

    参数不合法会抛出异常:

    可以单独获取想要的异常信息(原本的信息太长)


    实现Controlled

    实现Service

    实现客户端代码

    //存储数据
    localStorage.setItem("user_token","value");

    //读取数据
    localStorage.getItem("user_token");

    //删除数据
    localStorage.removeItem("user_token");


    2.5 实现强制要求登录

    当用户访问博客列表页和博客详情页时,如果用户当前尚未登录,就自动跳转到登录页面

    可以采用拦截器来完成,token通常有前端放在header中,从header中获取token,并校验token是否合法

    添加拦截器

    ERROR com.example.springblog.common.util.JwtUtils — token解析失败,token:eyJhbGciOiJIUzI1NiJ9.ehyJuYW1lIjoiemhhbmdzYW4iLCJpZCI6MX0.8GHwbRNe44MuWq-UteQFqZ_-oIc_649gBovAn56XSeE  null

    解析失败会返回null

    实现客户端代码

    浏览器不会自动把 localStorage 中的 token 放到请求头里,必须由前端代码显式实现

    前端请求时,header中统一添加token,后端返回异常时,跳转登录页面,代码逻辑卸载common。js中

    2.6 实现显示用户信息

    用户信息可以随着用户登录而发生改变

    1. 如果当前页面是博客列表页,则显示当前登录用户的信息

    2.如果当前页面是博客详细页,则显示该博客的作者用户的信息


    由于前端代码能力有限,改为在后端处理

    约定前后端交互接口

    在博客列表页,获取当前登录用户的用户信息

    [请求]
    /user/getUserInfo?userId=1

    [响应]
    {
    "id": 1,
    "username": "test",
    "githubUrl":"bite.gitee.com"
    }

    在博客详情页,获取当前文章作者的用户信息

    [请求]
    /user/getAuthorInfo?blogId=1

    [响应]
    {
    "id": 1,
    "username": "test",
    "githubUrl":"bite.gitee.com"
    }

    实现服务器代码

    定义返回接口实体类

    服务层可以相互调用

    实现客户端代码

    2.7 实现用户退出

    前端直接清楚token即可

    实现客户端代码

    2.8 实现发布博客

    约定前后端交互

    [请求]
    /blog/add

    [参数]
    {
    "userId":1,
    "title":"标题",
    "content":"正⽂"
    }

    [响应]
    {
    "code": 200,
    "msg": "",
    "data": true
    }
    //true 成功
    //false 失败

    实现服务器代码

    客户端代码

    editor.md简单介绍  Editor.md – 开源在线 Markdown 编辑器

    是一个开源的页面,markdown编辑组件

    配置使得html生效

    设置背景等细节

    2.9 实现删除/编辑博客

    进入用户详情页,如果当前登录用户正式文章作者,则在导航栏中显示【编辑】【删除】按钮,用户点击时则进行相应的处理

    需要实现两件事: 1. 判定当前博客详情页是否要显示【删除】【编辑】按钮

    2.实现编辑/删除逻辑(采用逻辑删除)

    约定前后端接口

    1. 修改博客

    [请求]
    /blog/update

    [参数]
    Content-Type: application/json
    {
    "id": "4",
    "title": "测试修改⽂章",
    "content": "在这⾥写下⼀篇博客"
    }

    [响应]
    {
    "code": 200,
    "msg": "",
    "data": true
    }

    2. 删除博客

    [请求]
    /blog/delete?blogId=1

    [响应]
    {
    "code": 200,
    "msg": "",
    "data": true
    }

    实现服务器代码

    定义修改接口实体类

    实现客户端代码

    blog_detail.html

    blog_update.html

    测试

    以zhangsan的身份登录

    3.10 加密/加盐

    加密介绍

    在MySQL数据库中,需要对密码,身份证号,手机号等敏感信息进行加密,以保证数据的安全性,如果使用明文储存,当黑客入侵数据库时,就可以轻松获取到用户的相关信息,从而对用户或者企业造成信息泄露或者财产损失

    目前我们用户的密码还是明文设置,为了保护用户的密码信息,我们需要对密码进行加密

    密码算法分类

    密码算法主要分为三类:对称密码算法,非对称密码算法,摘要算法

    加密思路

    博客系统中我们采用MD5算法来进行加密


    测试:

    实现服务器代码

    由于该博客系统没有注册功能,只介绍登录场景

    修改接口

    修改数据库中的密码

    赞(0)
    未经允许不得转载:171主机测评 » 案例综合练习-博客系统
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址