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. 架构师修炼 II - 表达思维与驾驭方法论

    开篇之前我想先说说当年开发的那点事儿:大约10年前吧,我还是一个程序员的时候经常都是遇到这样的项目开发流程: 解决方案 :满足客户目的和投标用的一堆文档(不少还是互联网上抄的) ,是以Word为主的纯 ...

  2. LeetCode 3Sum (Two pointers)

    题意 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all ...

  3. Python中浅拷贝和深拷贝的区别总结与理解

    单层浅拷贝 import copy a = 1 # 不可变数据类型 copy_a = copy.copy(a) print(id(a),id(copy_a)) # 内存地址相同 a = [1,2] # ...

  4. 吉他软件Guitar Pro播放无声音的解决方法

    系统环境:适用于Windows操作系统和macOS的Guitar Pro . 问题表现:已成功安装Guitar Pro ,但用Guitar Pro 播放时没有任何声音或播放失真. 解决方案:首先确保安 ...

  5. Loadrunner 面试常见问题

    三大组件: 脚本生成器,录制和调试脚本 . 控制台,设置运行和资源场景 结果分析器,将测试结果数据以不同的图表呈现,便于性能分析 工作原理: 录制:根据不同协议,记录下客户端和服务器二者之间的对话,生 ...

  6. 学习git 新手。这个写的不错

    转自:https://www.cnblogs.com/wupeiqi/p/7295372.html 版本控制 说到版本控制,脑海里总会浮现大学毕业是写毕业论文的场景,你电脑上的毕业论文一定出现过这番景 ...

  7. jmeter的开启

    先申明我以jmeter的3.2版本来描述本文内容,通常不要选择太新的版本,因为新版本容易出现不稳定和不兼容因素.启动jmeter的前提是JDK已经安装和配置,具体的JDK已经安装和配置自行查资料,此处 ...

  8. PHP Laravel 连接并访问数据库

    第一次连接数据库 数据库配置位于config/database.php数据库用户名及密码等敏感信息位于.env文件创建一个测试表laravel_course <?php namespace Ap ...

  9. python爬虫-使用cookie登录

    前言: 什么是cookie? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密). 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想 ...

  10. Final互评------《飞词》---- 拉格朗日2018

    一.基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题; N(Need,需求):拉格朗日2018团队对需求分析的做法是通过问卷调查的形式,通过问卷调查分析出目前的大学生群体 ...