SpringBoot学习笔记3.27

发布于:2025-03-30 ⋅ 阅读:(30) ⋅ 点赞:(0)

目录

实战篇第二课

1.注册参数的校验:

学习过程中遇到的问题:

1.什么是正则表达式

 2.怎么自定义异常?

1. 创建全局异常处理类

2. 定义响应对象

3. 使用 @ExceptionHandler

4. 设置响应状态码

5. 返回统一响应

6. 测试全局异常处理

注意事项@RestControllerAdive

实战篇第三课 

1.登录的主逻辑

​编辑 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层:

 

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