黑马新出的SpringBoot3项目后端总结

2024-05-14 06:44

本文主要是介绍黑马新出的SpringBoot3项目后端总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!





基础篇-00_SpringBoot3_Vue3导学课程_哔哩哔哩_bilibili  这个是视频链接

这个新课程里面用了一些企业里会用的注解例如Validated这种,业务流程清晰明了简单上手,算是可以了解最基本的Springboot开发流程,方便上手和快速入门

主要是下面这几个部分

目录

引入Validation依赖

全局异常处理器

创建全局异常处理器

指定要处理的类的类型是Result类

拦截器HandlerInterceptor

自定义拦截器

在配置类里面注册拦截器

ThreadLocal的使用

 preHandle

afterCompletion

自定义注解来做参数校验

自定义注解State

自定义校验数据类StateValidation实现ConstraintValidator接口

在需要校验的地方使用自定义注解

(小重点)分组校验的实现

 定义分组

 定义校验项指定归属的分组

检验时指定要检验的分组

使用图床替代OOS上传图片简化实现

Redis实现登录逻辑优化

多环境开发

配置优先级

单文件配置

多文件配置

多环境分组

JWT的使用

引入依赖

jwt令牌的创建

jwt令牌的解析

其他常用注解

JsonIgnore

Data

Validated 


引入Validation依赖

引入springboot的Validation起步依赖,这个依赖的作用是对应参数使用的注解生效

这个依赖提供了许多的注解例如

  • Email
  • Pattern
  • NotNull
  • NotEmpty
  • URL
  • 等等
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><version>3.2.5</version>
</dependency>

我们看看Controller里面用的Pattern注解,这个就是Validation提供的注解

我们之前要写一大堆的逻辑,来判断username和password是否符合规范

但是我们可以使用Pattern注解直接写正则表达式,这样子就可以简化很多流程了

我们来看看这个项目中Validation其他注解

Validated注解,我们用在Controller上,这个是让我们的实体类User里面的注解生效

看看我们的实体类User

NotNull   不能不传

NotEmpty  必须是字符串,且不能是空字符串

记住NotNull和NotEmpty是有区别的

Pattern   使用正则表达式

Email    判断是否是合理的邮箱

URL 判断是否是URL

这些注解就是Validation提供的注解

但是我们的Validation注解要结合全局异常处理器来使用,不然抛出异常的话我们无法处理


全局异常处理器

例如我们方法上面的注解Pattern匹配失败了,那么它就会报异常

而且它是整个方法都异常了,所以我们不能try catch finally

所以我们要写一个全局异常处理器,定义通用异常抛

创建全局异常处理器

我们自己创建一个全局异常处理器类,GlobalExceptionHandler

注意我们有两个注解

RestControllerAdvice

ExceptionHandler(Exception.class)

RestControllerAdvice,因为我们抛出异常的地方在我们的RestController中

ExceptionHandler(Exception.class)这个注解要写到我们要抛出异常的类上

指定要处理的类的类型是Result类

你看我们Controller里面也就是写了那个Pattern注解的,就是可能抛出异常的,类型是Result类型

所以我们的ExceptionHandler(Exception.class)对应的方法要是Result

e.getMessage是获取我们的错误信息,但是有写异常我们获取不到错误信息,这样子返回给前端不太友好

所以

StringUtils.hasLength我们用这个来判断我们是否e.getmessage是否有信息

记得我们的Validation注解要结合 全局异常处理器来使


拦截器HandlerInterceptor

自定义拦截器

jwt我们就不说了,因为我们不可能在每一个Controller都解析我们的token判断是否登录,所以我们在拦截器里面来解析我们的token,如果我们token解析成功的话,我们就放行

我们的拦截器记得加Component注解来扫描包,然后注入到我们IOC容器

我们自己弄一个类名字叫LoginInterceptor,然后连接HnadlerInterceptor接口,来重写里面的方法

例如我们的preHandler,也就是我们拦截前

我们从请求头里面拿出我们的token,然后解析,如果不报错解析成功的话,我们就return true放行

否则我们就拦截return false

在配置类里面注册拦截器

然后我们把自己写的拦截注册我们的WebConfig配置类里面,也就是我们的WebMvcConfigurer

里面有一个addInterceptors方法,就是添加我们的拦截器

配置类上面要记得加上Configuration注解,使我们的配置生效

我们因为之前把我们自定义拦截器Intercptor弄到IOC容器里面了,所以我们这里可以引入然后AutoWired自动注入

然后我们在addInterceptors()里添加我们的拦截器,但是我们有两个路径是不能拦截的

也就是我们的登录接口和注册接口,所以我们用excludePathPatterns()里面不拦截我们的登录接口和注册接口

然后修改我们的Controller,因为的解析Token的流程已经弄到拦截器里面了,我们不需要在Controller里面来解析Token


ThreadLocal的使用

如果我们想要使用我们存到Token里面的信息的时候,我们就要从请求头获取然后解析

但是我们不可能每次想要用这些信息,然后就每次都从请求头拿出来我们的Token解析吧,这样子太麻烦了,我们直接优化成TreadLocal

ThreadLocal线程池

我们的线程池有线程隔离的效果,我们一般往里面存类似于用户名这种东西,让这个能全局使用

方便取出来弄sql语句或者调用其他函数之类的

我们可以用TreadLocal来存全局变量,这样子就方便了很多

我们要改成从ThreadLocal里面获取我们的数据,但首先我们要往我们的ThreadLocal里面存取我们的数据

一般来说我们要new 一个ThreadLocal线程池 然后用set get remove三个方法

黑马把这些步骤封装成了一个工具类,我们直接使用就行

 preHandle

我们在拦截器的逻辑里面,把我们的业务数据存储到我们的ThreadLocal中

 因为我们token解析的时候是解析成Map的

 我们在拦截器里面,把解析token得到的Map存到我们的ThreadLocal线程池里面

因为我们之前是存了一个map进我们的ThreadLocal

所以我们拿出来的时候,也是一个Map

然后我们用map.get()来取出我们的key对应的

其实我们这个map里面一般放的就是我们的username,id这些,方便我们全局调用的变量

我们还要在线程结束之后把我们的往线程池里存的map移出去,防止占用内存拦截结束后,我们还要记得after之后,清空我们的TreadLocal里面的东西

afterCompletion

所以拦截器里面我们要多重写一个方法,afterCompletion


自定义注解来做参数校验

分为三步

一 自定义注解State

二 自定义校验数据类StateValidation实现ConstraintValidator接口

三 在需要校验的地方使用自定义注解

自定义注解State

我们的类是@interface,我们要写的是注解

@Documented 

这是一个元注解(meta-annotation)用于标记该注解应该包含在生成的文档中

@Target( ElementType.FIELD) 

 元注解,作用在属性上

@Retention(RetentionPolicy.RUNTIME ) 

元注解,注解在我们运行阶段任然要保留,我们这里是Runtime所以是运行阶段要保留

@Constraint(validatedBy = {})

用来指定将来谁给我们自己写的state注解提供校验规则,并指定了 StateValidation.class 作为校验规则的提供者

提供校验失败后的提示信息

String message() default "{jakarta.validation.constraints.NotEmpty.message}";

指定分组

Class<?>[] groups() default {};

负载,获取到State注解的附加信息

Class<? extends Payload>[] payload() default {};

因为我们指定了StateValidation类作为我们的校验规则,所以我们要写一个这个类出来,然后里面实现方法

自定义校验数据类StateValidation实现ConstraintValidator接口

创建规则类,实现 ConstraintValidator接口

我们的ConstraintValidator接口有两个参数

第一个参数,给哪个注解提供校验规则

第二个参数,校验的数据类型

我们是给我们刚刚的State注解提供校验规则,然后我们检验的数据类型为String

重写isValid方法,在isValid这个方法里写我们的校验规则

在需要校验的地方使用自定义注解

然后我们就可以把State注解写到我们的实体类里面


(小重点)分组校验的实现

分组校验

我们添加一下发现添加失败了,失败的原因是我们的id不能为null

因为我们刚刚实体类的ID设置了notnull

但是我们新增和删除,一个不需要传id,一个需要传id

那我们可不可以用校验来进行分组呢?

添加的时候的时候我们需要传ID

新增的时候我们不需要传ID

所以我们来弄一下分组校验

 定义分组

我们用groups来指定我们的注解是哪一个校验组的

 你看我们在这个运行失败的实体类下面弄多了两个自定义接口,名称就好和用途一样

public interface Add extends Default {};
public interface update extends Default{};

一个是Add代表添加,一个是Update代表更新

 定义校验项指定归属的分组

然后我们在Controller里的Validated,指定我们的生效的类型

检验时指定要检验的分组

 如果不指定的话,默认分为为Default,默认组

我们一开始时这样子写,但是我们只定义了Add和Update这两个分组

所以我们就算不些这两个,我们默认分组就包含这两个了

因为我们这样子继承默认分组

就说明我们这两个类其实默认都有了这两个指定对象

所以我们不用大费周章所有都写

(groups = Add.class,update.class),因为如果不写默认就是这两个


使用图床替代OOS上传图片简化实现

我们可以弄图床,然后后端只存我们的url,就可以拿到我们的图片了,我们就不用使用oos

我们随便找一个免费图床,上传图片然后把url存入到我们的数据库就行了,可以不给予OOS简化实现


Redis实现登录逻辑优化

因为jwt令牌无法在某些特定场景做到主动过期,所以我们要结合Redis来做token主动过期

因为我们之前是在jwt里面设置过期时间,拦截器里面解析token,如果解析成功就放行,解析失败就拦截。但是如果我们修改密码之后,我们会得到一个新的token,但是我们旧的token还没有过期,按照之前的逻辑,如果有人能拿到我们的旧的token写入前端请求头,它还是能通过我们的拦截器然后实现登录

所以我们要结合redis优化登录,当更新密码之后,我们往redis里面存新的token,然后主动过期旧的token

所以我们登录的时候,我们要把token存到redis里面

修改密码之后,我们要把原本的token从redis中删除

 然后我们的拦截器的逻辑就是从我们的Redis里面来取出我们的token,然后再来用jwt解析token


多环境开发

配置优先级

我们的属性配置有这四种方式

项目中的application.yml文件

jar包目录下的application.yml文件

操作系统环境变量

命令行参数

然后我们的配置的优先级,从上往下递增,下面的优先级高 


基本使用

分为单文件配置和多文件配置

单文件配置

Profile隔离应用程序配置

首先我们用spring:config来弄三个不同的环境,分别是test,dev和pro

spring:config:activates:on-profile

spring:profiles:active,来指定哪一个环境生效

然后我们在spring:profiles:active的下面配置我们的通用属性

我们的自定义配置属性会覆盖我们的通用属性


多文件配置

我们也可以不在一个配置文件来写,我们可以直接写多个配置文件

例如这样子

我们要在通用配置里面来指定激活的环境,我们的application.yml就是我们的通用配置,其他就是其他配置,我们可以在通用配置里面来指定使用其他配置


多环境分组

如果我们直接这样子写的话,我们的application文件太长了,不利于维护

所以我们使用分组,不同的配置文件写不同的内容,然后弄成同一组统一生效

例如我们的server就写端口配置

我们的DB就写数据库配置

我们的self就写自定义配置

 然后我们把这三个配置文件弄成一组

active来指定我们哪个配置文件生效,这样子就是我们整个组都生效了,简洁还方便维护


JWT的使用

引入依赖

首先我们要引入一个java-jwt依赖

<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version>
</dependency>

然后我们使用jwt就行了

jwt令牌的创建

载荷是用来存我们的信息的,我们要把信息存到map里面

然后添加载荷,用“user“当变量存进去,以后取出来也用“user”取

然后withExpiresAt添加过期时间

用sign()里面指定我们的加密算法,

Algorithm是我们的jwt提供的一个加密算法
Algorithm.HMAC256("KIRA")然后我们用“KIRA”来当作这个算法的密钥

jwt令牌的解析

JWTVerifier jwtVerifier = 
JWT.require(Algorithm.HMAC256("KIRA"))
.build();

我们的解析算法和密钥要和我们加密的时候一模一样我们才能成功解析出来

用构造来弄我们的token解析器,类型是JWTVerifier

使用方法vertify(token),来解析我们的token

从解析出来的token拿出Map,这个Map里面存了我们之前存进去的一些数据   

dcoded JWT.getClaims()

这个解析出来的存数据的Map的类型是Map<String,Claim>

之前我们的数据是存到“user”这里的,所以我们取出存的数据的时候用“user”取出

然后我们把这个生成token和解析token弄到一个工具类里面,这样子就简化了代码方便了使用。


驼峰映射

在application文件中开启驼峰映射,这样子我们的sql语句里面的字段才可以自动转换匹配mysql数据库的字段


动态SQL语句

因为我们有些参数不是必须传的,所以我们的后端的SQL语句不能写死,所以我们要写一个xml文件来写一个动态SQL语句,来实现动态传参数

 

 记住,我们的Resource的Mapper的目录,要和上面我们写的Mapper的目录一一对应

看看我们目录的对应 

 Resource其实就是我们的根目录

然后我们安装一个Mybatis插件,如果我们的xml文件和Mapper文件对应上的了话,左边就会有Mapper的标志

 


其他常用注解

JsonIgnore

这个注解的用处是,当我们这个类转化成Json传输的时候,这个参数不参与转换成Json,这样子我们的密码这种隐私信息就不会返回给前端了

Data

lombok的一个自动赋值注解,get,set

Validated 

我们直接在这个Controller类上面用Validated注解,这样子下面使用的Validation注解全都可以生效了

 也可以让POJO实体类里的Validation注解生效

JsonFormat

 用正则表达式来格式化我们的日期

RequestHeader 请求头

RequestParam 参数

RequestBody 请求体

上面三个不必多说

PathVariable 要求路径参数名和形参名一一对应

例如这种


Override 

小提一嘴,这个注解的意思是这个方法是父类的方法,我们可以重写

这篇关于黑马新出的SpringBoot3项目后端总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/988036

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

springboot3打包成war包,用tomcat8启动

1、在pom中,将打包类型改为war <packaging>war</packaging> 2、pom中排除SpringBoot内置的Tomcat容器并添加Tomcat依赖,用于编译和测试,         *依赖时一定设置 scope 为 provided (相当于 tomcat 依赖只在本地运行和测试的时候有效,         打包的时候会排除这个依赖)<scope>provided

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000