Tagbangers Blog

​Spring MVC @RequestMappingのマッピング優先度まとめ

Controllerに使う@RequestMappingにはURIの変数や正規表現などいろいろなパターンを指定できますが、どのコントローラにマッピングされるかという優先度をいつも忘れてしまうのでまとめてみます。

ちなみにパターンとして記述できる記号についてはAntPathMatcherのAntPatternComparatorの中で説明されているようで
そのdocによると、

? → 1文字にマッチ
* (ワイルドカード) → 0かそれ以上の文字数にマッチ
** (ダブルワイルドカード) → 0かそれ以上のディレクトリにマッチ

という意味になってます。


URI変数({variables})とワイルドカード(*)の数が少ないパターンに優先的にマッピングされる

これを仮に自由度と呼ぶと「自由度が少ない、特定しやすいパターンに優先的にマッピングされる」
1 /hotels/{hotel}/* →URI変数1つ + ワイルドカード1つ = 自由度2
2 /hotels/{hotel}/** →URI変数1つ + ワイルドカード2つ = 自由度3

この2つを比較すると、自由度の少ない方1にマッピングされる。

自由度が同じ場合は文字数が長い方にマッピングされる

3 /foo/bar*
4 /foo/*
この2つの場合、それぞれワイルドカードが1つなので自由度は同じ
文字数が長い方が特定しやすいため3にマッピングされる

自由度が同じで文字数も同じ場合はワイルドカードの数が少ないパターンにマッピングされる

5 /hotels/{hotel}
6 /hotels/*
この場合は自由度はそれぞれ1にカウントできるが、ワイルドカードがない5にマッピングされる。
さらにスペシャルルールとして

デフォルトマッピングパターン 「/**」 は最も優先されない

7 /**
8 /api/{a}/{b}/{c}

自由度だけ考えると8の方が多いようだけれど、8の方が特定しやすいのでそれにマッピングされる


プレフィックスパターン「/prefix/**」はダブルワイルドカード(**)を含んでいないどのパターンよりも優先されない

9 /public/**
10 /public/path3/{a}/{b}/{c}

上記と同じく、10の方が自由度が多いように見えるが、10にマッピングされる。


参考:http://docs.spring.io/spring/docs/current/spring-f...