SpringBoot学习笔记3.27

目录

实战篇第二课

1.注册参数的校验:

学习过程中遇到的问题:

1.什么是正则表达式

2.怎么自定义异常?

[1. 创建全局异常处理类](#1. 创建全局异常处理类)

[2. 定义响应对象](#2. 定义响应对象)

[3. 使用 @ExceptionHandler](#3. 使用 @ExceptionHandler)

[4. 设置响应状态码](#4. 设置响应状态码)

[5. 返回统一响应](#5. 返回统一响应)

[6. 测试全局异常处理](#6. 测试全局异常处理)

注意事项@RestControllerAdive

实战篇第三课

1.登录的主逻辑

[​编辑 2.登录认证jwt](#编辑 2.登录认证jwt)

JWT的组成:​​​​​​​

JWT的使用:

在test中模拟JWT的生成和使用(只用理解不用记忆):

3.如何实现登录认证(拦截器)?

[实战第四课 :获取用户的详细信息](#实战第四课 :获取用户的详细信息)

但是只执行过程中遇到两个小问题:

TreadLocal提供线程局部变量

具体实现:

实战第五课:

更新用户基本信息:

具体实现:

对更新用户的基本信息进行参数校验

[​编辑 具体实现:](#编辑 具体实现:)

更新用户密码:

具体实现:

至此,我们的用户接口全部书写完毕!


实战篇第二课

1.注册参数的校验:

注意@Pattern(regexp="")里面写的是正则表达式。

如果参数不合规,则会返回异常,而这个异常的格式和result格式不同,所以我们需要自定义一个全局的异常:

总结:

学习过程中遇到的问题:

1.什么是正则表达式

匹配符:

d? d出现0/1次

a* a可以出现0/多次

a+ a出现一次以上

a{6} a出现6次

a{2,} a出现2次以上

a{2,6} a出现2-6次

匹配多个字符:

(ab)+ ab出现一次以上

或运算:

a (cat|dog) 匹配 a cat or a dog

a cat|dog 匹配 a cat or dog

字符类:

匹配由abc构成的数据【abc】+ abc出现一次以上 abc aabbcc

【a-zA-Z0-9】 ABCabc123

^ 排除 【^0-9】 匹配0-9之外的数据(包括换行符)

元字符

\d 数字字符 \d+ 匹配一个以上的数字

\D 非数字字符

\w 单词字符 单词 数字 下划线即英文字符

\W 非单词字符

\s 空白符 包含空格和换行符

\S 非空白字符

\b 单词的边界 单词的开头或结尾 单词与符号之前的边界

\B 非单词的边界 符号与符号 单词与单词的边界

. 任意字符不包含换行符

\. 表示. 通过\进行了转意

^ 匹配行首 $ 匹配行尾

*+{}贪婪匹配

<strong><b>https://www.wondershare. com</strong></b>

<.+> 会匹配整串 因为是贪婪匹配

<.+?> 只匹配两个标签代码,➕? 设置为懒惰匹配

举例:

假设我们想要匹配一个有效的电子邮件地址,可以使用以下正则表达式:

复制代码
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

这个表达式的含义是:

  • ^:匹配字符串的开始。

  • [a-zA-Z0-9._%+-]+:匹配一个或多个字母、数字、点、下划线、百分号、加号或减号。

  • @:匹配 @ 字符。

  • [a-zA-Z0-9.-]+:匹配一个或多个字母、数字、点或减号。

  • \.:匹配点字符(需要转义,因为在正则表达式中点有特殊含义)。

  • [a-zA-Z]{2,}:匹配两个或多个字母。

  • $:匹配字符串的结束。

2.怎么自定义异常?

在 Spring 框架中,你可以通过实现 ExceptionHandler 接口或者使用 @ControllerAdvice 注解注解来定义全局异常处理。通过这种方式,你可以捕获并处理整个应用程序中抛出的特定异常,然后返回统一的响应。

以下是如何使用 @ControllerAdvice@ExceptionHandler 来定义全局异常处理的步骤:

1. 创建全局异常处理类

首先,创建一个类并使用 @ControllerAdvice 注解注解标注该类,表示该类用于全局异常处理。

java复制

复制代码
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ControllerAdvice
public class GlobalExceptionHandler {

    // 处理特定异常
    @ExceptionHandler(YourCustomException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST) // 设置响应状态码
    public ModelAndView handleCustomException(YourCustomException ex, WebRequest request) {
        ModelAndView modelAndView = new ModelAndView("errorPage");
        modelAndView.addObject("message", ex.getMessage());
        modelAndView.addObject("url", ((ServletWebRequest) request).getRequest().getRequestURL());
        return modelAndView;
    }

    // 处理所有异常
    @ExceptionHandler(Exception.class)
    public @ResponseBody ErrorResponse handleException(Exception ex, WebRequest request) {
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        errorResponse.setMessage(ex.getMessage());
        errorResponse.setPath(((ServletWebRequest) request).getRequest().getRequestURI());
        return errorResponse;
    }
}

2. 定义响应对象

定义一个响应对象 ErrorResponse,用于封装错误信息。

java复制

复制代码
public class ErrorResponse {
    private int status;
    private String message;
    private String path;

    // getters and setters
}

3. 使用 @ExceptionHandler

@ControllerAdvice 注解注解的类中,使用 @ExceptionHandler 注解注解标注方法,以处理特定类型的异常。你可以为不同的异常类型定义不同的处理方法。

4. 设置响应状态码

使用 @ResponseStatus 注解注解设置 HTTP 响应状态码。

5. 返回统一响应

在异常处理方法中,返回统一的响应格式,可以是视图名称(对于 ModelAndView)或响应体(对于 @ResponseBody)。

6. 测试全局异常处理

现在,当你的项目中抛出定义的异常时,Spring 会自动使用你定义的全局异常处理方法来处理这些异常,并返回统一的响应。

注意事项@RestControllerAdive

  • 确保 @ControllerAdvice 注解注解的类在 Spring 应用上下文中被扫描到,通常放在 @ComponentScan 指定的包路径下。

  • 你可以根据需要定义多个异常处理方法,分别处理不同类型的异常。

  • 全局异常处理可以大大简化异常处理代码,提高代码的可维护性和可读性。

  • @RestControllerAdvice@ControllerAdvice 的一个特化,专门用于 RESTful 控制器(使用 @RestController 注解的控制器)。

  • 它通常用于处理 RESTful 服务中的异常,返回 JSON 或 XML 格式的响应体。

  • @RestControllerAdvice 中的方法通常返回 @ResponseBody 注解的对象,这样对象会被自动序列化为 JSON 或 XML 格式。

  • 它不适用于返回视图(View)或 ModelAndView 对象,因为它主要用于 RESTful API。

实战篇第三课

1.登录的主逻辑

登录过程中查询用户名称和密码,在注册时已经时间,所以主要实现Controller层逻辑

Controller层的登录逻辑实现:

2.登录认证jwt

JWT的组成:​​​​​​​

包含header、payload、signature三个部分,注意有效载荷里面不要放私密数据。

JWT的使用:

前端在完成登录后,后端会返回一个JWT,每当浏览器发送请求时,会携带JWT用于验证是否登录

JWT的生成(不用特别记忆,主要是理解JWT的构成):

JWT是如何解密和验证的?如果头载荷或者签名有一个出错,都会返回错误。

总结:

在test中模拟JWT的生成和使用(只用理解不用记忆):

.withClaim()方法用于添加负荷,.withExpiresAt()添加过期时间,.sign()指定加密算法和秘钥,这样我们就会create出一个JWT字符串。

.build()生成JWT解码器,解码器可以解析JWT,解析后的结果调用.getClaim()会获得负荷,注意负荷会是一个<String,Claim>的形式;

3.如何实现登录认证(拦截器)?

我们要创建一个拦截器,因为在登录后浏览器的每次请求都会携带JWT,在访问一些登录后才能查看的路径时,如果JWT有问题,那么就会返回401状态码并提示未登录;对于登录和注册界面没必要添加拦截。

拦截器实现:

1首先要创建一个拦截器。要实现HandlerInterceptor接口,重写里面的PreHandle方法

2然后我们要将这个拦截器配置到WebMvcConfigurer里面,即重写里面的addInterceptors方法,将拦截器注册到环境中去,注意login和register界面不用拦截。

3postman测试一下,携带正确的Autorization的请求头返回正确,不携带token的话会被拦截且返回401

实战第四课 :获取用户的详细信息

Controller层的实现方法,通过请求头获取JWT,解码JWT获得有效载荷里面的username,在通过username去查询用户信息:

但是只执行过程中遇到两个小问题:

第一个是我们返回的user里面,我们给前端返回的用户详细信息不能包含password,我们给它添加@JsonIgnore后,他可以在当user类转化成json时,不传输对应的属性;

第二个是由于user实体类中时间的命名是驼峰命名,而数据库中我们是下划线命名,如:create_time这样,那么我们在@Select后,两个时间属性就不会赋值给user类,解决这个只需要在配置文件中打开mybatis的驼峰命名和下划线命名的自动转换:

TreadLocal提供线程局部变量

具体实现:

1.在每次对请求拦截时,我们会获取token中的负载,在后面的Controller或者service中我们可能会再次用到这个负载,那么我们可以用一个线程安全的全局变量来存储这个负载,减少我们后面传递、计算的开销。

2.我们在Controller层就可以直接使用获取的这个负载。

3.请求完成之后我们要释放这个threadlocal

实战第五课:

更新用户基本信息:

具体实现:

1.Controller层里面写好update方法,注意@RequestBody:告诉 Spring,方法的 user 参数应该从请求体中获取数据,使Spring 会自动将 JSON 或 XML 数据转换为 Java 对象。

2.service层的实现类去调用Mapper层的方法:

3.Mapper层执行SQL语句:

对更新用户的基本信息进行参数校验

具体实现:

注意要在使用时添加@Validated注解里面的校验注解才会生效:

注意我们如果要修改用户头像,我们需要对参数进行校验,在参数钱添加@URL进行校验:

更新用户密码:

具体实现:

Controller层,注意逻辑,原密码不正确、新密码和确认密码不一致、有任意一个密码为空都会直接返回error:

Service层:

Mapper层:

至此,我们的用户接口全部书写完毕!

相关推荐
序属秋秋秋1 小时前
算法基础_基础算法【高精度 + 前缀和 + 差分 + 双指针】
c语言·c++·学习·算法
慵懒学者1 小时前
15 网络编程:三要素(IP地址、端口、协议)、UDP通信实现和TCP通信实现 (黑马Java视频笔记)
java·网络·笔记·tcp/ip·udp
爱吃馒头爱吃鱼1 小时前
QML编程中的性能优化二
开发语言·qt·学习·性能优化
白夜易寒2 小时前
Docker学习之容器虚拟化与虚拟机的区别(day11)
学习·docker·容器
教练 我想学编程2 小时前
学习记录706@微信小程序+springboot项目 真机测试 WebSocket错误: {errMsg: Invalid HTTP status.}连接不上
spring boot·学习·微信小程序
星空寻流年2 小时前
css之定位学习
前端·css·学习
张张张3123 小时前
4.1学习总结 拼图小游戏+集合进阶
java·学习
RadNIkMan3 小时前
Python学习(二)操作列表
网络·python·学习
笑鸿的学习笔记3 小时前
ROS2笔记之服务通信和基于参数的服务通信区别
android·笔记·microsoft
yanxy5124 小时前
【TS学习】(15)分布式条件特性
前端·学习·typescript