Spring MVC でバージョン管理されたサービスをセットアップしようとしています。継承を使用して古いコントローラーを拡張し、変更されていないコントローラー メソッドを書き換えないようにしています。バージョン管理サービスに関する以前の質問に基づいてソリューションを作成しましたが、あいまいなマッピングの問題に遭遇しました。
@Controller
@RequestMapping({"/rest/v1/bookmark"})
public class BookmarkJsonController {
@ResponseBody
@RequestMapping(value = "/write", produces = "application/json", method = RequestMethod.POST)
public Map<String, String> writeBookmark(@RequestParam String parameter) {
// Perform some operations and return String
}
}
@Controller
@RequestMapping({"/rest/v2/bookmark"})
public class BookmarkJsonControllerV2 extends BookmarkJsonController {
@ResponseBody
@RequestMapping(value = "/write", produces = "application/json", method = RequestMethod.POST)
public BookmarkJsonModel writeBookmark(@RequestBody @Valid BookmarkJsonModel bookmark) {
// Perform some operations and return BookmarkJsonModel
}
}
このセットアップで私は得IllegalStateException: Ambiguous mapping found
ます。BookmarkJsonControllerV2
これに関する私の考えは、戻り値/引数の型が異なる 2 つのメソッドがあるため、同じマッピングを持つ 2 つのメソッドがあるということです。回避策として、リクエストマッピングなしでオーバーライドしようとしwriteBookmark
ました:BookmarkJsonControllerV2
@Override
public Map<String, String> writeBookmark(@RequestParam String parameter) {
return null; // Shouldn't actually be used
}
ただし、このコードをコンパイルして実行すると、まだあいまいなマッピングの例外が発生します。ただし、URL/rest/v2/bookmark/write
にアクセスすると、空/null の応答が返されました。変更後return null
:
return new HashMap<String, String>() {{
put("This is called from /rest/v2/bookmark/write", "?!");
}};
そのマップで JSON を受け取ります。これは、リクエスト マッピング アノテーションがないにもかかわらず、明らかにスーパー クラスからアノテーションを「継承」していることを示しています。この時点で、コントローラーの拡張を将来的に保証するための唯一の「解決策」は、すべてのコントローラーを返して、オブジェクトとオブジェクトObject
のみを引数として持つことです。これは完全なハックのように思えます。HttpServletRequest
HttpServletResponse
では、Spring MVC を使用して URL のバージョン管理を実現するためのより良い方法はありますか?これにより、後続のバージョンで更新されたメソッドのみをオーバーライドできるようになりますか、それとも各コントローラーを完全に書き換える唯一の現実的なオプションですか?