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` 文件中,你应该去掉 `#` 符号以激活这个配置。
  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tin9898

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值