Spring MVC 中 @ModelAttribute 注解的妙用

Spring MVC 提供的这种基于注释的编程模型,极大的简化了 web 应用的开发。其中 @Controller@RestController 注解的组件使用 @RequestMapping@ExceptionHandler 等注解来表示请求映射,请求输入,异常处理等,使得开发者能专注于业务逻辑的编写,提高了开发效率。 带注释的控制器具有灵活的方法签名,不必扩展基类,也不需要实现特定的接口。

可以使用 ServletWebApplicationContext 中的标准 Spring bean 定义来定义控制器 bean。 所有带有 @Controller 注解的类会被自动检测,就像 Spring 通常的扫描方式一样,检测类路径中的 @Component 类,并为它们自动注册 bean 定义。 它也充当注释类的刻板,表示它可以作为一个 Web 组件。

带有 @RequestMapping 注解的方法叫做 Handler Method - 处理器方法,它的参数可以来自很多地方,比如 ServletRequestServletResponseHttpSession 等。

@ModelAttribute

在控制器的处理器方法参数上添加 @ModelAttribute 注释可以访问模型中的属性,如果不存在这个模型,则会自动将其实例化,产生一个新的模型。 模型属性还覆盖了来自 HTTP Servlet 请求参数的名称与字段名称匹配的值,也就是请求参数如果和模型类中的域变量一致,则会自动将这些请求参数绑定到这个模型对象,这被称为数据绑定,从而避免了解析和转换每个请求参数和表单字段这样的代码。 例如:

@PostMapping("/componies/{componyId}/departments/{departmentId}/edit")
public String processSubmit(@ModelAttribute Department department) { }

这个处理器方法中的 department 参数会被从以下几个来源进行匹配绑定:

  • 已经定义过的模型方法(带有 @ModelAttribute 的方法,后面解释)
  • HTTP Session 中和字段名匹配的会话方法(带有 @SessionAttribute 的方法,和模型方法类似,只是作用域不同)
  • 经过 URL 转换器解析过的路径变量
  • 该模型类的默认构造方法
  • 调用具有与 Servlet 请求参数匹配的参数的 “主构造函数”; 参数名称通过 JavaBeans @ConstructorProperties 或通过字节码中的运行时保留参数名称确定。

虽然一般都是使用模型方法 Model method 来使用属性填充模型,但另一种方法是依靠 Converter<String,T> 识别 URI 路径变量来绑定。在下面的例子中,模型属性名称 “user” 与 URI 路径变量 “user” 匹配,并且通过将 String 类型的用户名交给给已注册的 Converter<String,User> 这个转换器来生成创建模型:

@PutMapping("/users/{user}")
public String saveUser(@ModelAttribute("user") User user) {
// ...
}

在获得模型属性实例之后,请求数据就会被绑定到模型属性上。 WebDataBinder 负责将 Servlet 请求参数名称(查询参数或表单字段)和目标模型对象上的字段名称进行匹配。 必要时会将属性的类型进行转换后再填充对应字段。

数据绑定不能保证不会出错,发生错误时默认情况下会抛出 BindException 异常,但要在处理器方法中识别出这些错误,需要在 @ModelAttribute 后面添加一个 BindingResult 类型的参数,需要注意的是:这个参数必须和模型属性参数 (@ModelAttribute 参数)相邻,如下所示:

@PostMapping("/owners/{componyId}/departments/{departmentId}/edit")
public String processSubmit(@ModelAttribute("compony") Compony compony, BindingResult result) {
if (result.hasErrors()) {
return "componyForm";
}
// ...
}

这个例子表示如果用户提交的表单不符合预期的匹配规则,就会返回视图 componyForm

有时候我们需要获得一个不带数据绑定的模型属性,也就是需要在处理器方法中使用 new 关键字来实例化一个对象。但是在 Spring MVC 中就不用这么麻烦了,我们可以将模型注入控制器并直接访问它,或者可以添加 @ModelAttribute(binding = false) 来表示不需要绑定数据,如下所示:

@ModelAttribute
public UserForm setUpForm() {
return new UserForm();
} @ModelAttribute

public User findUser(@PathVariable String userId) {

return userRepository.findOne(userId);

} @PostMapping("update")

public String update(@Valid UserUpdateForm form, BindingResult result,

@ModelAttribute(binding=false) User user) {

// ...

}

在参数上添加 javax.validation.Valid 注解或 Spring 的 @Validated 注解,就可以在数据绑定后使用字段校验功能了,就像这样:

@PostMapping("/componies/{componyId}/departments/{departmentId}/edit")
public String processSubmit(@Valid @ModelAttribute("department") Department department, BindingResult result) {
if (result.hasErrors()) {
return "departmentForm";
}
// ...
}

这样写和在方法体中写 model.addAttribute("compony",compony) 是等价的。

需要注意的是 @ModelAttribute 注解如果不加,按照 BeanUtils 中的 isSimpleProperty 方法来判断,如果不属于简单类型的参数,都会被自动视为 ModelAttribute

欢迎访问 郑保乐的博客

      </div>
</div>
</div>
posted @
2019-02-26 17:13 
星朝 
阅读(...) 
评论(...) 
编辑 
收藏

Spring MVC 中 @ModelAttribute 注解的妙用的更多相关文章

  1. Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法

    Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法 在Action中方法的返回值都是字符串行,一般情况是返回某个JSP,如: return "xx" ...

  2. spring 以及 spring mvc 中常用注解整理

    spring 以及 spring mvc 中常用注解整理 @RequestMapping(映射路径) @Autowired(注入 bean 对象) 例如: @Autowired private Bas ...

  3. Spring MVC中基于注解的 Controller

         终于来到了基于注解的 Spring MVC 了.之前我们所讲到的 handler,需要根据 url 并通过 HandlerMapping 来映射出相应的 handler 并调用相应的方法以响 ...

  4. 0001 - Spring MVC中的注解

    1.概述 Spring MVC框架提供了功能强大的注解,大大简化了代码开发的同时也提升了程序的可扩展性 2.注解 2.1.@RequestMapping Spring MVC通过@RequestMap ...

  5. Spring MVC中@RequestMapping注解使用技巧(转)

    @RequestMapping是Spring Web应用程序中最常被用到的注解之一.这个注解会将HTTP请求映射到MVC和REST控制器的处理方法上. 在这篇文章中,你将会看到@RequestMapp ...

  6. 在Spring MVC中使用注解的方式校验RequestParams

    概述   Spring MVC支持Bean Validation,通过这个验证技术,可以通过注解方式,很方便的对输入参数进行验证,之前使用的校验方式,都是基于Bean对象的,但是在@RequestPa ...

  7. Spring MVC中@ControllerAdvice注解实现全局异常拦截

    在网上很多都把Advice翻译成增强器,其实从翻译工具上看到,这个单词翻译是忠告,通知的意思. 首先这个注解实在Spring Web包下,而Spring MVC离不开Spring Web的依赖,所以经 ...

  8. spring mvc之@ModelAttribute注解

    1.@ModelAttribute注释void返回值的方法 @Controller public class HelloModelController { @ModelAttribute public ...

  9. Spring MVC SessionAttributes ModelAttribute注解

    说明 本文主要针对 @SessionAttributes注解 和 @ModelAttribute注解的基础用法进行解析.至于为什么会将这两个注解放在一起,是因为它们之间还是有点影响的. @Sessio ...

随机推荐

  1. git常用命令学习总结

    英语真是我的硬伤啊,提示都要用百度翻译看一遍,费劲... 下面是我日常工作中遇到的各种问题汇总 1.远程服务器分支与本地代码合并 我第一次打出 git pull 显示下面的错误 就怪我英语太差,都懒得 ...

  2. Jenkins Maven安装设置

    Jenkins Maven安装设置 如果没有学习过 Maven 的朋友,可以先了解 Maven教程,然后再进一步学习本教程文章. 第1步:下载和设置Maven Maven的官方网站就是Apache M ...

  3. 微软职位内部推荐-Senior Software Engineer_HPC

    微软近期Open的职位: Job Title: Senior Software Engineer_HPC Location: Shanghai, China Are you passionate ab ...

  4. M2 Daily SCRUM要求

    每个人的工作 (有work item 的ID):昨天已完成的工作,今天计划完成的工作:工作中遇到的困难. 燃尽图 照片 每人的代码/文档签入记录(不能每天都在 “研讨”, 但是没有代码签入) 如实报告 ...

  5. Estimation And Gain

    Estimation: Almost every is spent on ergod the text and build the dictionary. Gains: I have never us ...

  6. 每日scrum(5)

    进入冲刺第五天,软件的界面设计成为主打,收集学校的很多美图是我们组的任务: 问题在于软件已很难有很大的改进,大方向也都是变不了的 任务看板: 燃尽图:

  7. 软件工程学习之小学四则混合运算出题软件 Version 1.00 设计思路及感想

    对于小学四则混合运算出题软件的设计,通过分析设计要求,我觉得为了这个软件在今后便于功能上的扩充,可以利用上学期所学习的<编译原理>一课中的LL1语法分析及制导翻译的算法来实现.这样做的好处 ...

  8. c++中队列queue和栈stack的基本操作

    1.queue 模板类的定义在<queue>头文件中. 定义queue 对象的示例代码如下:queue<int> q1;queue<double> q2; queu ...

  9. 暑假学习笔记(一)——初识Neo4j和APICloud入门

    暑假学习笔记(一)--初识Neo4j和APICloud入门 20180719笔记 1.Neo4j 接了学姐的系统测试报告任务,感觉工作很繁重,但是自己却每天挥霍时光.9月份就要提交系统测试报告了,但是 ...

  10. 格式化输出Json对象

    1.调用方式: alert(JsonUti.convertToString(jsonObj)); //jsonObj为json对象. 2.格式化输出Json对象方法定义: var JsonUti = ...