拦截器-登录检查与静态资源放行
# 370.拦截器-登录检查与静态资源放行
之前我们说了 SpringBoot 处理请求的底层原理,接下来就来说说其他常用的 web 功能,例如拦截器、文件上传、异常处理等。
# 拦截器
还是以我们的后台管理系统为例,我们只有在 main 页面做了登录的校验,其他都是没做校验的;
但如果每个页面请求都做登录校验,就太麻烦了,有很多的重复代码;为此我们可以使用拦截器(原生 Servlet 的 Filter 也可以)
在底层中,拦截器是这样一个接口:
package org.springframework.web.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
说明:
- preHandle 方法:预先处理,就是处理请求之前,要做的事情(就是在执行我们自己写的 controller 方法之前要做的事情)
- postHandle 方法:后处理,就是处理完请求之后,要做的事情
- afterCompletion 方法:在页面渲染完之后,要做的事情,例如清理一些数据
# 新增拦截器
我们可以通过实现拦截器接口,来完成拦截,例如:
package com.peterjxl.learnspringbootwebadmin.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 登录检查
* 1. 配置好拦截器要拦截哪些请求
* 2. 把这些配置放在容器中
*/
public class LoginInterceptor implements HandlerInterceptor {
/**
* 目标方法执行之前
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if (loginUser != null) {
// 已登录
return true;
}
// 未登录,返回登录页面
request.setAttribute("msg", "请先登录");
request.getRequestDispatcher("/").forward(request, response);
return false;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 将拦截器放到 web 容器
新增了拦截器后,我们还得将其放到容器中:
package com.peterjxl.learnspringbootwebadmin.config;
import com.peterjxl.learnspringbootwebadmin.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 拦截所有请求,包括静态资源
.excludePathPatterns("/", "/login", "/css/**", "/fonts/**", "/images/**", "/js/**");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
注意,我们还配置了拦截规则和放行规则。然后我们就可以去除 main 页面中的校验登录的代码了。
# 测试
我们直接访问 localhost: 9999/dynamic_table (opens new window),此时就访问不了,而提示要登录:
# 最后
总结下拦截器的使用步骤:
- 编写一个拦截器,实现 HandlerInterceptor 接口
- 注册拦截器到容器中(实现
WebMvcConfigurer
的adInterceptors
方法) - 指定拦截规则(注意放行静态资源)
已将本文源码上传到 Gitee (opens new window) 或 GitHub (opens new window) 的分支 demo4,读者可以通过切换分支来查看本文的示例代码
上次更新: 2024/10/3 10:01:52