skip to content

Compare PathPatternParser with the legacy AntPathMatcher. Why did Spring switch defaults, and what behavioral differences should you know?

level: principalimportance: should knowfreq 40%

answer

  1. Ant = re-parse string per request; PathPattern = parse once at startup
  2. PathPattern default: WebFlux always, MVC since 5.3/Boot 2.4
  3. PathPattern adds {*name}, restricts ** to the end
  4. Suffix matching off; trailing-slash match deprecated
  5. Override: spring.mvc.pathmatch.matching-strategy=ant-path-matcher

basics

~20 s

AntPathMatcher parses patterns as strings on every request; PathPatternParser pre-compiles each pattern once into a reusable PathPattern, so matching is much faster. PathPatternParser is the modern default and adds {*name} capture, but restricts ** to the pattern's end.

solid answer

~50 s

AntPathMatcher, the original matcher, works on the raw request string and re-parses the pattern for every request, doing repeated string operations. PathPatternParser parses each route once at startup into an immutable, linked PathPattern of path elements, then matches against a pre-parsed RequestPath — this is allocation-light and significantly faster, which is why it's the default in WebFlux from the start and in Spring MVC since Framework 5.3 / Boot 2.4+. Behavioral differences: PathPattern requires ** to be the last segment and appear once; it adds the capturing {*name} multi-segment variable; it treats the path as decoded, structured segments (matrix variables and encoding handled per-segment); and it deliberately does not support suffix pattern matching or the older trailing-slash-insensitive behavior in the same way (trailing-slash match is being tightened/deprecated). You can still force AntPathMatcher via configuration if a legacy pattern needs mid-path ** — but new code should assume PathPattern.

go deeper

for a junior

Likely unaware two matchers exist; fine to not know.

for a middle

Knows PathPattern is the modern default and is faster; fuzzy on specifics.

for a senior

Explains pre-parsing vs per-request parsing, the ** placement rule, and {*name}; aware suffix matching is off.

for a principal

Sets org-wide policy: standardize on PathPattern, ban mid-path ** and suffix/trailing-slash reliance, treat catch-alls as security-sensitive, knows the override property and its narrow legitimate use.

## Two matchers, one job Spring must decide which `@RequestMapping` a URL belongs to. Historically it used **`AntPathMatcher`** (Ant-style globbing on strings). Spring 5 introduced **`PathPatternParser`** producing **`PathPattern`** objects, now the recommended and default engine. ## How each works **`AntPathMatcher`**: - Operates on the **raw path String**. - For every request, it tokenizes both the pattern and the path and walks them, performing substring/regex work repeatedly. - Flexible: `**` may appear anywhere (`/a/**/b`). - Cost: re-parsing per request; more allocations; the classic hotspot in high-throughput routing. **`PathPatternParser` / `PathPattern`**: - Parses each configured pattern **once at startup** into an immutable chain of `PathElement`s (literal, single-char wildcard, `{var}`, `{var:regex}`, single-segment `*`, capturing/`**`). - At request time it matches this pre-parsed structure against a **`RequestPath`** — the request URL already decomposed into `PathContainer` segments with separators and matrix parameters identified. - Much lower per-request overhead → higher throughput. ## Why Spring switched the default 1. **Performance**: pre-parsing + structured matching removes per-request string parsing. 2. **Correctness/clarity around encoding and matrix variables**: `PathPattern` matches on parsed segments, so URL-decoding and matrix parameters (`;k=v`) are handled per segment rather than by fragile string manipulation on the whole path. 3. **Determinism**: restricting `**` to the tail removes ambiguous backtracking cases. Defaults: **WebFlux** always used `PathPattern`. **Spring MVC** made it the default in Framework 5.3 / Boot 2.4, and Boot 3 / Framework 6 solidified it. ## Behavioral differences to know | Aspect | AntPathMatcher | PathPatternParser | |---|---|---| | Pattern parsing | Per request | Once at startup | | `**` placement | Anywhere | Only final segment, once | | Capturing tail | Not directly | `{*name}` | | Suffix pattern matching (`.*`) | Was supported (now off) | Not supported | | Speed | Slower | Faster | | Matrix variables | String-based | Per-segment, first-class | ## Trailing slash Both historically treated `/foo` and `/foo/` as matching the same mapping (`setUseTrailingSlashMatch`). This lenient behavior is **deprecated** in modern Spring — the guidance is to make trailing-slash a genuine 404 or handle redirects explicitly. Don't rely on it in new code. ## Suffix pattern matching Old MVC could map `/foo` and match `/foo.json`, `/foo.xml` (content-negotiation via extension). This is a **security risk** (RFD attacks, path-variable truncation) and is **disabled by default**; `PathPattern` doesn't implement the legacy suffix behavior at all. Use `Accept` headers or explicit extensions instead. ## Choosing / overriding Spring Boot uses `PathPattern` by default. If a legacy application genuinely needs mid-path `**`, you can revert via `spring.mvc.pathmatch.matching-strategy=ant-path-matcher` (or configure `PathMatchConfigurer.setPatternParser`/`setPathMatcher`). But this is a compatibility escape hatch, not a design choice for new systems. ## Principal-level framing Standardize on `PathPattern`, forbid mid-path `**` (redesign such routes), avoid suffix and trailing-slash reliance, and treat `{*path}` catch-alls as security-sensitive (path traversal). Understand that WebFlux and MVC now share the same matching semantics, which simplifies reasoning across a mixed stack.

  • What single Spring Boot property reverts MVC to the legacy matcher, and when would you use it?
    spring.mvc.pathmatch.matching-strategy=ant-path-matcher. Use it only as a compatibility escape hatch for legacy patterns (e.g. mid-path **) you can't yet redesign — not for new applications.
  • Why is suffix pattern matching disabled by default in modern Spring?
    It caused security problems — Reflected File Download (RFD) attacks and path-variable value truncation when a value contained a dot — and made content negotiation ambiguous. Explicit Accept headers are safer.
  • How does PathPattern handle URL encoding and matrix variables differently?
    It matches against a RequestPath already decomposed into decoded segments with matrix parameters (;k=v) separated per segment, rather than doing string surgery on the whole raw path as AntPathMatcher did.

saying these in an interview costs you the question

  • Claiming AntPathMatcher is still the MVC default
  • Saying the two matchers are behaviorally identical
  • Not knowing ** placement differs between them
  • Relying on trailing-slash or suffix (.json/.xml) matching as current best practice

context