先上代码:
主要是控制器:
@Controller public class AccountController { private Mapaccounts = new ConcurrentHashMap (); private static Logger log = LoggerFactory .getLogger(AccountController.class); // value = "createForm", @RequestMapping(method = RequestMethod.GET) public String getCreateForm(Model model) { log.info("createForm method is running"); model.addAttribute(new Account()); return "account/createForm"; } // value = "account", @RequestMapping(method = RequestMethod.POST) public String create(@Valid Account account, BindingResult result) { log.info("account method is running"); if (result.hasErrors()) { List errors = result.getAllErrors(); for (ObjectError error : errors) { log.info(error.getDefaultMessage()); } return "account/createForm"; } this.accounts.put(account.assignId(), account); return "redirect:/account/" + account.getId(); } // account @RequestMapping(value = "/{id}", method = RequestMethod.GET) public String getView(@PathVariable Long id, Model model) { log.info("getView method is running"); Account account = this.accounts.get(id); if (account == null) { throw new ResourceNotFoundException(id); } model.addAttribute(account); return "account/view"; } }
在mvc中配置了一个首页:
在使用3.0.5版本时,只能welcome。而在使用3.1.4版本能访问到:getCreateForm 和create,但是不能访问到getView方法。而且不能进入首页。
后来发现,在3.0.5版本中,使用的是AbstractUrlHandlerMapping,而在3.1的版本中使用的是AbstractHandlerMethodMapping、这是3.1版本中新加的类。
根据日志信息分析一下:
先来看3.0.5版本中的:AbstractUrlHandlerMapping:
Mapped URL path [/{id}] onto handler 'accountController'
Mapped URL path [/{id}.*] onto handler 'accountController'
Mapped URL path [/{id}/] onto handler 'accountController'
控制器中的三个方法都不能匹配上,只有首页“/”能匹配上。所以只能访问首页。
再来看3.1.4版本中的:AbstractHandlerMethodMapping
Mapped "{[],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}"
Mapped "{[],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}"
Mapped "{[/{id}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}"
可以看到,第一个方法和第二个方法只是get/和post的区别。而且匹配“/” 所以,直接通过Url访问时,匹配上了getCreateForm方法。跳转到account/createForm。在createFrom中提交的时候使用的是post,则匹配上第二个方法。而第三个则无法匹配(其实是前面两个把第三个覆盖了。)
解决办法:在控制器上加上:@RequestMapping(value = "/account")
首页可以直接访问。
account。
在3.1.5中:
1:Mapped "{[/account],methods=[POST],
2:Mapped "{[/account/{id}],methods=[GET]
3:Mapped "{[/account],methods=[GET],
首页,上面三种都不能匹配,所以会显示welcome。
访问/account。会匹配3. 提交表单会匹配1。查看表单内容可匹配3.
在3.0.5版本中:
[/account/{id}]
[/account/{id}.*]
[/account/{id}/]
[/account]
[/account.*]
[/account/]
好吧,由于我对Spring源码不熟悉,不知道怎么会是这样。但是通过观察还是可以看出都是可以匹配上的。
留待以后深入源码级别的时候去了解了解,当然大神能告诉我也行。
可以看出来,3.0和3.1的mvc是有区别的,以前一直没有关注。当然以前都是直接声明映射方式的。