资讯专栏INFORMATION COLUMN

3.10、在方法参数上使用@ModelAttribute注解

huhud / 2321人阅读

摘要:本节解释它用在参数上的情形。一个用在方法参数上的注解指示了参数应该从模型这里所说的模型指中获取。方法是一种常用的从数据库中获取属性的方式,可以通过使用注解把这种属性在各个请求之间共享。下一步是数据绑定。

  这一部分实例见这个项目的 mvc 分支下的 ModelAttrArgsController.java

  上节说过,@ModelAttribute可以用在方法或方法参数上。本节解释它用在参数上的情形。

  一个用在方法参数上的@ModelAttribute注解指示了参数应该从模型(这里所说的“模型”指 Model)中获取。如果模型中不存在,参数会首先被实例化,然后添加到模型中。一旦模型中存在,这个参数的字段会被所有的名字匹配的请求参数所填充。这在 Spring MVC 中叫做数据绑定,它能够把你从要对每一个字段进行类型转换的繁重体力劳动中解救出来,是非常有用的机制。

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) 
{ 
    // ...
}

  上面给出的例子的 Pet 实例来自哪里?这里有一个可选项:

它可能已经存在与模型中了,因为使用了@SessionAttributes — 见“使用@SessionAttributes存储模型属性到 HTTP 会话中”一节.

它可能已经存在于模型中了,因为同一个控制器中的@ModelAttribute方法,就像上一节中解释的那样。

它可能是从URI模板变量和类型转换器中获取的(下面会详细解释)。

它可能是使用默认构造器初始化的。

@ModelAttribute方法是一种常用的从数据库中获取属性的方式,可以通过使用@SessionAttributes注解把这种属性在各个请求之间共享。在一些情况下,可以很方便的通过使用URI模板变量和类型转换器来获取这些属性。下面是一个例子:

@PutMapping("/accounts/{account}")
public String save(@ModelAttribute("account") Account account) 
{
    // ...
}

  在这个例子中,模型属性名(“account”)匹配URI模板变量名。如果你注册的一个Converter可以把字符串 account 值转换为一个 Account,那么上面的例子即使不需要@ModelAttribute也可以正常工作。

  下一步是数据绑定。WebDataBinder类匹配请求参数名称——包括请求字符串参数和表单字段——到属性字段名。在必须的类型转换(从字符串到目标类型字段)之后,匹配的字段收集好了。数据绑定和校验见官方文档第五章-检验、数据绑定和类型转换。为控制器自定义数据绑定过程见 “自定义WebDataBinder初始化”一节。

  在数据绑定之后,可能会出现一些错误,比如缺少必须字段或者类型转换错误。为了检查这些错误,你可以紧跟在@ModelAttribute参数后面添加一个BindingResult参数:

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) 
{
    if (result.hasErrors()) { return "petForm"; }
    // ...
}

  有了BindingResult之后,你就可以检查在提交同一个表单时有没有发现错误,这些错误可以通过 Spring 的表单标签来显示。

  注意到在一些情况下,在 model 中不使用数据绑定来访问一个属性是很有用的。这种情况下,你可以把Model注入到控制器中,或者在注解上使用绑定标记:

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

@ModelAttribute
public Account findAccount(@PathVariable String accountId) 
{ 
    return accountRepository.findOne(accountId); 
}

@PostMapping("update")
public String update(
        @Valid AccountUpdateForm form, BindingResult result,
        @ModelAttribute(binding=false) Account account) 
{ /* omitted */ }

  除了数据绑定,你也可以使用你自己定义的、用来传递BindingResult(用于记录数据绑定错误)的校验器调用校验这允许数据绑定和验证的错误积累在一个地方,随后报告给用户:

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) 
{
    new PetValidator().validate(pet, result);
    if (result.hasErrors()) return "petForm";

    // ...
}

  或者你可以自动调用校验,通过添加 JSR-303 的 @Valid 注解:

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) 
{
    if (result.hasErrors()) return "petForm";

    // ...
}

  关于如何配置和使用校验器,详见官方文档的5.8节“Spring校验”和第五章 校验、数据绑定和类型转换。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66040.html

相关文章

  • 3.9、方法使用@ModelAttribute注解

    摘要:用在方法上的指示那个方法的目的是添加一个或多个模型属性。在控制器中的方法的调用时机是在同一个控制器中的方法之前。注意,有两种形式的方法。注解也可以用在方法上。   这一部分翻译自 Spring 5.0.0.M1 文档中的 Using @ModelAttribute on a method 一节。这一节的演示示例在这个项目的 mvc 分支中的 ModelAttrController.ja...

    王笑朝 评论0 收藏0
  • springmvc常用注解标签详解

    摘要:分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了注解。作用该注解用于将的方法返回的对象,通过适当的转换为指定格式后,写入到对象的数据区。用于注解层,在类上面注解。使用标记的参数。 1、@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个M...

    notebin 评论0 收藏0
  • 从原理层面掌握@ModelAttribute使用使用篇)【一起学Spring MVC】

    摘要:和一起使用参照博文从原理层面掌握的使用一起学。至于具体原因,可以移步这里辅助理解从原理层面掌握的使用核心原理篇一起学再看下面的变种例子重要访问。 每篇一句 每个人都应该想清楚这个问题:你是祖师爷赏饭吃的,还是靠老天爷赏饭吃的 前言 上篇文章 描绘了@ModelAttribute的核心原理,这篇聚焦在场景使用上,演示@ModelAttribute在不同场景下的使用,以及注意事项(当然有些...

    BenCHou 评论0 收藏0
  • 从原理层面掌握@ModelAttribute使用(核心原理篇)【一起学Spring MVC】

    摘要:虽然它不是必须,但是它是个很好的辅助官方解释首先看看官方的对它怎么说它将方法参数方法返回值绑定到的里面。解析注解标注的方法参数,并处理标注的方法返回值。 每篇一句 我们应该做一个:胸中有蓝图,脚底有计划的人 前言 Spring MVC提供的基于注释的编程模型,极大的简化了web应用的开发,我们都是受益者。比如我们在@RestController标注的Controller控制器组件上用@...

    wdzgege 评论0 收藏0
  • spring-mvc注解

    摘要:关键注解的关键注解主要有其中主要是用于标记该类是一个控制器,用于指示的哪一个类或方法来处理请求动作,即用于标识具体的处理器。默认已经装配了作为组件的实现类,而由使用,将请求信息转换为对象。 关键注解 springmvc的关键注解主要有@Controller/@RequestMapping/@RequestParam/@PathVariable/@RequestHeader/@Cooki...

    EdwardUp 评论0 收藏0

发表评论

0条评论

huhud

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<