java Servlet 概念讲解 以及和Golang概念对比
一 JAVA Servlet
Java Web 中核心、常被混淆的一组概念:Servlet
、Filter
、Interceptor
、WebMvcConfigurer
。
下面将用 系统性、通俗易懂的方式,从底层到高层,帮你彻底理清它们的概念、作用、执行顺序和关系。
🧱 一、先看整体架构:请求是怎么被处理的?
Client (浏览器) ↓ HTTP 请求(如 /user/1)
Tomcat(Servlet 容器)↓
Filter(过滤器) → 可有多个↓
DispatcherServlet(Spring MVC 的核心 Servlet)↓
Interceptor(拦截器) → 可有多个↓
@Controller 方法(你的业务逻辑,如 getUser())↓
Interceptor(后处理)↓
View Resolver / @ResponseBody(生成响应)↓
Interceptor(完成后)↓
Filter(响应处理)↓
HTTP 响应返回给 Client
✅ 关键点:这是一个责任链模式,请求从外向内层层进入,响应从内向外层层返回。
📌 二、核心概念详解
1. Servlet
—— Java Web 的“基石”
✅ 是什么?
- 一个 Java 类,实现
javax.servlet.Servlet
接口 - 运行在 Servlet 容器(如 Tomcat)中
- 负责处理 HTTP 请求并返回响应
✅ 典型代表:
public class DispatcherServlet extends HttpServlet { ... }
DispatcherServlet
是 Spring MVC 的前端控制器,所有请求都先经过它。
✅ 作用:
- 接收请求
- 分发请求到对应的
@Controller
- 返回响应
✅ 生命周期(容器管理):
init()
:初始化service()
:处理请求(内部调用doGet
/doPost
)destroy()
:销毁
2. Filter
—— Servlet 层的“过滤器”
✅ 是什么?
- 实现
javax.servlet.Filter
接口 - 运行在 Servlet 容器层,早于 Spring
- 可以拦截所有进入的请求和返回的响应
✅ 典型用途:
- 统一设置字符编码(
CharacterEncodingFilter
) - 跨域处理(
CorsFilter
) - 日志记录(记录请求耗时)
- 权限校验(如 JWT 验证)
- XSS 防护
✅ 代码示例:
@Component
@Order(1) // 执行顺序,数字越小越早
public class LogFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("Filter: 请求开始");long startTime = System.currentTimeMillis();// 放行,进入下一个 Filter 或 Servletchain.doFilter(request, response);System.out.println("Filter: 请求结束,耗时: " + (System.currentTimeMillis() - startTime) + "ms");}
}
✅ 特点:
- 基于 Servlet 规范,不依赖 Spring
- 可以操作
ServletRequest
和ServletResponse
(如包装请求体) - 执行在 Interceptor 之前
3. Interceptor
—— Spring 层的“拦截器”
✅ 是什么?
- 实现
org.springframework.web.servlet.HandlerInterceptor
- 运行在 Spring MVC 层,晚于 Filter
- 拦截的是 被 DispatcherServlet 分发后的请求
✅ 典型用途:
- 登录状态检查(如验证 Session)
- 权限控制(如角色校验)
- 日志记录(记录 Controller 调用)
- 性能监控
✅ 代码示例:
@Component
public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {System.out.println("Interceptor: 请求进入 Controller 之前");// 可以在这里验证登录String token = request.getHeader("Authorization");if (token == null || !token.equals("secret")) {response.setStatus(401);return false; // 拦截,不再放行}return true; // 放行}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {System.out.println("Interceptor: Controller 执行完,视图渲染前");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("Interceptor: 请求完成(包括异常)");}
}
✅ 特点:
- 依赖 Spring 容器
- 可以拿到
Handler
(即哪个 Controller 方法要执行) - 有三个生命周期方法:
preHandle
、postHandle
、afterCompletion
- 执行在 Filter 之后,Controller 之前
4. WebMvcConfigurer
—— Spring MVC 的“配置中心”
✅ 是什么?
- 一个接口,用于定制化 Spring MVC 的行为
- 你可以通过实现它来注册
Interceptor
、Filter
、静态资源、跨域等
✅ 典型用途:
- 注册自定义
Interceptor
- 配置静态资源路径(如
/static/**
) - 配置跨域(CORS)
- 添加消息转换器(如 Fastjson)
✅ 代码示例:
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate AuthInterceptor authInterceptor;// ✅ 注册 Interceptor@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(authInterceptor).addPathPatterns("/api/**") // 拦截哪些路径.excludePathPatterns("/api/login", "/api/public/**"); // 放行哪些路径}// ✅ 配置静态资源@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");}// ✅ 配置跨域@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/api/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE");}
}
✅ 特点:
- 是一个配置类,不是拦截器或过滤器
- 用于集中管理 Spring MVC 的各种配置
- 它本身不处理请求,但可以注册处理请求的组件
🔗 三、四者关系图解
+---------------------+
| Client |
+----------+----------+|↓
+---------------------+
| Filter Chain | ← 实现 Filter 接口
| (Servlet 层) | 如:日志、编码、CORS
+----------+----------+|↓
+---------------------+
| DispatcherServlet | ← 核心 Servlet
| (Spring MVC 入口) |
+----------+----------+|↓
+---------------------+
| Interceptor Chain | ← 实现 HandlerInterceptor
| (Spring 层) | 如:登录检查、权限
+----------+----------+|↓
+---------------------+
| @Controller 方法 | ← 你的业务逻辑
+----------+----------+|↓ (响应返回)
+---------------------+
| Interceptor (后处理)|
+----------+----------+|↓
+---------------------+
| Filter (后处理) |
+----------+----------+|↓
+---------------------+
| Response |
+---------------------+
✅ 执行顺序:
Filter.preFilter
Interceptor.preHandle
Controller
Interceptor.postHandle
Interceptor.afterCompletion
Filter.postFilter
🆚 四、Filter vs Interceptor 对比
对比项 | Filter | Interceptor |
---|---|---|
所属层次 | Servlet 容器层 | Spring MVC 层 |
依赖 Spring | ❌ 不依赖 | ✅ 依赖 |
执行时机 | 所有请求(包括静态资源) | 仅 Spring MVC 映射的请求 |
能否拦截静态资源 | ✅ 可以 | ❌ 默认不拦截(除非配置) |
能否获取 Controller 方法 | ❌ 不能 | ✅ 能(Object handler ) |
配置方式 | @WebFilter 或 FilterRegistrationBean | WebMvcConfigurer.addInterceptors() |
典型用途 | 编码、CORS、XSS | 登录验证、权限、日志 |
✅ 五、使用建议
场景 | 推荐使用 |
---|---|
统一编码、CORS、XSS 防护 | ✅ Filter |
登录验证、权限控制 | ✅ Interceptor (更方便获取 handler) |
记录 Controller 耗时 | ✅ Interceptor |
记录所有请求耗时(含静态资源) | ✅ Filter |
注册多个 Interceptor 并设置顺序 | ✅ WebMvcConfigurer |
✅ 六、总结:一句话记住它们
概念 | 一句话总结 |
---|---|
Servlet | Java Web 的“发动机”,所有请求的入口 |
Filter | Servlet 层的守门人,不依赖 Spring,能操作原始请求/响应 |
Interceptor | Spring 层的检查站,依赖 Spring,能知道你要调哪个 Controller |
WebMvcConfigurer | Spring MVC 的“配置中心”,用来注册 Interceptor、CORS、静态资源等 |
💡 记忆口诀:
- Filter 先过,Interceptor 后拦
- Filter 管请求,Interceptor 管 Controller
- WebMvcConfigurer 是管理员,负责安排它们上班
在实际开发中,你最常用的是:
- 用
WebMvcConfigurer
注册Interceptor
- 用
Interceptor
做登录校验 - 用
Filter
做全局日志或 CORS
理解它们,你就掌握了 Spring Boot Web 开发的“请求处理流水线”!
二 Golang(Gin)视角对比看 JAVA Servlet
下面将用 对比方式,把在 Java 中熟悉的 Servlet
、Filter
、Interceptor
、WebMvcConfigurer
等概念,一一对应到 Golang Gin 框架中的实现,帮助快速建立认知映射。
🧱 一、整体架构对比
Java (Spring Boot + Tomcat) | Go (Gin) |
---|---|
Tomcat(Servlet 容器) | net/http server(Go 原生 HTTP 服务器) |
DispatcherServlet | Gin 的 Engine 路由器 |
Filter(过滤器) | Middleware(中间件) |
Interceptor(拦截器) | 也是 Middleware(但执行时机不同) |
WebMvcConfigurer | 自定义配置函数 + Use() 注册中间件 |
@Controller + @RequestMapping | router.GET("/path", handler) |
✅ 核心思想:Gin 的 Middleware 就是 Filter 和 Interceptor 的“融合体”,但更灵活。
🔗 二、详细概念映射与代码对比
1. Servlet
/ DispatcherServlet
→ Gin 的 Engine
和 net/http
Java:
// 所有请求进入 DispatcherServlet
public class DispatcherServlet extends HttpServlet { ... }
Go (Gin):
package mainimport "github.com/gin-gonic/gin"func main() {r := gin.Default() // 创建 Gin 引擎(相当于 DispatcherServlet)r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong"})})r.Run(":8080") // 启动内置 HTTP 服务器(相当于内嵌 Tomcat)
}
✅
gin.Default()
就是 Gin 的“前端控制器”,负责路由分发。
✅r.Run()
内部启动的是 Go 原生net/http
服务器,没有额外容器(Go 自带 HTTP 服务器)。
2. Filter
→ Gin 的 全局 Middleware
Java Filter(日志):
public class LogFilter implements Filter {public void doFilter(...) {System.out.println("Filter: 请求开始");chain.doFilter(request, response);System.out.println("Filter: 请求结束");}
}
Go Gin Middleware(日志):
func LoggerMiddleware() gin.HandlerFunc {return func(c *gin.Context) {fmt.Println("Middleware: 请求开始")// 记录开始时间c.Next() // 放行,进入下一个中间件或 handlerfmt.Println("Middleware: 请求结束")}
}func main() {r := gin.New()r.Use(LoggerMiddleware()) // 全局注册,相当于 Filterr.GET("/hello", func(c *gin.Context) {c.String(200, "Hello")})r.Run(":8080")
}
✅
r.Use()
= 注册全局 Filter
✅c.Next()
=chain.doFilter()
✅ 执行时机:在所有路由处理之前/之后
3. Interceptor
→ Gin 的 路由级 Middleware
Java Interceptor(登录检查):
public boolean preHandle(HttpServletRequest request, ...) {if (!request.getSession().containsKey("user")) {response.setStatus(401);return false;}return true;
}
Go Gin Middleware(JWT 验证):
func AuthMiddleware() gin.HandlerFunc {return func(c *gin.Context) {token := c.GetHeader("Authorization")if token == "" {c.AbortWithStatus(401) // 拦截,不继续return}// 假设验证通过c.Next() // 放行}
}func main() {r := gin.Default()// 只对 /api 路由组生效,相当于 Interceptor 的路径匹配api := r.Group("/api")api.Use(AuthMiddleware()) // 相当于 addInterceptor()api.GET("/user", func(c *gin.Context) {c.JSON(200, gin.H{"user": "admin"})})r.Run(":8080")
}
✅ 这就是“Interceptor”的行为:只对部分路径生效,可拦截。
4. WebMvcConfigurer
→ Go 的 配置函数
Java WebMvcConfigurer:
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(authInterceptor).addPathPatterns("/api/**");}
}
Go 配置方式(函数式):
func setupRouter() *gin.Engine {r := gin.Default()// 配置 CORSr.Use(CORSMiddleware())// 配置日志r.Use(LoggerMiddleware())// 配置认证中间件(仅 /api)api := r.Group("/api")api.Use(AuthMiddleware()){api.GET("/user", getUserHandler)api.POST("/order", createOrderHandler)}// 静态资源r.Static("/static", "./static")return r
}func main() {r := setupRouter()r.Run(":8080")
}
✅
setupRouter()
就是你的WebMvcConfigurer
,集中管理路由和中间件。
🔄 三、执行流程对比
Java 流程:
Client↓
Filter → pre↓
DispatcherServlet↓
Interceptor → preHandle↓
Controller↓
Interceptor → postHandle↓
Interceptor → afterCompletion↓
Filter → post↓
Response
Gin 流程:
Client↓
Middleware 1 (全局)↓
Middleware 2 (路由组)↓
Handler (业务逻辑)↓
Middleware 2 (后处理)↓
Middleware 1 (后处理)↓
Response
✅
c.Next()
是关键:它会执行后续的所有中间件和 handler,然后回到当前中间件继续执行。
func MyMiddleware() gin.HandlerFunc {return func(c *gin.Context) {fmt.Println("Before Next")c.Next() // ← 所有后续逻辑在这里执行fmt.Println("After Next")}
}
🆚 四、核心差异总结
对比项 | Java Spring Boot | Go Gin |
---|---|---|
HTTP 服务器 | 内嵌 Tomcat(外部依赖) | Go 原生 net/http (语言内置) |
Filter vs Interceptor | 两个不同概念 | 统一为 Middleware |
注册方式 | WebMvcConfigurer | 函数式 r.Use() 或 group.Use() |
性能 | JVM 启动慢,运行时优化好 | 编译型语言,启动快,内存低 |
部署 | .jar 文件 | 单个可执行文件(无依赖) |
学习曲线 | 高(概念多) | 低(简洁直观) |
✅ 五、Gin 中常见的“中间件”对应 Java 概念
Java 概念 | Gin 实现 |
---|---|
CharacterEncodingFilter | Gin 默认 UTF-8,无需配置 |
CorsFilter | gin-contrib/cors 中间件 |
OncePerRequestFilter | 自定义 Middleware,用 c.Next() 控制 |
HandlerInterceptor | 路由组 Middleware |
WebMvcConfigurer | setupRouter() 函数 |
@ControllerAdvice | Gin 无直接对应,可用 c.Error() + 全局错误处理 |
✅ 六、总结:一张表记住对应关系
Java 概念 | Go (Gin) 对应物 | 说明 |
---|---|---|
Tomcat | net/http server | Go 原生支持,无需外容器 |
DispatcherServlet | gin.Engine | 路由分发核心 |
Filter | 全局 Middleware | r.Use(mw) |
Interceptor | 路由组 Middleware | group.Use(mw) |
WebMvcConfigurer | setupRouter() 函数 | 集中配置中间件、路由 |
chain.doFilter() | c.Next() | 放行请求 |
preHandle / postHandle | c.Next() 前后代码 | 中间件内部控制 |
静态资源 | r.Static() | 类似 Spring 的 addResourceHandlers |
最终建议
- 如果你熟悉 Spring Boot,Gin 的 Middleware 就是 Filter + Interceptor 的“超级融合版”。
- Gin 更简洁,没有“套娃容器”,Go 自带 HTTP 服务器。
- 性能上,Gin 通常比 Spring Boot 更快、更省资源(编译型语言优势)。
- 部署上,Gin 生成一个可执行文件,丢上去就能跑,比 JAR 更轻量。