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

news2025/1/21 6:29:14





基础篇-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 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1673913.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

差异基因散点图绘制教程

差异基因散点图绘制教程 本期教程 小杜的生信笔记&#xff0c;自2021年11月开始做的知识分享&#xff0c;主要内容是R语言绘图教程、转录组上游分析、转录组下游分析等内容。凡事在社群同学&#xff0c;可免费获得自2021年11月份至今全部教程&#xff0c;教程配备事例数据和相…

Python---NumPy万字总结【此篇文章内容难度较大,线性代数模块】(3)

NumPy的应用&#xff08;3&#xff09; 向量 向量&#xff08;vector&#xff09;也叫矢量&#xff0c;是一个同时具有大小和方向&#xff0c;且满足平行四边形法则的几何对象。与向量相对的概念叫标量或数量&#xff0c;标量只有大小&#xff0c;绝大多数情况下没有方向。我们…

【JAVA】数组的定义与使用

前一篇我们讲述了方法的使用和递归&#xff0c;这一讲 我们来叙述一下数组相关知识点。最近更新较快&#xff0c;大家紧跟步伐哦~~ 1. 数组的基本概念 1.1 为什么要使用数组 假设现在要存5个学生的javaSE考试成绩&#xff0c;并对其进行输出&#xff0c;按照之前掌握的知识点&…

Gooxi发布最新AI服务器:加速生成式AI落地 更懂AI

近日&#xff0c;Gooxi发布最新训推一体AI服务器&#xff0c;以大容量内存和灵活的高速互连选项满足各种AI应用场景&#xff0c;最大可能支持扩展插槽&#xff0c;从而大幅提升智能算力性能&#xff0c;以最优的性能和成本为企业的模型训练推理落地应用提供更好的通用算力。 AI…

AICloud 分论坛 07-AI原生数据库与RAG【文档管理】

https://github.com/infiniflow/infinityhttps://infiniflow.org/视频观看&#xff1a;https://www.bilibili.com/video/BV16m411y7xW/?spm_id_from333.999.0.0&vd_sourceae7b192be069682aabc96350ba419fc5 简介 为LLM应用程序构建的AI原生数据库&#xff0c;提供令人难…

单元测试之TestNG知识点总结及代码示例

TestNG 是一个测试框架&#xff0c;用于自动化测试 Java 和 Scala 应用程序&#xff0c;它是 JUnit 和 NUnit 的一个强大替代品。TestNG 支持数据驱动测试、参数化测试、测试套件、依赖管理、多线程测试等特性。TestNG官网&#xff1a;TestNG Documentation 目录 1.TestNG 基…

think PHP导入导出excel

本地环境 think PHP5&#xff0c;PhpOffice/PhpSpreadsheet&#xff0c;composer PHP版本7.4&#xff0c;这个插件的最低版本要求7.2 配置PhpSpreadsheet 官网&#xff1a;https://phpspreadsheet.readthedocs.io/en/stable/ composer require phpoffice/phpspreadsheet数据库…

华强北宋仕强论道之项目管理

华强北宋仕强论道之项目管理&#xff0c;金航标和萨科微总经理宋仕强先生说&#xff0c;良好的项目管理是企业成功的关键之一&#xff0c;项目是公司最小的管理单元&#xff0c;而项目管理则是确保项目顺利完成的关键工作。在一个项目中&#xff0c;需要明确目标&#xff0c;合…

下载element-ui报错

此错误表示尝试从npm注册表下载“resize observer polyfill”包时超时。这可能是由于网络连接问题或npm注册表服务器的问题。 要解决此问题&#xff0c;您可以尝试以下步骤&#xff1a; 1.重试npm install命令&#xff1a;有时&#xff0c;网络问题会导致临时超时。再次运行npm…

用友NC printBill 任意文件读取/删除漏洞复现(XVE-2024-10609)

0x01 产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。 0x02 漏洞概述 用友NC printBill 接口处存在任意文件读…

【Unity】为小球添加爆发力往前移动的代码

代码里的几个变量都需要在场景中提前创建好并赋值 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Shotobjt : MonoBehaviour {// 点击按钮&#xff0c;克隆一个prefab&#xff0c;然后给这个克隆后的对象添加往前方的力publi…

搭建Rust开发环境

Windows搭建 下载&#xff1a;https://www.rust-lang.org/zh-CN/tools/install Linux搭建 这里我更推荐基于Linux搭建。 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh

如何用微信小程序实现远程控制4路控制器/断路器

如何用微信小程序实现远程控制4路控制器/断路器呢&#xff1f; 本文描述了使用微信小程序调用HTTP接口&#xff0c;实现控制4路控制器/断路器&#xff0c;支持4路输出&#xff0c;均可独立控制&#xff0c;可接入各种电器。 可选用产品&#xff1a;可根据实际场景需求&#xf…

最新小红书颜值打分项目,吸引小姐姐,刷爆后端收益

嘿&#xff0c;朋友们&#xff01;今天我要给你们分享一个我自己都觉得挺诧异的项目&#xff0c;它叫做“颜值打分”。听起来有点搞笑对吧&#xff1f;但真的&#xff0c;这个项目已经帮助了很多人实现了月入万元的目标。你没听错&#xff0c;就是月入万元&#xff01;所以&…

品牌出海新趋势:掌握“微创新”策略,快速适应海外市场

在全球化的今天&#xff0c;品牌出海已成为众多企业拓展业务、实现国际化发展的重要途径。然而&#xff0c;海外市场与本土市场在文化、消费习惯、法律法规等方面均存在显著差异&#xff0c;这要求品牌在海外市场中必须灵活应变&#xff0c;通过微小的、有针对性的创新来快速适…

node和npm版本太高导致项目无法正常安装依赖以及正常运行的解决办法:如何使用nvm对node和npm版本进行切换和管理

1&#xff0c;点击下载 nvm 并且安装 进入nvm的github&#xff1a; GitHub - coreybutler/nvm-windows: A node.js version management utility for Windows. Ironically written in Go. 这里下载发行版&#xff0c;Releases coreybutler/nvm-windows GitHub 找到 这个 nv…

C# XPTable in .net6(XPTable控件使用说明八)

经过作者schoetbi、armin-pfaeffle的努力&#xff0c;XPTable已经可以在 winform .net6 .net8的环境下使用&#xff0c;版本升级到了2.0&#xff0c;这样就可以在winform下同时使用XPTABLE和EFcore, 这样就可以解决大部分的场景了。

提示词技巧十个级别:你达到了哪个水平?

在数字化时代&#xff0c;人工智能的应用已成为提升效率和优化交互的关键。特别是在内容生成领域&#xff0c;如何有效地使用ChatGPT来达到最佳的交互效果成为了一个热门话题。最近&#xff0c;一段关于ChatGPT提示词技巧的视频引起了广泛关注&#xff0c;视频中将提示词技巧分…

ai写作软件有哪些?看看这几款好用免费的Ai写作工具

在科技的浩瀚星海中&#xff0c;人工智能技术的星辰愈发闪耀。近年来&#xff0c;AI写作技术作为其中的重要分支&#xff0c;正以其独特的光芒&#xff0c;改变着传统的内容创作模式。今天&#xff0c;我们就来深入讨论一下这项技术的实力和前景。 我们要明确一个概念&#xff…

从旺店通·企业奇门到金蝶云星空通过接口配置打通数据

从旺店通企业奇门到金蝶云星空通过接口配置打通数据 接通系统&#xff1a;旺店通企业奇门 慧策最先以旺店通ERP切入商家核心管理痛点——订单管理&#xff0c;之后围绕电商经营管理中的核心管理诉求&#xff0c;先后布局流量获取、会员管理、仓库管理等其他重要经营模块。慧策的…