网站首页 > java教程 正文
1. 引言
在开发 web 应用程序时,常常需要在请求处理的前后执行一些通用逻辑,如认证、日志记录等。Spring MVC 提供了强大的拦截器(Interceptor)机制,允许在控制器执行之前和之后插入自定义的处理逻辑。本文将详细讲解 Spring Boot 中拦截器的基本概念、设计原则、执行顺序、应用场景,并提供具体实现和示例代码。
2. 基本概念
拦截器(Interceptor) 是 Spring MVC 的一部分,用于在请求进入控制器之前和之后对其进行拦截,并执行特定逻辑。拦截器类似于过滤器(Filter),但它具有更强的功能和灵活性。
- preHandle():在请求处理前执行,通常用于身份验证、权限检查等。
- postHandle():在请求处理后,但在视图渲染之前执行,可用于对 ModelAndView 进行修改。
- afterCompletion():在视图渲染完成后执行,通常用于清理资源或记录日志。
3. 设计原则
拦截器的设计遵循以下原则:
- 单一职责原则:每个拦截器应专注于一种特定的处理任务,例如日志记录、权限控制、数据验证等。
- 分层处理:通过链式调用机制,允许多个拦截器在请求处理的不同阶段分别执行逻辑。
- 解耦:拦截器与控制器解耦,不影响业务逻辑,使得横切关注点(如日志和认证)更容易维护。
4. 执行顺序
- preHandle():按照拦截器注册顺序依次执行,若返回 false,则后续的拦截器和控制器不再执行。
- postHandle():按拦截器注册的顺序逆序执行。
- afterCompletion():按拦截器注册的顺序逆序执行,确保在所有逻辑完成后执行资源清理等操作。
5. 应用场景
- 认证和授权:在 preHandle() 方法中检查用户身份和权限,拦截非法请求。
- 日志记录:在请求到达控制器之前或返回响应之后记录访问日志。
- 性能监控:记录请求的开始和结束时间,以便监控系统性能。
- 请求参数校验:对请求参数进行全局的合法性校验。
6. 实现拦截器
6.1 项目结构
src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ ├── config
│ │ │ └── WebConfig.java
│ │ ├── interceptor
│ │ │ └── LoggingInterceptor.java
│ │ ├── controller
│ │ │ └── UserController.java
│ │ ├── model
│ │ │ └── User.java
│ │ └── service
│ │ └── UserService.java
│ └── resources
│ └── application.properties
6.2 创建拦截器
LoggingInterceptor 类记录每个请求的开始和结束时间。
package com.example.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Request URL: " + request.getRequestURL());
request.setAttribute("startTime", System.currentTimeMillis());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
long startTime = (Long) request.getAttribute("startTime");
System.out.println("Request URL: " + request.getRequestURL() + " processed in " + (System.currentTimeMillis() - startTime) + " ms");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("Request completed for URL: " + request.getRequestURL());
}
}
6.3 配置拦截器
在 WebConfig 中注册拦截器,确保拦截器作用于所有请求路径。
package com.example.config;
import com.example.interceptor.LoggingInterceptor;
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 WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/**");
}
}
6.4 控制器类
UserController 提供简单的用户 API,用于演示拦截器的功能。
package com.example.controller;
import com.example.model.User;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
User user = new User();
user.setId(id);
user.setName("John Doe");
return user;
}
@PostMapping
public User createUser(@RequestBody User user) {
user.setId(1L);
return user;
}
}
6.5 User类
package com.example.model;
public class User {
private Long id;
private String name;
// Getters and Setters
}
7. 拦截器与过滤器的区别
- 拦截器 (Interceptor):Spring MVC 特有,基于框架,主要用于拦截 Spring MVC 控制器的执行过程。执行的顺序为 preHandle -> Controller -> postHandle -> afterCompletion。
- 过滤器 (Filter):基于 Servlet 规范,适用于所有请求,包括静态资源等。在请求进入 Spring MVC 前执行,处理的是更底层的 Servlet 请求。
8. 总结
Spring Boot 中的拦截器提供了一种强大且灵活的机制,可以在控制器前后执行各种逻辑。通过合理设计拦截器,可以解耦横切关注点并提高代码的可维护性。在应用中,拦截器被广泛用于身份验证、日志记录、性能监控等场景。希望本文能帮助你深入理解拦截器的使用和设计。如有问题,欢迎讨论!
猜你喜欢
- 2024-11-04 【快学springboot】12.实现拦截器
- 2024-11-04 Spring Boot 中的拦截器和过滤器到底有什么区别?
- 2024-11-04 SpringBoot中的过滤器和拦截器有什么区别?
- 2024-11-04 为什么你写的拦截器注入不了Java bean?
- 2024-11-04 使用Spring Cloud Zuul实现过滤器或拦截器功能案例
- 2024-11-04 java服务-springboot拦截器实现用户登录Token及权限校验
- 2024-11-04 JAVAEE就业工程师教程之第4章 Struts2拦截器
- 2024-11-04 Spring框架功能分为哪些模块?(spring框架有哪几部分组成)
- 2024-11-04 高级码农Spring Boot实战进阶之过滤器、拦截器的使用
- 2024-11-04 轻量级 Java 权限认证框架Sa-Token初体验(五)
你 发表评论:
欢迎- 最近发表
-
- pyinstaller打包python程序高级技巧
- 将python打包成exe的方式(python打包成exe的方法)
- Python打包:如何将 Flask 项目打包成exe程序
- py2exe实现python文件打包为.exe可执行程序(上篇)
- 如何将 Python 项目打包成 exe,另带卸载功能!
- Python打包成 exe,太大了该怎么解决?
- 可视化 Python 打包 exe,这个神器绝了!
- 案例详解pyinstaller将python程序打包为可执行文件exe
- Cocos 3.x 菜鸟一起玩:打包window程序
- 怎么把 Python + Flet 开发的程序,打包为 exe ?这个方法很简单!
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)