您的位置:首页 > 移动开发

Spring MVC的@RequestMapping注解的方法签名异常

2010-06-02 19:17 399 查看

Spring MVC的@RequestMapping注解的方法签名异常

病理特征:Errors/BindingResult argument declared without preceding model attribute. Check your handler method signature

堆栈信息:忘了^_^...

自从使用Spring框架以后,笔者再也没有用EJB了,当然更不会用落后的Struts。Spring与Struts为两种不同功能的框架,没有可比性,但Spring框架中有个子模块Spring MVC与Struts功能是一样的,如果项目中选用Spring来管理服务层,加上它有MVC模块,何必再一套繁琐的Struts呢?尽管Struts2变得不再那么复杂。

Spring MVC自2.5版以来,全面支持@MVC,笔者天天做程序,曾经较长一段时间没有与xml文件打过交道,Spring 的@MVC的确灵活高效,以致爱不释手。

我们知道,当Spring MVC基础配置好后,浏览器发来的每个请求都可以通过@RequestMapping映射到方法上,例如发布一篇文章:

@Controller
public class ArticleAction{

@Resource protected GenericService service;

@RequestMapping(value="/inputArticle",method=RequestMethod.GET)
public String editAttribute(HttpServletRequest request){

request.setAttribute("article", new Article);
return "编辑界面";

}

@RequestMapping(value="/inputArticle",method=RequestMethod.POST)
public String saveArticle(@ModelAttribute("article") Article article, BindingResult result, ModelMap model, HttpServletRequest request){

try {

new ArticleValidator().validate(article, result, request);
if(result.hasErrors()){
throw new RuntimeException("验证未通过,请查检数据是否合法!");
}
service.save(article);

} catch (Exception e) {
result.reject("id", null, e.getMessage());//原来校验的错误信息也在result对象中,另加上Exception对象中的消息
return "编辑界面";
}

return "成功页面";

}

}

这是一个典型的Pojo,没有任何继承与接口,通过@Controller和@RequestMapping就使这个pojo变成了一个强大的web控制器,第一个方法是不浏览器发来GET请求,则进入编辑文章的界面,第二方法是当浏览器发来POST请求,请执行文章保存。这是新添加文章,但修改文章也是如此,因此我们没必要再做重复的方法,只要在方法签名中增加一个id绑定就可以,如果id为空,就是新增,如果有值就是修改,那么第二个方法修改如下:

public String saveArticle(@ModelAttribute("article") Article article, @RequestParam(value="id",required=false) Integer articleId, BindingResult result, ModelMap model, HttpServletRequest request){ }

这时个就会出现一个异常:Errors/BindingResult argument declared without preceding model attribute. Check your handler method signature

我搜索中文有关这个异常的解决办法(英文太菜了),答案有一个:解决方法是查看Controller的方法参数,去除BindingResult result参数即可。哈哈,典型的中国式医学手术——哪个器官坏了切掉哪个器官,也不管人受不受得了,和上篇笔者关于JPA、Hibernate出现“cannot simultaneously fetch multiple bags异常的解决”文章所提的一样,很多同仁们就是禁掉实时加载。这样都不能从根本上解决问题。

经过笔者研究读代码,发现BindingResult的对象必须与@ModelAttribute声明的对象绑定,这种绑定是由Spring MVC来做,但若他们中间插入别的参数,则无法绑定了,所以Errors/BindingResul类型的参数必须在标注@ModelAttribute 类型的参数次一位置(挨着),见org.springframework.web.bind.annotation.support.HandlerMethodInvoker源代码。

http://howsun.blog.sohu.com/119023106.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: