GenericFilterBean与OncePerRequestFilter:何时分别使用?
Hey there! Let's break this down clearly since I know the docs can be a bit vague on the edge cases. First, let's cover when a regular Filter might run multiple times for a single user request, then compare the use cases, and finally answer your specific JWT/CORS questions.
A standard Filter will execute multiple times for the same user-initiated request in these scenarios:
- Request Forwarding: When you use
request.getRequestDispatcher("/some-path").forward(req, res)in a Servlet or Controller, the forwarded request will re-traverse the entire filter chain. That means your Filter runs once for the original request, and again for the forwarded one. - Request Inclusion: Similar to forwarding, using
request.getRequestDispatcher("/some-path").include(req, res)will trigger the Filter again for the included resource request. - Error Page Redirects: If your app has custom error pages configured (like via
web.xmlor Spring Boot's error handling), when an exception triggers a redirect to the error page, that redirect request will also pass through the filter chain a second time.
- Regular Filter: Ideal for logic that needs to run on every request instance—including the original request and any internal forwards/inclusions. Examples:
- Counting access to all resources in your app (including internally routed APIs or pages)
- Detailed logging for every single entry into the filter chain, regardless of whether it's a user-initiated or internal request
- OncePerRequestFilter: Built explicitly to ensure your logic runs exactly once per original user request, avoiding redundant processing. Perfect for:
- Authentication and authorization checks (repeating these wastes resources and can cause logical bugs)
- One-time request context setup (like setting a unique request ID in MDC)
- Single-pass response header configuration (to avoid duplicate headers)
1. JWT Filter: Which implementation to use?
Use OncePerRequestFilter without question.
Why? JWT authentication is meant to verify a user's identity once when the original request arrives. If you use a regular Filter, any internal forwards or error redirects will trigger the JWT logic again. This leads to:
- Unnecessary repeated parsing of the JWT token (wasting CPU cycles)
- Potential bugs, like repeatedly overwriting the authentication object in
SecurityContextHolder(which could break valid session context)
JWT validation is a one-and-done step for a request's lifecycle—OncePerRequestFilter guarantees that exactly once.
2. CORS Filter: Which implementation to use?
Use OncePerRequestFilter as the best practice.
Why? CORS requires setting response headers like Access-Control-Allow-Origin and Access-Control-Allow-Methods. These headers only need to be set once per user request. A regular Filter would re-add these headers on forwards/inclusions, which:
- Goes against HTTP standards (duplicate headers are not recommended, even if most browsers tolerate them)
- Can cause compatibility issues with strict browsers or API clients
Additionally, preflight OPTIONS requests (used for CORS) only need to be handled once. OncePerRequestFilter ensures your CORS logic runs exactly once, keeping responses clean and efficient.
内容的提问来源于stack exchange,提问作者Bogdan Emil Mariesan

