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` 文件中,你应该去掉 `#` 符号以激活这个配置。
相关推荐
编程、小哥哥4 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
wxin_VXbishe9 小时前
springboot合肥师范学院实习实训管理系统-计算机毕业设计源码31290
java·spring boot·python·spring·servlet·django·php
OEC小胖胖9 小时前
Spring Boot + MyBatis 项目中常用注解详解(万字长篇解读)
java·spring boot·后端·spring·mybatis·web
落落落sss10 小时前
MybatisPlus
android·java·开发语言·spring·tomcat·rabbitmq·mybatis
潘多编程18 小时前
Java中的状态机实现:使用Spring State Machine管理复杂状态流转
java·开发语言·spring
_阿伟_18 小时前
SpringMVC
java·spring
杨半仙儿还未成仙儿1 天前
Spring框架:Spring Core、Spring AOP、Spring MVC、Spring Boot、Spring Cloud等组件的基本原理及使用
spring boot·spring·mvc
攸攸太上1 天前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
无理 Java1 天前
【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)
java·后端·spring·面试·mvc·框架·springmvc
gobeyye1 天前
spring loC&DI 详解
java·spring·rpc