博客系统bug记录文档

文章目录

  • 博客系统Bug记录
    • 前言
    • 后端
      • 前台模块
      • 后台模块
    • 前端

博客系统Bug记录

前言

本文是对博客系统开发中遇到的bug总结,当然这只是一部分记录(●’◡’●)
推荐阅读:

  • 继瑞吉外卖后的又一个项目——SpringBoot+Vue的前后端博客系统

后端

前台模块

  • Bug1:SpringBoot启动失败

    • 问题背景:在使用MyBatisX插件生成代码后,编写完测试Controller,然后启动SpringBoot访问URL,结果报错java.lang.IllegalStateException: Failed to load ApplicationContext

    • 问题原因:tb_user_role是一张关系表,他又两个id,user_id和role_id,MyBatisX在生成对应实体类时,自动添加了两个@TableId注解,由于一张表只能存在一个主键,所以启动报错

    • 问题解决:将两个@TableId注解都删除

      温馨提示:如何一个实体类中不存在@TableId,则无法使用MyBatisPlus的 xxxById方法,关系表好像也不需要使用byId方法

  • Bug2:Knife4j接口文档无法访问

    • 问题背景:我在配置完项目的访问接口前缀为/api/common后,无法访问Knife4j的接口文档,然后又为Knife4j配置了路径映射,但是仍然与计无补
    • 问题原因:暂且未知
    • 问题解决:待定
  • Bug4:自定义接口文档的Footer失败

    • 问题背景:在配置好Knife4j后,我想改动以下Knife4j默认的样式,于是参考Knife4j官网进行了配置,单最终失败了┭┮﹏┭┮
    • 问题原因:版本兼容性问题,Knife4j3.x版本需要配置插件,在创建Docket时要指定为DocumentationType.OAS_30,而我指定的是DocumentationType.SWAGGER_2,这是Knife2.x版本的
    • 问题解决:配置文件中开启增强模式,同时Knife4j的配置类中需要配置插件,同时Docket指定为DocumentationType.OAS_30,完成这三部即可成功配置Footer

    参考文章:

    • 3.24 自定义Footer | Knife4j (xiaominfo.com)

    • 3.0.2版本自定义配置不生效 · Issue #I29TLI · 萧明/knife4j - Gitee.com

    • knife4j 2.x 升级 3.x 版本后自定义文档不生效解决【附自定义响应状态码配置】一壶浊酒伴余生的博客-CSDN博客

  • Bug3:热部署依赖失效

    • 问题背景:在多模块项目中,一个父模块用于控制依赖版本,然后是三个子模块(一个公共模块、一个前台模块、一个后台模块),在父模块中配置好以来,然后在公共模块引入对应的热部署依赖,配置好IDEA的各种热部署相关配置,结果热部署失效

      PS:主要是之前没怎么开发过多模块的项目,单模块项目热部署依赖配置是可以生效的

    • 问题原因:暂且未知

    • 问题解决:待定

  • Bug4:SpringSecurity默认登录页面加载失败

    • 问题背景:引入SpringSecurity后,发送请求后自动重定向到SpringSecurity提供的登录页面,但是页面加载失败
    • 问题原因:SpringSecurity默认的登录页面是通过CDN的形式引入了Bootstrap样式,由于校园网直接拒绝访问该URL,所以页面样式加载很缓慢,甚至直接加载失败
    • 问题解决:本人解决方法是直接开VPN,然后就能成功访问了。方式二是自定义一个登录页面,让SpringSecurity默认跳转到你自定义的登录也买你上

    参考文章:

    • SpringSecurity踩坑之-默认登陆页加载异常_yuyang_ing的博客-CSDN博客
  • Bug5:存入Redis的用户信息出现乱码

    • 问题背景:在进行用户登录操作时,用户输入账号密码后,成功登录需要将用户的信息存入Redis中,用于后续的登录校验。结果存入Redis中的数据出现了乱码
    • 问题原因:Redis无法直接存储Java对象,需要先进行序列化
    • 问题解决:引入FastJson,然后编写一个RedisConfig类,重新注册一个序列化后的RedisTemplate对象,覆盖原有的RedisTemplate对象(原有的RedisTemplate对象是RedisTemplate,而覆盖后是RedisTemplate,Object兼容String)
  • Bug6:无法根据id查询出对应的分类

    • 问题背景:在根据id查询分类时,发现前端无法接收到分类信息,但是在后端接口测试时,却可以得到正确的结果

    • 问题原因:由于分类表的主键ID是Long类型的,传递给前端时,会发生精度丢失问题。在Java中,Long类型的数据是64位有符号整数,可以表示范围在 − 2 6 3 -2^63 263 2 6 3 − 1 2^63-1 2631之间的整数。而在前端中,JavaScript使用的是IEEE 754标准的双精度浮点数(64位),可以表示范围在 − 2 5 3 -2^53 253 2 5 3 2^53 253之间的数值,因此比Java中的Long类型范围更小

    • 问题解决:自定义一个消息转换器,然后将所有传递给后端的Long类型数据转换成String类型

  • Bug7:无法查询出子评论

    • 问题背景:在实现查询文章的评论功能时,我需要实现父子评论功能(即根评论嵌套子评论的二级结构),结果只展示了根评论,没有展示子评论

    • 问题原因:

      问题1:在构建子评论时,出现了逻辑错误(递归出现了问题)

      问题2:添加orderByDesc(Comment::getCreateTime)就无法查询到子评论

    • 问题解决:

      问题1:最终通过Debug的方式定位到了问题,然后进行了逻辑修改

      问题2:暂时没有有较好的方法,但是我改用stream流实现排序

后台模块

  • Bug1:无法新增已删除的标签

    • 问题背景:在实现标签管理时,对于已被删除的标签,无法重新新增
    • 问题原因:这个问题是由于MyBatisPlus导致,它默认的删除都是采用逻辑删除,而我为标签的name添加了唯一性索引,这就导致在新增一个我已经删除的标签时,MySQL直接报错该字段已重复,但是页面上却看不到这条记录
    • 问题解决:
      1. 方案一:重构新增代码的逻辑,在新增之前判断该标签是否在已被逻辑删除的记录中是否存在(这个需要在mapper文件中编写,MP没有提供API)
      2. 方案二:重新新增一个代码逻辑,先删除原有的已逻辑删除的记录,然后再将新增的记录添加到表中
  • Bug2:无法访问Knife4j接口文档

    • 问题背景:在编写完登录接口后,想访问Knife4j提供的网页接口文档,但是却无法访问,后端报错nested exception is java.lang.NumberFormatException: For input string: "doc.html"
    • 问题原因:由于我同时编写了多个Controller,其中有两个Controller我是提前编写好的,没有指定@RequestMapping注解中的value值,导致Knife4j在创建这两个Controller的接口时发生了冲突,导致无法访问(但为什么后台报的是一个数字格式化错误,我真的是一脸懵逼)
    • 问题解决:方法一删除冲突的Controller,方法二为这两个Controller的@RequestMapping的value属性配置对应的非重复的路径
  • Bug3:SpringSecurity拦截了Knife4j的接口请求

    • 问题背景:将后台除登录和Knife4j的请求外,其它请求都设置需要认证后才能访问(.anyRequest().authenticated()),问题出现在,Knife4j接口文档能够在浏览器上访问,但是不显示接口
    • 问题原因:SpringSecurity拦截了Knife4j的接口请求
    • 问题解决:这个不算正面解决,我找遍了官网,以及其他人的解决方法,但是最终都无法解决,最终我是配置所有请求都能允许非登录访问,然后对于需要登录访问的单独配置,这样做有一个缺点,就是后台要登陆后访问的接口很多,所以要配置的有很多,但好在有通配符

    参考资料:

    • 3.5 访问权限控制 | Knife4j (xiaominfo.com)
    • springboot + security + swagger+Knife4j springboot整合swagger swagger优化,接口文档生成多包扫描,security免登陆 生成接口文档_binglong180的博客-CSDN博客
  • Bug4:参数校验失效

    • 问题背景:在实现新增友链功能时,使用@NotBlank对参数进行判空,从而避免项目中出现过多的if-else,但是最终发现判空失效

    • 问题原因:对于spring-boot-starter-validation使用不熟练

    • 问题解决:

      1)对于Parameter类型(请求头)的参数,需要在Controller类上加上@Validated注解

      2)对于Body类型(请求体)的参数,需要在@RequestBody上加上@Validated 或者是 在Controller类上加上 @Validated,在@RequestBody 上加上 @Valid

      综合1)和2),为了便于记忆,统一在Controller类上加上 @Validated,对于1)直接不用干啥了,对于2)直接添加@Valid

    参考资料:

    • Springboot @NotBlank参数校验失效汇总_springboot 参数校验不生效_爱码僧的博客-CSDN博客
    • @NotBlank @NotNull 全局捕获异常返回自定义封装_一个正在努力的菜鸡程序员的博客-CSDN博客
    • spring spring-boot @valid @NotNull @NotEmpty 基本校验使用以及 全局异常优化集成-CSDN博客
    • @Validated和@Valid区别_@vadiation_程序猿拯救世界的博客-CSDN博客
    • spring-boot-starter-validation进行参数校验_吹灭读书灯-CSDN博客

前端

  • Bug1:执行 npm i 报错

    • 问题背景:在下载完Vue脚手架后,使用npm i下载项目所需依赖但是直接报错ENOENT: no such file or directory, open ‘D:\Node\package.json‘
    • 问题原因:这个错误提示表明Node.js在指定的目录(这里是 D:\Node\)下无法找到 package.json 文件
    • 问题解决:先执行 npm init -f 再安装npm i

    参考文章:(npm install执行报错:ENOENT: no such file or directory, open ‘D:\Node\package.json‘_-CSDN博客

  • Bug2:删除最后一页的记录时,会清零需要手动刷新页面

    • 问题背景:在实现后台系统的标签管理时,分页展示了标签数据,第2页只有一条记录时,直接将它删除,跳转到第一页但是数据会清零,需要手动刷新

    • 问题原因:前端分页请求currentPage没有实时更新。由于我删除了最后一页的数据,但是pageNum和pageSize这两个参数没有发生变化,此时分页虽然跳转到第一页,但是发送的分页查寻请求还是最后一页的,由于最后一页的数据已经被删除了,所以此时就显示第一页的数据为空了

    • 问题解决:

      1. 方案一:前端解决,在发送分页请求前先对currentPage参数进行校验,判断当前curentPage是否超出当前最大页码,超出了就重置currentPage为当前最大页码(或者直接置为1)
      2. 方案二:后端解决,配置MyBatisPlus分页插件相关数据,只要检测到当前的页码大于查询出来数据的最大页码,就直接响应第一页的数据

      PS:本人用的是方案二

    参考资料:

    • MyBatis-Plus分页:删除最后一页最后一条数据后显示无数据(后端解决方法) - 简书 (jianshu.com)
    • 解决 “element分页:删除最后一页的所有数据后,currentPage显示正确,但列表内容为空” 的问题-CSDN博客
  • Bug3:添加不符合规范的菜单,会导致加载缓慢

    • 问题背景:在实现菜单管理功能时,在测试添加菜单功能时,如果选择添加主类目,但是路由地址却是多级的,此时菜单能够添加成功,但是刷新页面时,数据加载不出来

    • 问题原因:由于前端的菜单是动态生成的,当我们添加主类目时,如果路由地址是多级的,就会导致Vue去寻找一级菜单,但此时本身就是一级菜单,这就导致Vue加载不出来菜单

    • 问题解决:

      1. 方案一:进行前端校验,规定菜单类型是目录时,必须的单极菜单
      2. 方案二:进行后端校验,当后端检测到添加的菜单类型是目录时,必须的多级菜单(本人使用后端校验)

      虽然经过后端校验,但是还是有问题!

  • Bug4:修改角色无法及时响应

    • 问题背景:在实现系统管理中的用户信息修改功能时,修改用户的角色信息,需要改动一下其它数据才能响应
    • 问题原因:异步更新:Vue在某些情况下会使用异步更新机制,例如在事件处理函数内部或者在计时器回调函数中进行数据修改操作。这种情况下,Vue会将视图更新延迟到下一个事件循环中执行,而不是立即更新视图。
    • 问题解决:可以使用$nextTick方法来在视图更新后执行一些操作。$nextTick会在DOM更新后执行传入的回调函数,确保你可以在更新后获取到最新的DOM结构。

你可能感兴趣的:(Web,Project,Bug记录,bug,java,web)