Springboot拦截器的使用

复制代码
* 1、编写一个拦截器实现HandlerInterceptor接口
* 2、拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)
* 3、指定拦截规则【如果是拦截所有,静态资源也会被拦截】

这段代码定义了一个 `LoginInterceptor` 类,它实现了 `HandlerInterceptor` 接口,用于在 Spring MVC 中进行拦截器的操作。拦截器可以用来在请求的处理流程中执行特定的逻辑,比如权限检查、日志记录等。下面是对这段代码的注释和解释:

```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerInterceptor;

@Slf4j // 通过 Lombok 注解自动创建 Logger 实例
public class LoginInterceptor implements HandlerInterceptor {

/**
* 目标方法执行之前调用的拦截器逻辑
* @param request HTTP 请求对象
* @param response HTTP 响应对象
* @param handler 处理器,例如 Controller 中的方法
* @return 如果返回 true,则请求继续执行;如果返回 false,则请求中断,不再执行后续的拦截器或处理器
* @throws Exception 可能抛出的异常
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 获取请求的 URI
String requestURI = request.getRequestURI();
// 使用 SLF4J 记录拦截的请求路径
log.info("preHandle拦截的请求路径是{}", requestURI);

// 登录检查逻辑
// 通过 request 获取当前会话的 HttpSession 对象
HttpSession session = request.getSession();

// 从 session 中获取名为 "loginUser" 的属性,用于验证用户是否已登录
Object loginUser = session.getAttribute("loginUser");

// 如果用户已登录(即 loginUser 不为空),则放行请求
if (loginUser != null) {
return true;
}

// 如果用户未登录,则拦截请求
// 将错误消息 "请先登录" 存储在 request 属性中,以便在登录页面显示
request.setAttribute("msg", "请先登录");
// 转发到登录页面(这里使用了 request.getRequestDispatcher("/") 来获取登录页面的请求分发器)
request.getRequestDispatcher("/").forward(request, response);
// 返回 false 表示请求被拦截,不会继续执行后续的拦截器或处理器
return false;
}
}
```

解释:

  1. `@Slf4j` 是 Lombok 库提供的一个注解,它可以自动生成一个名为 `log` 的 `Logger` 实例,用于记录日志。这样,你就可以直接使用 `log.info()` 等方法来记录日志,而不需要手动创建 `Logger` 对象。

  2. `preHandle` 方法是 `HandlerInterceptor` 接口中的一个方法,它在控制器方法(handler)执行之前被调用。这个方法的返回值决定了请求是否继续执行。如果返回 `true`,则请求继续向下执行;如果返回 `false`,则请求被拦截,不会执行后续的拦截器或控制器方法。

  3. 在 `preHandle` 方法中,首先记录了当前请求的 URI。然后,通过 `request.getSession()` 获取当前会话的 `HttpSession` 对象,并尝试从会话中获取名为 "loginUser" 的属性,这个属性通常用于存储用户的登录状态。

  4. 如果用户已经登录(`loginUser` 不为空),则方法返回 `true`,请求继续执行。

  5. 如果用户未登录(`loginUser` 为空),则在请求属性中设置一条消息,并转发到登录页面。这里使用 `request.getRequestDispatcher("/").forward()` 方法来实现请求的转发。

  6. 最后,方法返回 `false`,表示请求被拦截,不会继续执行后续的拦截器或控制器方法。

代码行 `request.getRequestDispatcher("/").forward(request, response);

**`**是 Java Servlet API 中的一部分,用于在当前请求的上下文中转发请求到另一个资源。这行代码通常用于拦截器或 Servlet 中,当你想要将用户的请求从当前路径重定向到另一个路径时。

让我们分解这行代码:

  • `request.getRequestDispatcher`:这是 `HttpServletRequest` 对象的一个方法,它创建一个 `RequestDispatcher` 对象。`RequestDispatcher` 是用于转发请求到其他资源的接口。调用 `request.getRequestDispatcher` 时,你需要传入一个路径,这个路径是相对于当前请求的路径的。

  • `"/"`:这是传递给 `request.getRequestDispatcher` 方法的路径。在这个例子中,`"/"` 表示应用程序的根路径。这意味着请求将被转发到应用程序的首页或登录页面,具体取决于应用程序的配置。

  • `.forward(request, response)`:这是 `RequestDispatcher` 对象的一个方法,它将请求和响应对象作为参数。此方法将请求和响应对象传递给目标资源,这样目标资源就可以生成响应内容并将其发送回客户端。

在上下文中,`request.getRequestDispatcher("/").forward(request, response);` 这行代码的作用是:

  1. 获取一个能够转发请求到应用程序根路径的 `RequestDispatcher` 对象。

  2. 使用这个 `RequestDispatcher` 将当前的请求和响应对象转发到根路径。

  3. 由于请求被转发,控制器中 `preHandle` 方法之后的代码不会被执行。

  4. 用户的浏览器会收到一个转发到新页面的响应,通常是登录页面,用户可以在该页面进行登录操作。

这种转发是服务器端的,用户不会感知到 URL 的变化(除非他们查看浏览器的地址栏)。这与重定向(redirect)不同,重定向是通过发送一个新的响应给客户端,告诉浏览器去请求一个新的 URL。

复制代码
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginInterceptor())
            .addPathPatterns("/**")  //所有请求都被拦截包括静态资源
            .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**",
                    "/js/**","/aa/**"); //放行的请求



这段代码是 Spring Boot 应用中配置拦截器的一个典型例子。`InterceptorRegistry` 是 Spring MVC 提供的一个接口,用于注册拦截器(`HandlerInterceptor`)并配置它们的拦截规则。

```java
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginInterceptor()) // 注册自定义的拦截器
            .addPathPatterns("/**") // 设置拦截器拦截所有请求,包括静态资源
            .excludePathPatterns("/", "/login", "/css/**", "/fonts/**", "/images/**",
                    "/js/**", "/aa/**") // 设置不拦截的请求路径
}
```

解释:

1. `@Override` 注解表明该方法是对父类或接口中方法的重写。

2. `public void addInterceptors(InterceptorRegistry registry)` 是一个方法,它接收一个 `InterceptorRegistry` 类型的参数。这个方法通常在配置类中实现,并且使用 `@Override` 注解标记,因为它重写了 `WebMvcConfigurer` 接口中的 `addInterceptors` 方法。

3. `registry.addInterceptor(new LoginInterceptor())` 这行代码将一个名为 `LoginInterceptor` 的拦截器添加到 Spring MVC 的拦截器链中。`LoginInterceptor` 是一个自定义的拦截器类,它可能包含一些逻辑,比如检查用户是否登录、记录日志等。

4. `.addPathPatterns("/**")` 指定拦截器应该拦截的请求路径。`"/**"` 是一个 Ant 风格的路径模式,表示匹配所有的请求路径。这意味着 `LoginInterceptor` 将对所有的请求进行拦截,包括对静态资源的请求。

5. `.excludePathPatterns` 方法用于指定拦截器不应对哪些请求路径进行拦截。在这个例子中,它排除了以下几个路径:
   - `"/"`:应用的根路径,通常是首页。
   - `"/login"`:登录页面的路径。
   - `"/css/**"`:所有 `/css` 目录下的请求,包括子目录。
   - `"/fonts/**"`:所有 `/fonts` 目录下的请求。
   - `"/images/**"`:所有 `/images` 目录下的请求。
   - `"/js/**"`:所有 `/js` 目录下的请求。
   - `"/aa/**"`:所有 `/aa` 目录下的请求。

通过这种方式,你可以灵活地控制拦截器的行为,确保它们只对需要进行特定处理的请求进行拦截,而不影响对静态资源和其他不需要拦截的请求的访问。这是一种常见的做法,用于确保安全性和性能的最佳实践,例如,通过拦截器实现用户身份验证和授权。



`#spring.mvc.static-path-pattern=/static/**`


 是一个 Spring Boot 的配置属性,用于定义静态资源的映射路径。这个配置通常位于 `application.properties` 或 `application.yml` 配置文件中。

在 Spring Boot 应用中,静态资源(如 HTML、CSS、JavaScript 文件等)通常由内置的 Tomcat 或其他嵌入式服务器提供。`spring.mvc.static-path-pattern` 属性指定了应用中哪些请求应该被视为静态资源请求,并告诉 Spring Boot 从哪里提供这些资源。

这里的配置表示:

- `static`:这是一个占位符,表示静态资源的根目录。
- `/**`:这是一个 Ant 风格的路径模式,表示匹配 `/static/` 路径下的所有子路径。

换句话说,这个配置告诉 Spring Boot 将所有以 `/static/` 开头的请求映射为静态资源请求。例如,如果你有一个位于 `/static/css/style.css` 的 CSS 文件,你可以通过 `/static/css/style.css` 的 URL 来访问它。

如果你的静态资源位于类路径(classpath)的 `/static` 目录下,这个配置就会自动生效。如果你希望使用不同的目录或路径模式,你可以修改这个属性的值。

例如,如果你想要从 `/resources/static` 目录提供静态资源,并希望它们可以通过 `/static/**` 路径模式访问,你可以这样配置:

```properties
spring.mvc.static-path-pattern=/static/**
```

请注意,当使用 `#` 符号时,它通常表示这是一个注释,但在这个上下文中,它可能是配置文件中的一个注释掉的行,或者是在文档中用来说明的一个示例。在实际的 `application.properties` 文件中,你应该去掉 `#` 符号以激活这个配置。
相关推荐
卓怡学长2 小时前
w269基于spring boot + vue 候鸟监测数据管理系统
java·数据库·spring boot·spring·intellij-idea
Listen·Rain7 小时前
向量化详解
java·人工智能·spring·机器学习·ai
添砖java_8579 小时前
网页聊天室测试报告
java·spring boot·spring·maven
xixingzhe210 小时前
Spring 依赖注入
java·后端·spring
闲猫19 小时前
Spring AI 对接Deepseek ChatModel 聊天对话
java·前端·spring
醇氧1 天前
Spring 容器 Map 注入机制详解
java·后端·spring
ylscode1 天前
Cloudflare Workers Cache 深度解析:边缘缓存如何重塑无服务器性能边界
java·spring·mybatis
沉静的小伙1 天前
Spring事务
java·数据库·spring
Wang's Blog1 天前
Java框架快速入门: Spring Bean核心配置与实例化详解
java·开发语言·spring
AI人工智能+电脑小能手1 天前
【大白话说Java面试题 第160题】【06_Spring篇】第20题:Spring 事务什么时候会失效?
java·spring·事务失效·事务传播·异常回滚