How is the order of Servlet Filters determined, and why does order matter?
answer
- web.xml: order = order of <filter-mapping>
- @WebFilter order is NOT spec-guaranteed
- Spring: FilterRegistrationBean.setOrder / @Order, lower = earlier
- Auth before business; decode before parse
- Outermost filter = first to see request, last to see response
basics
~20 sIn web.xml, filter order follows the order of the <filter-mapping> elements. With annotations or Spring, you set order explicitly (e.g. @Order or a FilterRegistrationBean). Order matters because earlier filters can short-circuit or change the request before later ones see it.
solid answer
~50 sServlet Filters execute in a defined sequence, and that sequence is the contract of the chain. With web.xml, the order is the order of <filter-mapping> elements (url-pattern mappings before servlet-name mappings). With @WebFilter annotations the order is not guaranteed by the spec, so for deterministic ordering you typically register filters programmatically — in Spring Boot via FilterRegistrationBean.setOrder, or with @Order / Ordered on a bean picked up by the framework. Order matters because filters are nested: an earlier filter wraps all later ones. An authentication filter must run before a filter that assumes an authenticated user; a decompression filter must run before one that parses the body; a logging filter placed first sees the raw request and the final response. A misordered chain can leak unauthenticated access, double-wrap responses, or log the wrong thing. Spring Security itself is a single filter that internally runs its own ordered sub-chain.
go deeper
Knows that filters run in some order and that order can change behavior; can point to web.xml mapping order.
Explains each configuration mechanism (web.xml, @WebFilter, FilterRegistrationBean/@Order), that annotation order is not guaranteed, and gives ordering-dependent examples like auth-before-business.
Reasons about nesting (outermost sees request first/response last), wrapping dependencies, and the security implications of misordering; chooses programmatic ordering when it matters.
Designs the whole interception stack, places Spring Security's single proxy correctly, and reasons about ordering interactions across filters, Spring interceptors, and AOP.
### Why ordering is even a question Servlet Filters form a **Chain of Responsibility**: each filter runs, optionally calls `chain.doFilter` to invoke the next, and optionally runs code after that call returns. Because the calls are **nested** (filter A calls B which calls C which calls the servlet, then unwinds back through C, B, A), the *order* in which filters are placed determines: - which filter sees the request **first** (outermost), - which filter sees the response **last** (also the outermost, on the unwind), - and which filters get a chance to **short-circuit** (reject/redirect) before later ones run. ### How order is configured There are several configuration mechanisms, and they decide order differently: **1. `web.xml` (the classic deployment descriptor).** You declare `<filter>` elements (the definitions) and `<filter-mapping>` elements (which URLs each applies to). The **order of the `<filter-mapping>` elements** in the file determines execution order. The spec also says URL-pattern mappings are applied before servlet-name mappings. This is fully deterministic. **2. `@WebFilter` annotation.** You annotate a class with `@WebFilter("/path")` and the container discovers it. The Servlet spec does **not** define a relative order among annotation-discovered filters — it is implementation-dependent. So if order matters, annotations alone are risky. **3. Programmatic registration (Spring Boot).** You register a filter as a `FilterRegistrationBean` and call `setOrder(int)` — **lower numbers run earlier**. Alternatively a `Filter` bean implementing `Ordered` or carrying `@Order` is ordered by the framework. This is the recommended approach when order is important, because it is explicit and centralized. ### Key terms - **Deployment descriptor (`web.xml`)**: an XML file declaring servlets, filters, and mappings. - **`FilterRegistrationBean`**: a Spring Boot object that wraps a filter and exposes URL patterns and an `order`. - **`@Order` / `Ordered`**: Spring's general ordering mechanism; lower value = higher priority = runs first. - **Short-circuit**: a filter ending the request (not calling `chain.doFilter`) so later handlers never run. ### Why order matters — concrete cases - **Security before business**: an authentication filter must run *before* any filter or servlet that assumes a logged-in user; if it runs too late, an attacker may reach protected logic. - **Decode before parse**: a filter that decompresses or sets character encoding must run before one that reads/parses the body, or the body is read in the wrong form. - **Logging placement**: a logging filter placed outermost (first) sees the untouched request and the fully-built response; placed innermost it misses what other filters changed. - **Wrapping**: filters that wrap the request/response (e.g. to cache the body) must enclose the filters that depend on the wrapper. ### Spring Security note In a Spring app, **Spring Security registers a single `DelegatingFilterProxy` / `FilterChainProxy`** into the servlet chain, and *inside* it runs its **own** ordered chain of security filters. So there are effectively two levels of Chain of Responsibility, and the position of that one security filter within the servlet chain still matters. ### Failure modes of bad ordering Leaking unauthenticated access, double-compressing a response, logging a request that a later filter then rewrites, or a wrapper filter not enclosing its dependents. Each is a direct consequence of the nesting order — which is why ordering is treated as part of the chain's contract, not an afterthought.
- You annotate two filters with @WebFilter and order is wrong. How do you fix it deterministically?Register them programmatically as FilterRegistrationBeans with explicit setOrder values (or use web.xml filter-mapping order), since annotation order is not guaranteed by the spec.
- In Spring's @Order, does a lower or higher number run first?Lower runs first (higher precedence). Ordered.HIGHEST_PRECEDENCE is Integer.MIN_VALUE.
saying these in an interview costs you the question
- Assuming @WebFilter annotation order is deterministic
- Thinking filter order doesn't affect security
- Confusing @Order semantics (lower runs first, not last)
- Believing the servlet runs before filters