一文搞懂Spring Boot自定义拦截器
为什么需要拦截器?
在我们开发的Web系统中,资源可分为大致三类:公开资源、个人资源和隐私资源,比如公开资源有任何人都能看新闻、视频、文章等等,个人资源就是指系统用户的个人信息等等,隐私资源可以表示系统的后台管理、用户管理等等。
因此我们需要进行系统用户访问资源的认证规则,而Spring自带的拦截器处理器就可以很好地完成我们的需求,下面开始今天的表演!
1 场景需求分析
我们假设有三类资源,分别为公开资源、个人资源和隐私资源,请求路径分别对应为:
- 公开资源:/user/getUserPublicInfo
- 个人资源:/user/getUserInfo
- 隐私资源:/user/getUserPrivateInfo
此外我们还需要一个别拦截后的跳转路径,防止用户在自己被拦截后还浑然不知
- 未授权下跳转路径:/user/noAuth
下面我们罗列下访问这些资源都有什么要求
资源名称 | 资源路径 | 要求 |
公开资源 | /user/getUserPublicInfo | 无 |
个人资源 | /user/getUserInfo | 带上请求参数token |
隐私资源 | /user/getUserPrivateInfo | 带上请求参数token加请求头ymx-name |
2 项目架构
2.1 依赖和配置文件
我们新建Spring Boot项目,引入依赖,修改配置文件
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> 复制代码
配置文件:
server.port=9000 复制代码
2.2 项目结构
网络异常,图片无法展示
|
2.3 类的分析
网络异常,图片无法展示
|
3 具体代码实现
3.1 项目代码实现
UserController.java
/** * @desc: UserController * @author: YanMingXin * @create: 2021/9/27-17:12 **/ @RestController @RequestMapping("/user") public class UserController { @Data @Accessors(chain = true) class User { private String name; private Integer age; } /** * 个人资源 * * @return */ @RequestMapping("/getUserInfo") public User getUserInfo() { return new User().setName("User:zs").setAge(12); } /** * 隐私资源 * * @return */ @RequestMapping("/getUserPrivateInfo") public User getUserPrivateInfo() { return new User().setName("PrivateUser:ls").setAge(2); } /** * 公开资源 * * @return */ @RequestMapping("/getUserPublicInfo") public User getUserPublicInfo() { return new User().setName("PublicUser:ww").setAge(15); } /** * 未授权跳转页面 * * @return */ @RequestMapping("/noAuth") public String noAuth() { return "You were intercepted~"; } } 复制代码
WebInterceptorHandler.java
/** * @desc: 自定义拦截器 * @author: YanMingXin * @create: 2021/9/27-17:10 **/ @Component public class WebInterceptorHandler implements HandlerInterceptor { private final String USER_TOKEN_NAME = "token"; private final String USER_TOKEN_VALUE = "ymx"; private final String AUTH_HEADER = "ymx-name"; private final String PRIVATE_URL = "/user/getUserPrivateInfo"; private final String REDIRECT_URL = "/user/noAuth"; /** * 预处理回调方法 * * @param request * @param response * @param handler * @return 返回true为继续处理,false为中断处理 * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getParameter(USER_TOKEN_NAME); String headerValue = request.getHeader(AUTH_HEADER); String requestURI = request.getRequestURI(); //用户个人隐私 if (PRIVATE_URL.equals(requestURI)) { if (USER_TOKEN_VALUE.equals(headerValue) && USER_TOKEN_VALUE.equals(token)) { return true; } else { //拦截后跳转路径 response.sendRedirect(REDIRECT_URL); return false; } } //一般隐私 if (USER_TOKEN_VALUE.equals(token)) { return true; } //拦截后跳转路径 response.sendRedirect(REDIRECT_URL); return false; } /** * 后处理回调方法,在渲染视图之前实现处理器的后处理 * * @param request * @param response * @param handler * @param modelAndView * @throws Exception */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,可用于记录日志 * * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } } 复制代码
WebInterceptorConfig.java
/** * @desc: 拦截器配置 * @author: YanMingXin * @create: 2021/9/27-17:01 **/ @Configuration public class WebInterceptorConfig extends WebMvcConfigurationSupport { /** * 注入自定义拦截器 */ @Resource private WebInterceptorHandler webInterceptorHandler; /** * 配置拦截器和拦截、放行路径 * * @param registry */ @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(webInterceptorHandler) .excludePathPatterns("/user/getUserPublicInfo") .excludePathPatterns("/user/noAuth") .addPathPatterns("/**"); } } 复制代码
3.2 总体分析
实现自定义拦截器:
在Spring5之前
@Component public class WebInterceptorHandler extends WebMvcConfigurerAdapter {} 复制代码
Spring5及以后
@Component public class WebInterceptorHandler implements HandlerInterceptor {} 复制代码
或
@Component public class WebInterceptorHandler extends WebMvcConfigurationSupport {} 复制代码
拦截器配置:
@Configuration public class WebInterceptorConfig extends WebMvcConfigurationSupport{} 复制代码
4 测试
启动项目,打开postman
4.1 访问公开路径:http://127.0.0.1:9000/user/getUserPublicInfo
网络异常,图片无法展示
|
4.2 访问个人路径:http://127.0.0.1:9000/user/getUserInfo
网络异常,图片无法展示
|
带上需要的参数再次访问:
网络异常,图片无法展示
|
4.3 访问隐私路径:
网络异常,图片无法展示
|
带上参数和请求头再次访问:
网络异常,图片无法展示
|
测试成功!
今天的表演到此结束咯~