次のようなシンプルなコントローラーがあります:
@Controller
@RequestMapping(value = "/groups")
public class GroupsController {
// mapping #1
@RequestMapping(method = RequestMethod.GET)
public String main(@ModelAttribute GroupForm groupForm, Model model) {
...
}
// mapping #2
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String changeGroup(@PathVariable Long id, @ModelAttribute GroupForm groupForm, Model model) {
...
}
// mapping #3
@RequestMapping(method = RequestMethod.POST)
public String save(@Valid @ModelAttribute GroupForm groupForm, BindingResult bindingResult, Model model) {
...
}
}
基本的に、このページには次の機能があります。
/groups GET
)。/groups POST
)、または特定のグループを選択する(/groups/1 GET
)。/groups/1 POST
)。ここでは、両方のGET要求マッピングがどのように機能するかを理解しています。マッピング#2が定義されている場合、それ以外の場合(/groups/1 GET
)は「マッピングが見つかりません」という例外を引き起こします。
ここで理解しようとしているのは、マッピング#3が(/groups POST
)と(/groups/1 POST
)の両方を処理する理由ですか?要求マッピングがURIと一致するため、ここで(/groups POST
)を処理する必要があります。なぜ(/groups/1 POST
)が「マッピングが見つかりません」という例外をここでスローしないのですか?実際、/ groups(例:/groups/bla/1 POST
)で始まるURIのPOST)もマッピング#3によって処理されるようです。
誰かがこれを明確に説明してもらえますか?どうもありがとう。
[〜#〜]説明[〜#〜]
より適切なメソッド(GET、POST、PUT、DELETEなど)を使用できるという事実を理解しています...または、/groups/{id} POST
を処理するための別の要求マッピングを作成できます。
しかし、私が本当に知りたいのは...
.... "なぜマッピング#3は/groups/1 POST
も処理するのですか?"
マッピング#2を削除すると、マッピング#1が/groups/1 GET
を処理すると思うので、「最も近い一致」の推論は当てはまらないようです。例外。
私はここで少し困惑しています。
これは複雑です。コードを読む方が良いと思います。
Spring 3.0では、_org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
_の内部クラスServletHandlerMethodResolver
のメソッドpublic Method resolveHandlerMethod(HttpServletRequest request)
によって魔法が行われます。
このクラスのインスタンスは、すべての要求コントローラークラスに存在し、すべての要求メソッドのリストを含むフィールドhandlerMethods
を持っています。
しかし、私がそれを理解する方法を要約させてください
RequestSpecificMappingInfoComparator
ソートはこのように機能します:RequestSpecificMappingInfoComparator
は最初にAntPathMatcher
の助けを借りてパスを比較し、これに従って2つのメソッドが等しい場合、他のメトリック(パラメーターの数、ヘッダーの数など)など)は、リクエストに関して考慮されます。
Springは、最も近いものに一致するマッピングを見つけようとします。
したがって、POSTリクエストの場合、リクエストタイプに対応する唯一のマップはMapping#3です。マッピング1もマッピング2もリクエストタイプと一致しません。 Mapping#3を削除してみて、Springが一致するものを見つけられないためランタイムエラーをスローすることを確認できます。
/ groups/{id}のPUTマッピングを追加します。 POSTも動作しますが、HTTPの観点からは厳密には正しくありません。
@RequestMapping( "/ {id}"、POST)を追加することでカバーできますか?