MHBLOG开发日志
前言
项目github地址:项目地址
本项目是来自三更草堂的SGBLOG项目
本人购买了项目资源跟着视频进行开发学习
开发环境:
JDK21
nvm 1.1.12
nodejs 12.16.3
IDEA 2024.2.2
VSCODE
MYSQL8.0
Redis 7.4
(其实开发工具并不是最重要的,重要的是开发思路)
MHBLOG开发第一天 2024/9/17
今日遇到的最大问题:
使用过高的nodejs版本导致npm install前端工程的时候一直失败
解决办法: 使用nvm来进行nodejs的版本切换控制
今日进度:
- 创建后端工程(基于Springboot和MyBatisPlus)
- 使用项目前端工程(Vue3)
- 通过WebMvcConfig解决跨域问题(犯错: 将origins和originspattern弄混,origins是指定的路径请求,支持String数组,但是不允许通配originpattern支持通配符)
- 实现了将Entity类封装成VO类再封装成ResponseResult返回给前端axios Request请求
MHBLOG开发第二天 2024/9/18
今日在开始项目开发之前学习:MybatisPlus
感觉不用花很多时间学习,还是以熟练使用MyBatisPlus为主
今日遇到的问题:
Spring从2.7版本开始取消支持循环依赖,可以在application.yml(application.properties)当中配置
- sping.main.allow-circular-references: true
来支持循环依赖.(未了解如何解决循环依赖)
使用stream链式编程出现报错变量类型 R 的实例不存在,因此void 符合 R
解决方式:在Entity类当中加上lombok的注解@Accessors(chain = true)
(未了解原理) 2024/9/24日已解决
原理: 首先查看源码
在这里我们可以看到,map方法的参数是一个函数式接口Function
该函数接接受两个泛型参数T,R,在该接口里实现方法apply就是将返回t的类型
也就是说在使用map之后会将流的每一项都转化成R的类型,在使用lombok这个@Access( chain=true )之前,setter的返回值为void,这样子就会显示上图的报错,在使用这个注解之后的setter在赋值完成之后会返回this,返回值就是当前对象,符合泛型对象R的使用
今日进度
- 分类跳转
- 首页文章list获取(分页查询)
- 文章详情页展示(修复了前端模板当中因命名不对的问题导致后端API的数据无法被前端读取到)
感想:熟悉了后端业务的开发流程,根据前端提供的API文档来编写程序真的很舒服
MHBLOG开发第三天 2024/9/20
19号摸了
今日在开始项目开发之前学习:SpringSecurity+JWT
很难,今日未能理解SpringSecurity具体原理,网上的教学版本和实际用到的开发版本方法有差别,很多已经弃用了.包括JWT新版本更新很多方法的实现也不一样了.
今日遇到的问题
- 使用SpringSecurity时5.7版本前后的方法实现问题
- 使用JWT0.9.1版本和1.2.3版本的实现方法问题
- 关于Security实现登录认证
- RedisConfig没有加@Configuration注解导致Redis里的value缓存出现二进制乱码
- 在加上RedisConfig的@Configuration注解的同时实现了Entity类的序列化借口并生成固定的序列化ID导致JACK2SON和序列化冲突在Redis里的Value为Empty
问题解决方案
关于Security 5.7 之后新版本的配置
SpringbootSecurity+JWT的工作流程
今日进度
- 实现友链查询(简单)
- 实现登录接口(困难)
感想:跟着这个项目学习到了项目开发时结构的组成,接下来就是去学习SpringSecurity和JWT的认证使用和原理,加深印象.
MHBLOG开发第四天 2024/9/22
21号学习了SpringbootSecurity和JWT的相关知识,晚上摸了
今日遇到的问题
-
Blog网页在登录时会显示403,但是POSTMAN的Send方法却能返回正确的JSON,查看F12开发者工具可以知道是前端的Axios请求发送的data里命名跟后端不一致,改正过后能正常登录.
修改为userName -
在测试JWTFilter的时候出现错误
Could not read JSON: Unrecognized field "enabled" (class com.minghai.domain.entity.LoginUser), not marked as ignorable (2 known properties: "authorities", "user"])
出现这个错误的原因: 在进行JSON反序列化时,com.minghai.domain.entity.LoginUser类中没有定义enabled字段,但JSON数据中却包含了enabled这个字段。因为这个字段没有被标记为可忽略,所以程序无法识别它,从而导致错误。
解决方法: 将未知字段标记为可忽略@JsonIgnoreProperties(ignoreUnknown = true)
今日进度
- 实现自定义认证过滤器
- 验证异常处理器
MHBLOG开发第五天 2024/9/23
今日遇到的问题
好像没有遇到什么特别大解决了很久的问题
今日进度
- 实现了用户登录功能的统一异常处理
- 实现了用户的登出功能
- 实现了文章的评论查看功能
感想:感觉逐渐的熟悉了开发流程,还有评论查看实现的方法
MHBLOG开发第六天 2024/9/24
今日遇到的问题
好像没有遇到什么特别大解决了很久的问题
今日进度
- 实现了评论回复功能
- 实现了友链评论查看功能
感想:熟悉开发流程,并且了解了MyBatisPlus的自动填充方法还有JAVA的lambda表达式的运用和stream()流方法的使用
MHBLOG开发第七天 2024/9/27
昨天因开发进度太少了所以合并到今天,主要是去研究了阿里云的OSS对象存储
今日遇到的问题
- 阿里云的OSS对象存储使用方法,以及权限部分
通过阅读阿里云的OSS快速入门手册来了解如何使用JAVA SDK来进行OSS存储
- Spring5以上的SpringMVC的参数自动编译部分
在老杜讲的SpringMVC课程当中有提到@RequestParam注解的省略,只要形参的命名和POST请求体里的数据参数名一致就能编译parameter参数并绑定,在语雀笔记里有记载(知道但是忘记了,这里帮我复习到了)
- 在前端工程文件当中的头像上传没有设置卸载token导致上传失败
看了一下前端代码,使用的是ElementUi里的upload组件,只需要在属性上添加:headers
个人在看文档的时候自己写漏写了一个s,就写了个:header导致一致没有将token添加到请求头当中卡了我很久,所以以后查看文档能复制粘贴就复制粘贴最好.
这样子就能携带token访问后端的controller了
- SpringBoot的自动装配顺序问题
在写OssUtil工具类的时候,我将
这两个属性放到了类的无参构造里,这两个属性是创建ossclient链接来上传文件到OSS的,我又在类上使用了 @ConfigurationProperties(prefix = "aliyun.oss") 注解来使用配置文件来给工具类里的属性赋值
而SpringBoot的自动配置是在Bean初始化之后进行配置的,所以在初始化的时候使用
上面的方法就会弹出空指针异常导致SpringBoot服务无法启动,研究过后使用 @PostConstruct注解定义了init方法来在SpringBoot自动配置完Bean之后调用这个方法来初始化参数,随后就能正常启动了 - 上传头像后端显示无法将认证信息转型成LoginUser类
问题代码来自
原因是在SecurityConfig文件里并没有设置引用该方法控制器的访问权限,所以返回的是String类型的 "anonymous"
解决方法是在SecurityConfig文件里添加这个路径的访问权限
今日进度
- 实现了UserInfo界面的用户信息获取并渲染到页面上
- 实现了使用OSS对象存储来进行用户头像的上传 (新知识)
感想:开始使用Debug来调试程序来看问题出现在哪里并解决,第一次在视频说出需求的时候完成需求没有完全依照视频走,感觉成长了一点
MHBLOG开发第八天 2024/10/4
因为前几天出新游戏了都在玩新游戏所以进度搁置了,基本上每天就实现几个功能,算是复习知识也没什么好记录的
今日遇到的问题
- 在AOP开发当中获取对应bussinessName的时候不知道如何获取
在这个功能当中创建了一个自定义的注解@interface SystemLog来作为AOP的切点.
使用@Around来环绕这个切点进行方法增强,我一开始使用的是通过joinpoint来获取HttpServletRequest来获取class再获取Annotaion,我忽略了一点就是这个类获取的其实是request类里的方法,我输入了指定的方法其实是获取不到的,后续查看视频得知是通过ProceedingJoinPoint类(也就是joinpoint)来获取MethodSignature接口,
public interface MethodSignature extends CodeSignature {
Class getReturnType(); /* name is consistent with reflection API */
Method getMethod();
}
signature类能返回的是这个切点的方法也就是
@PutMapping("/userInfo")
@SystemLog("更新用户信息")
public ResponseResult updateUserInfo(@RequestBody User user) {
return userService.updateUserInfo(user);
}
获取这个方法之后调用反射机制的 getAnnotation() 方法来获取方法上的指定注解SystemLog获取值
- 不知道如何获取Controller和Method的全路径
signature.getDeclaringTypeName(), signature.getName() 调用这两个方法就完成了 - 请求入参通过反射方法只能获取参数的类型而获取不到具体的参数
使用JoinPoint里的getArgs()方法获取请求参数,并使用JACKSON来转化为JSON格式输出(视频里用的是fastJson) - 不知道如何获取返回的参数
因为是使用的@Around,所以AOP当中在JoinPoint执行过后输出的日志,直接传入joinPoint.proceed()的返回值并打印就可以了
private void handleAfter(Object proceed) throws JsonProcessingException {
// 打印出参
log.info("Response : {}", new ObjectMapper().writeValueAsString(proceed));
}
今日进度
- 实现了个人用户信息的更新
- 实现了个人用户的注册
- 使用AOP来进行日志记录(AOP知道但是不熟悉,第一次在项目中使用)
- 使用Redis更新浏览次数,减少MYSQL的压力
感想:一些基础的运用复习了一边,在这次AOP使用过后发现自己学Spring的时候因为对AOP的使用很少所以理解有不足的地方.在更新浏览次数的功能当中也加深了对Redis和MYSQL两者直接使用配合的理解
MHBLOG开发第N天 2024/10/23
没想到下一次写博客是在这么久,这段时间玩玩写写终于是把项目给写完并且部署了
这几天遇到的问题
- 其实这个服务后端用的技术基本都是写用户端接口的时候用过的,没什么困难的,就是加深以下对前面知识的了解,唯一新的东西就属EasyExcel了,但是这个使用范围也很简单,稍微看一眼文档就会了
- 写管理端接口的时候印象比较深的就是再一次理解了使用Stream流来进行数据操作的流程,还有Security版本之间的区别(在2024/10/23学习kafka的时候了解到,命名的规则,第一个数字大版本更新是会跟前面的版本用法有出入)
- 其实这个项目有个很严重的Bug,那就是当有个用户在评论区底下作为子评论出现时,这时候如果后台删除了这位用户,那就会导致CommentVo接口的getUserName()方法抛出空指针异常,导致评论区消失.
- 弄清楚了DTO,VO,ENTITY之间的区别使用方法.
最后几个接口其实已经没有什么新的技术了,就是复习巩固之前的知识.