3.12 @ModelAttribute注解
org.springframework.web.bind.annotation.Modelattribute注解用于将请求参数绑定到对象。
@ModelAttribute注解只支持一个属性value,类型为String,表示绑定的属性名称。
提示:被@ModeAttribute注释的方法会在Controller每个方法执行前被执行,因此在个Controlller被映射到多个URL时,要谨慎使用。
@ModelAttribute注解的使用方式有很多种,下面来逐一介绍。
示例 @ModelAttribute注解的使用
index.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试@ModelAttribute</title> </head> <body> <h3>测试@ModelAttribute的不同用法</h3> <a href="loginForm1">测试@ModelAttribute(value="")注释返回具体类的方法 </a> <br> <a href="loginForm2">测试@ModelAttribute注释的返回值为void的方法</a> <br> <a href="loginForm3">测试@ModelAttribute注释的返回值为具体类的方法</a> <br> <a href="loginForm4">测试@ModelAttribute和@RequestMapping同时注释一个方法的情况 </a> <br> <a href="loginForm5">测试@ModelAttribute注释一个方法的参数 </a> <br> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package org.fkit.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping;
@Controller public class FormController { @RequestMapping(value = "/{formName}") public String loginForm(@PathVariable String formName) { return formName; } }
|
1.测试@ModelAttribute(value=””)注释返回具体类的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试@ModelAttribute</title> </head> <body> <h3>测试@ModelAttribute(value="")注释返回具体类的方法</h3> <form action="login1" method="post"> <table> <tr> <td><label>登录名: </label></td> <td><input type="text" id="loginname" name="loginname"></td> </tr> <tr> <td><input id="submit" type="submit" value="登录"></td> </tr> </table> </form> </body> </html>
|
ModelAttribute1Controller.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package org.fkit.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam;
@Controller public class ModelAttribute1Controller { @ModelAttribute("loginname") public String (@RequestParam("loginname") String loginname) { return loginname; } @RequestMapping(value = "/login1") public String login1() { return "result1"; } }
|
在ModelAttributelController类中除了@RequestMapping映射的login1方法之外,还提供了一个userModel1方法,该方法上有一个@ModelAttribute注解。此处@ModelAttribute注解默认的value值为"loginname",用来指定model属性的名称,而model属性的值就是userModel1方法的返回值。被@ModelAttribute注解的userMode11方法会先于login1调用,它把请求参数loginname的值赋给userModel1方法的形式参数loginname,并设置了一个属性loginname到Model当中,而属性的值就是方法的形式参数loginame的值。
result1.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试@ModelAttribute(value="")注释返回具体类的方法</title> </head> <body> 访问request作用范围域中的loginname对象:${requestScope.loginname } <br> </body> </html>
|
在跳转的result1.jsp中可以访问到由@ModelAttribute设置在Model中的的loginname的值。
部署ModelAttributeTest这个Web应用,在浏览器中输入如下URL来测试应用:
1
| http://localhost:8080/ModelAttributeTest/index.jsp
|
单击”测试@ModelAttribute(value="")注释返回具体类的方法“超链接发送请求,跳转到loginForm1.jsp页面.
输入登录名"test",单击”登录“按钮发送请求,而后将先调用userMode1方法,再调用login1方法并跳转到result1.jsp页面。
可以看到,在request作用域中访问到了Model的值。
2.测试@ModelAttribute注释void返回值的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试@ModelAttribute</title> </head> <body> <h3>测试@ModelAttribute注释void返回值的方法</h3> <form action="login2" method="post"> <table> <tr> <td><label>登录名: </label></td> <td><input type="text" id="loginname" name="loginname"></td> </tr> <tr> <td><label>密码: </label></td> <td><input type="password" id="password" name="password"></td> </tr> <tr> <td><input id="submit" type="submit" value="登录"></td> </tr> </table> </form> </body> </html>
|
ModelAttribute2Controller.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package org.fkit.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 org.springframework.web.bind.annotation.RequestParam;
@Controller public class ModelAttribute2Controller { @ModelAttribute public void userModel2(@RequestParam("loginname") String loginname, @RequestParam("password") String password, Model model) { model.addAttribute("loginname", loginname); model.addAttribute("password", password); } @RequestMapping(value = "/login2") public String login2() { return "result2"; } }
|
在ModelAttribute2Controller类中除了@RequestMapping映射的login2方法之外,还提供了一个userModel2方法,该方法上有一个@ModelAttribute注解。 userMode12方法会先于login方法被调用,它把请求参数值赋给对应变量,model属性名称和值由model.addAttribute()方法实现,前提是要在方法中加入一个Model类型的参数。
result2.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试@ModelAttribute注释void返回值的方法</title> </head> <body> 访问request作用范围域中的loginname对象:${requestScope.loginname } <br> 访问request作用范围域中的password对象:${requestScope.password } </body> </html>
|
在跳转的result2.jsp中可以访问到由@ModelAttribute注解设置的loginname和password的值.
在浏览器中输入如下URL来测试应用
1
| http://localhost:8080/ModelAttributeTest/index.jsp
|
单击”测试@ModelAttribute注释void返回值的方法“超链接发送请求,将会跳转到loginForm2.jsp页面。
输入登录名"test",密码”123456“,单击”登录”按钮发送请求,而后将先调用userModel2方法,再调用login2方法,并跳转到result2.jsp页面.
可以看到,在request作用域中访问到了Model的值。
3.测试@ModelAttribute注释返回具体类的方法
ModelAttribute3Controller.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| package org.fkit.controller;
import java.util.ArrayList; import java.util.List; import org.fkit.domain.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam;
@Controller public class ModelAttribute3Controller { private static List<User> userList; public ModelAttribute3Controller() { super(); userList = new ArrayList<User>(); User user1 = new User("test", "123456", "测试用户"); User user2 = new User("admin", "123456", "管理员"); userList.add(user1); userList.add(user2); } public User find(String loginname, String password) { for (User user : userList) { if (user.getLoginname().equals(loginname) && user.getPassword().equals(password)) { return user; } } return null; } @ModelAttribute public User userModel3(@RequestParam("loginname") String loginname, @RequestParam("password") String password) { return find(loginname, password); } @RequestMapping(value = "/login3") public String login3() { return "result3"; } }
|
在ModelAttribute3Controller类中除了@RequestMapping映射的login3方法之外,还提供了一个userModel3方法,该方法上有一个@ModelAttribute注解。 userModel3方法会先于login3方法被调用,这里model属性的名称没有被指定,它由@ModelAttribute注解的userModel3方法的返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称就是user。此处find(loginname, password)方法用来模拟数据库根据登录名和密码查询用户的功能实现。
result3.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试@ModelAttribute注释返回具体类的方法</title> </head> <body> 访问request作用范围域中的user对象:${requestScope.user.username } <br> </body> </html>
|
在跳转的result2.jsp页面中可以访问到由@ModelAttribute设置的loginname和password的值。
在浏览器中输入如下URL来测试应用
1
| http://localhost:8080/ModelAttributeTest/index.jsp
|
单击”测试@ModelAttribute注释返回具体类的方法“超链接发送请求,将跳转到lσginForm3.jsp页面,如图3.15所示,输入登录名"test",密码"123456",单击”登录”按钮发送请求,而后将先调用userModel3方法,再调用login3方法,并跳转到result3.jsp页面.
可以看到,在request作用域中访问到了User对象。
4 测试ModelAttribute和@RequestMapping同时注释一个方法
ModelAttribute4Controller.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package org.fkit.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping;
@Controller public class ModelAttribute4Controller { @RequestMapping(value = "/login4") @ModelAttribute(value = "username") public String login4() { return "admin"; } }
|
在ModelAttribute4Controller中,@ModelAttribute和@RequestMapping同时注释一个方法,此时login4方法的返回值并不是一个视图名称,而是model属性的值,视图名称是@RequestMapping的value值"/login4",Model的属性名称由@ModelAttribute的value值指定,这相当于在request中封装了username(key)= admin(value)。
注意,此处login4方法跳转的结果是"/login4"。
login4.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试@ModelAttribute和@RequestMapping同时注释一个方法</title> </head> <body> 访问request作用范围域中的username对象:${requestScope.username } <br> </body> </html>
|
在浏览器中输入如下URL来测试应用
1
| http://localhost:8080/ModelAttributeTest/index.jsp
|
单击”测试@ModelAttribute和@RequestMapping同时注释一个方法“超链接发送请求,而后跳转到loginForm4.jsp页面,如图3.15所示。输入登录名"test",密码"123456",单击”登录”按钮发送请求,将调用login4方法,跳转到login4.jsp页面,如图3.18所示。
可以看到,在request作用域中访问到了username的值,也就是login4方法的返回值"admin"。
5 测试@ModelAttribute注释一个方法的参数
ModelAttribute5Controller.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package org.fkit.controller;
import org.fkit.domain.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping;
@Controller public class ModelAttribute5Controller { @RequestMapping(value = "/login5") public String login5(@ModelAttribute User user) { user.setUsername("管理员"); return "result5"; } }
|
ModelAttribute5Controller类中login5方法的参数User使用了@ModelAttribute注解,前台页面的控件的值会自动入参到@ModelAttribute注解修饰的对象的同名属性当中。这种方式是在实际开发中使用最多的方式。
result5.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试@ModelAttribute注释一个方法的参数</title> </head> <body> 访问request作用范围域中的user对象的loginname属性:${requestScope.user.loginname } <br> 访问request作用范围域中的user对象的password属性:${requestScope.user.password } <br> 访问request作用范围域中的user对象的username属性:${requestScope.user.username } <br> </body> </html>
|
在浏览器中输入如下URL来测试应用
1
| http://localhost:8080/ModelAttributeTest/index.jsp
|
单击测试@ModelAttribute注释一个方法的参数超链接发送请求,跳转到loginForm5.jsp页面.输入登录名test,密码123456,单击登录按钮发送请求,而后将调用login5方法,跳转到result5.jsp页面.
可以看到,在request作用域中访问到了User对象.
提示@ModeAttribute注解的使用方法有很多种,非常灵活,读者可以根据业务需求选择使用。
原文链接: 3.12 @ModelAttribute注解