【发布时间】:2013-07-30 11:48:43
【问题描述】:
我正在尝试使用 Spring MVC 设置版本化服务,使用继承来扩展旧控制器以避免重写未更改的控制器方法。我的解决方案基于关于版本控制服务的previous question,但是我遇到了不明确映射的问题。
@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 中有两个具有相同映射的方法。作为一种解决方法,我尝试在没有任何请求映射的情况下覆盖 BookmarkJsonControllerV2 中的 writeBookmark:
@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 对象作为参数。这似乎完全是 hack,我宁愿永远不要这样做。
那么有没有更好的方法来使用 Spring MVC 实现 URL 版本控制,它只允许我在后续版本中覆盖更新的方法,还是我唯一真正的选择是完全重写每个控制器?
【问题讨论】:
-
你能发布你的 applicationContext.xml 吗?你是手动编写bean还是通过扫描包?这两种配置的混合可能会导致此问题。
-
@DeividiCavarzan 我确实在
application-context.xml中设置了一些与 Spring Security 相关的 bean,其余的都是通过扫描包来设置的。现在想起来有点没有实际意义,因为我已经通过为我的 REST 服务使用不同的处理程序映射来完成这项工作。
标签: spring-mvc versioning