【发布时间】:2012-03-16 13:49:26
【问题描述】:
我有一个简单的控制器,如下所示:-
@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)?它应该在这里处理 (/groups POST) 是有道理的,因为请求映射与 URI 匹配。为什么 (/groups/1 POST) 不会在此处引发“未找到映射”异常?事实上,几乎任何 URI 以 /groups 开头的 POST(例如:/groups/bla/1 POST)也将通过映射 #3 来处理。
谁能给我一个清楚的解释?非常感谢。
澄清
我知道我可以使用更合适的方法(如 GET、POST、PUT 或 DELETE)...或者我可以创建另一个请求映射来处理 /groups/{id} POST。
不过,我真正想知道的是……
.... “为什么映射 #3 也处理 /groups/1 POST?”
“最接近的匹配”推理似乎不成立,因为如果我删除映射 #2,那么我会认为映射 #1 将处理 /groups/1 GET,但它不会,它会导致“未找到映射” " 例外。
我只是有点难过。
【问题讨论】:
-
为什么不使用 PUT 来更新资源?那将是正确的 HTTP 协议。
-
web表单提交只支持GET和POST,我这里不做AJAX调用,所以我现在不能依赖PUT和DELETE。
-
@limc,这不是真的,可以在
org.springframework.web.filter.HiddenHttpMethodFilter的帮助下(在服务器端)将 POST 修改为其他请求类型 -
@Ralph,我的错...我刚才正在阅读,我意识到我可以使用
_methodhack。根据您的帖子,我现在正在浏览spring源代码。
标签: java spring spring-mvc request-mapping