java attribute的作用_@ModelAttribute 的使用

本文详细解析了Spring MVC中@ModelAttribute注解的应用方式,包括其在方法及参数上的使用、数据绑定特性以及与@Valid和@Validated配合进行数据验证的方法。

@ModelAttribute注解可被应用在 方法 或 方法参数 上。

对方法使用 @ModelAttribute 注解:

注解在方法上的@ModelAttribute说明了方法的作用是用于添加一个或多个属性到model上。这样的方法能接受与@RequestMapping注解相同的参数类型,只不过不能直接被映射到具体的请求上。

@ModelAttribute 方法会先被调用

在同一个控制器中,注解了@ModelAttribute的方法实际上会在@RequestMapping方法之前被调用。以下是几个例子:

package com.pudding.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class ModelAttributeController {

@ModelAttribute

public void init(Model model) {

System.out.println("@RequestMapping方法");

}

@RequestMapping("/model-attribute")

public String get() {

System.out.println("@ModelAttribute方法");

return "model-attribute";

}

}

控制台输出的结果如下:

9473f1a50dfb78cb186c16d5b7b6f871.png

无返回值的 @ModelAttribute 方法

一般被 @ModelAttribute 注解的无返回值控制器方法被用来向 Model 对象中设置参数,在控制器跳转的页面中可以取得 Model 中设置的参数:

ModelAttributeController.java:

package com.pudding.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class ModelAttributeController {

@ModelAttribute

public void init(Model model) {

model.addAttribute("arg", "model中设置的参数");

}

@RequestMapping("/model-attribute")

public String get() {

return "model-attribute";

}

}

model-attribute.jsp:

pageEncoding="UTF-8"%>

Insert title here

3cf70f5b096fc9725e62d4220d859bc5.png

可以发现,我们在被 @RequestMapping 标注的方法中并没有设置任何参数,但是页面却取得了在 @ModelAtribute 标注的方法设置的参数。由此可知,可以使用 @ModelAttribute 标注的方法来设置其他 @ReqeustMapping 方法的公用参数,这样就不用每一个方法都设置共同的 Model 参数。

package com.pudding.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class ModelAttributeController {

@ModelAttribute

public void init(Model model) {

model.addAttribute("arg", "model中设置的参数");

}

@RequestMapping("/model-attribute")

public String get() {

return "model-attribute";

}

@RequestMapping("/demo")

public String demo() {

return "demo";

}

}

在 demo.jsp 和 model-attribute.jsp 中都可以获得名为 "arg" 的 Model 参数。

有返回值的 @ModelAttribute 方法

有返回值的 @ModelAttribute 方法和没有返回值的 @ModelAttribute 方法的区别就是,没有返回值的 @ModelAttribute 方法使用 model.addAttribute(String key, Object value); 来向 Model 中增加参数。而有返回值的 @ModelAttribute 方法则直接将需要增加的参数返回。

package com.pudding.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

import com.pudding.bean.User;

@Controller

public class ModelAttributeController {

@ModelAttribute

public User init(Model model) {

User user = new User("小明", 18);

return user;

}

@RequestMapping("/model-attribute")

public String get() {

return "model-attribute";

}

}

上面的代码的作用是,向 Model 中增加了 key 为 "user" value 为 user 对象的键值对。这个 user 对象中有 username = "小明",age = 18 的属性。

使用 @ModelAttribute("key") 来显示指定属性名

属性名没有被显式指定的时候又当如何呢?在这种情况下,框架将根据属性的类型给予一个默认名称。举个例子,若方法返回一个User类型的对象,则默认的属性名为"user"。你可以通过设置@ModelAttribute注解的值来改变默认值。当向Model中直接添加属性时,请使用合适的重载方法addAttribute(..)-即,带或不带属性名的方法。

以下代码将会向 Model 中设置一个 key 为 "person" ,value 为 user对象的键值对:

package com.pudding.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

import com.pudding.bean.User;

@Controller

public class ModelAttributeController {

@ModelAttribute("person")

public User init(Model model) {

User user = new User("小明", 18);

return user;

}

@RequestMapping("/model-attribute")

public String get() {

return "model-attribute";

}

}

@ModelAttribute 和 @RequestMapping 注解在同一个方法上

如果 @ModelAttribute 和 @RequestMapping 注解在同一个方法上,那么代表给这个请求单独设置 Model 参数。此时返回的值是 Model 的参数值,而不是跳转的地址。跳转的地址是根据请求的 url 自动转换而来的。比如下面的例子中跳转页面不是 HelloWorld.jsp 而是 model-attribute.jsp。并且参数只有在 model-attribute.jsp 中能够取得,而 demo.jsp 中不能取得。

package com.pudding.controller;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

@Controller

public class ModelAttributeController {

@ModelAttribute("message")

@RequestMapping("/model-attribute")

public String init(Model model) {

return "HelloWorld";

}

@RequestMapping("/demo")

public String get() {

return "demo";

}

}

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

如上一小节所解释,@ModelAttribute注解既可以被用在方法上,也可以被用在方法参数上。这一小节将介绍它注解在方法参数上时的用法。

数据绑定

注解在方法参数上的@ModelAttribute说明了该方法参数的值将由model中取得。如果model中找不到,那么该参数会先被实例化,然后被添加到model中。在model中存在以后,请求中所有名称匹配的参数都会填充到该参数中。这在Spring MVC中被称为数据绑定,一个非常有用的特性,节约了你每次都需要手动从表格数据中转换这些字段数据的时间。

和 BindingResult 配合使用

使用 @ModelAttribute 进行数据绑定之后,可以使用 BindingResult 来返回数据验证结果。数据验证可以使用 hibernate validation 的 @Valid 标签或者 spring Validator 校验机制的 @Validated 配合 BindingResult 使用。 或者自定义校验器来返回 BindingResult 对象来进行校验。你可以通过Spring的 表单标签来在同一个表单上显示错误信息。

@Valid 校验器:

@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)

public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) {

if (result.hasErrors()) {

return "petForm";

}

// ...

}

@Validated 校验器:

@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)

public String processSubmit(@Validated @ModelAttribute("pet") Pet pet, BindingResult result) {

if (result.hasErrors()) {

return "petForm";

}

// ...

}

自定义校验器:

@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)

public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) {

// 自己编写一个校验方法来处理 result 对象

new PetValidator().validate(pet, result);

if (result.hasErrors()) {

return "petForm";

}

// ...

}

@Attribute@ModelAttribute 是 Spring MVC 中用于处理模型数据的注解,它们有以下区别: 1. 作用范围不同:@SessionAttribute 用于将属性值保存在会话作用域中,而 @ModelAttribute 则是用于将属性值添加到模型中,它的作用范围可以是请求、会话或应用级别。 2. 生命周期不同:@SessionAttribute 的生命周期与会话一致,即属性值会在会话期间一直存在,直到会话结束或手动移除。而 @ModelAttribute 的生命周期只在请求处理过程中有效,随着请求的完成,模型中的属性值即被销毁。 3. 使用方式不同:@SessionAttribute 注解可以应用在控制器类上或者控制器方法参数上,以指定哪些属性需要保存在会话中。而 @ModelAttribute 注解主要用于控制器方法参数上,用于绑定请求参数到方法参数或添加模型属性。 - 控制器类上使用 @SessionAttributes: ```java @Controller @SessionAttributes("user") public class UserController { ... } ``` - 控制器方法参数上使用 @SessionAttribute: ```java @GetMapping("/user") public String getUserInfo(@SessionAttribute("user") User user) { ... } ``` - 控制器方法参数上使用 @ModelAttribute: ```java @GetMapping("/user") public String getUserInfo(@ModelAttribute("user") User user) { ... } ``` 总的来说,@SessionAttribute@ModelAttribute 都用于处理模型数据,但是 @SessionAttribute 用于在会话中保存属性值,而 @ModelAttribute 则是用于绑定请求参数或添加模型属性。它们的使用方式和作用范围不同,需要根据具体的需求选择合适的注解来处理模型数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值