1. HTTP 请求处理的整体层级结构
1.1 请求处理链路总览
在一个典型的 Spring Boot Web 项目中,请求的处理顺序如下:
Client
↓
Tomcat (Web 容器(Servlet 容器))
↓
Servlet -----------------------------|
| Filter (Servlet 过滤器) |
| ↓ |
| DispatcherServlet (Servlet 实例) |
| ↓ |
-------------------------------------|
↓
Spring MVC --------------------------|
| Interceptor (拦截器) |
| ↓ |
| Controller (控制层) |
| ↓ |
| Service (业务层) |
| ↓ |
| Mapper / DAO (数据访问层) |
| ↓ |
-------------------------------------|
↓
Database (数据库)

2. HTTP 请求在各层级中的具体传递过程
以下以"用户登录"接口为示例,对请求在各层中的表现形式进行说明。
2.1 客户端发起 HTTP 请求
请求示例
POST /user/login HTTP/1.1 (请求头)
Host: localhost:8080 (请求行)
Content-Type: application/json
Authorization: Bearer xxx
Content-Length: 56
{ (请求体)
"username": "admin",
"password": "123456"
}
2.2 Tomcat(Web 容器)

-
监听端口(如 8080)
-
接收 TCP 连接
-
将原始 HTTP 报文解析为
HttpServletRequest和HttpServletResponse -
按 URL 映射规则分发给对应 Web 应用
2.3 Filter(过滤器)
Filter 属于 Servlet 规范的一部分,用于在请求进入 Servlet 之前、响应返回客户端之前进行统一处理。
常见用途:编码处理、日志记录、权限校验、跨域(CORS)
请求状态
-
请求仍为
HttpServletRequest -
请求体、请求头均可被读取或修改
示例代码
@WebFilter(urlPatterns = "/*")
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
System.out.println("Filter URI: " + req.getRequestURI());
chain.doFilter(request, response);
}
}
2.4 DispatcherServlet(核心 Servlet)
角色说明
-
Spring MVC 的前端控制器
-
本质是一个 Servlet
-
所有请求都会先进入 DispatcherServlet
核心职责
-
请求分发
-
查找 Handler(Controller 方法)
-
统一调用拦截器、参数解析、返回值处理
2.5 Interceptor(拦截器)
2.5.1 拦截阶段
拦截器在 DispatcherServlet 内部生效,主要有三个阶段:
-
preHandle:Controller 执行前 -
postHandle:Controller 执行后,视图渲染前 -
afterCompletion:请求完成后
3.5.2 请求状态
-
请求对象未发生结构变化
-
适合做登录态校验、权限控制
3.5.3 示例代码
STEP 1 创建一个实现 HandlerInterceptor 接口的类。
该接口包含三个方法:preHandle、postHandle 和 afterCompletion。这些方法分别在请求处理之前、控制器处理之后以及视图渲染之后被调用。根据需求重写相应的方法。
比如:
java
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
String token = request.getHeader("Authorization");
if (token == null) {
response.setStatus(401);
return false;
}
return true;
}
}
STEP 2:注册到WebMvcConfigurer实现类中
要在 Spring MVC 应用程序中使用拦截器,您需要将其注册到 WebMvcConfigurer 实现类中。
在下述示例代码中,我们通过实现 WebMvcConfigurer 接口并重写 addInterceptors 方法来配置拦截器。在 addInterceptors 方法中,我们将自定义的拦截器添加到 InterceptorRegistry 中。这样,当有请求到达应用程序时,拦截器将按照我们在配置文件中定义的顺序执行。
java
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 LoginInterceptor()); // 添加自定义拦截器
}
}
3.6 Controller(控制层)
3.6.1 职责说明
-
接收请求参数
-
调用业务层
-
返回结果(JSON / View)
3.6.2 请求变化
-
请求体被解析为 Java 对象(如 DTO)
-
参数绑定完成
3.6.3 示例代码
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/login")
public Result login(@RequestBody LoginDTO dto) {
return userService.login(dto);
}
}
3.7 Service(业务层)
3.7.1 职责说明
-
封装核心业务逻辑
-
控制事务边界
-
不直接接触 HTTP
3.7.2 示例代码
@Service
public class UserService {
public Result login(LoginDTO dto) {
User user = userMapper.findByUsername(dto.getUsername());
// 业务校验
return Result.success(user);
}
}
3.8 Mapper / DAO(数据访问层)
3.8.1 职责说明
-
与数据库交互
-
执行 SQL
-
返回数据实体
3.8.2 示例代码
@Mapper
public interface UserMapper {
@Select("select * from user where username = #{username}")
User findByUsername(String username);
}
3. 设计原理与分层思想
3.1 为什么要分这么多层
3.1.1 职责单一原则
-
Filter:通用前置处理
-
Interceptor:业务相关拦截
-
Controller:请求与响应
-
Service:业务规则
-
Mapper:数据访问
3.1.2 解耦与可维护性
-
各层职责清晰
-
修改一层不影响其他层
-
易于扩展与测试
3.2 Filter 与 Interceptor 的设计区分
| 维度 | Filter | Interceptor |
|---|---|---|
| 所属规范 | Servlet | Spring MVC |
| 生效范围 | 所有 Servlet | 仅 Controller |
| 使用场景 | 编码、日志、通用处理 | 登录、权限、业务拦截 |
图片来源: