我正在尝试使用 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
具有相同映射的方法。作为一种解决方法,我尝试writeBookmark
在BookmarkJsonControllerV2
没有任何请求映射的情况下覆盖:
@Override
public Map<String, String> writeBookmark(@RequestParam String parameter) {
return null; // Shouldn't actually be used
}
但是,当我编译并运行这段代码时,我仍然遇到了不明确映射的异常。但是,当我点击 URL 时,/rest/v2/bookmark/write
我得到了一个空/空响应。更改return null
为:
return new HashMap<String, String>() {{
put("This is called from /rest/v2/bookmark/write", "?!");
}};
我会收到带有该映射的 JSON,表明尽管没有任何请求映射注释,但它显然是“继承”了超类的注释。在这一点上,我对控制器扩展进行未来验证的唯一“解决方案”是让每个控制器返回Object
并且只有HttpServletRequest
和HttpServletResponse
对象作为参数。这似乎是一个彻头彻尾的黑客攻击,我宁愿永远不要这样做。
那么有没有更好的方法来使用 Spring MVC 实现 URL 版本控制,它只允许我在后续版本中覆盖更新的方法,或者是我唯一真正的选择来完全重写每个控制器?