参数绑定注解
1. @RequestParam 注解
org.springframework.web.bind.annotation.RequestParam 注解类型用于将指定的请求参数赋值给方法中的形参。
使用@RequestParam注解可指定如下表所示的属性:
属性 | 类型 | 是否必要 | 说明 |
name | String | 否 | 指定请求头绑定的名称 |
value | Stirng | 否 | name属性的别名 |
required | boolean | 否 | 指示参数是否必须绑定 |
defaultValue | String | 否 | 如果没有传递参数而使用的默认值 |
请求处理方法参数的可选类型为Java基本类型和String。示例代码如下:
@RequestMapping(value="/login") public ModelAndView login(@RequestParam("loginname") String loginname, @RequestParam("password") String password){ return ....; }假设请求如下:
http://localhost:8080/context/login?loginname=jack&password=123456
以上代码会将请求中的loginame参数的值“jack”赋给loginname变量,password参数的值“123456”赋给password变量。
@RequestParam还有如下写法:
@RequestParam(value="loginname",required=true, defaultValue="admin")
其中required参数不是必须的,默认值为true。
示例: @RequestMapping 和 @RequestParam注解的使用
新建一个项目RequestMappingTest, 加入所需的jar文件,示例代码如下:
新建User类:
package org.fkit.domain; import java.io.Serializable; //域对象,实现序列化接口 public class User implements Serializable{ /** * */ //私有字段 private String loginname; private String password; private String username; //公共构造器 public User() { super(); } public String getLoginname() { return loginname; } public void setLoginname(String loginname) { this.loginname = loginname; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
User是一个域对象,用来接收并封装前台页面传递过来的数据。
新建UserConroller:
package org.fkit.controller; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.fkit.domain.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; //Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作 @Controller //RequestMapping可以用来注释一个 控制器类,此时,所有方法都将映射为相对于类级别的请求 //表示该控制器处理的所有请求都被映射value属性所指示的路径下 @RequestMapping(value="/user") public class UserController { //静态List<User>集合,此处代替数据库用来保存注册的用户信息 private static List<User> userList; //UserController类的构造器,初始化List<User>集合 public UserController(){ super(); userList = new ArrayList<User>(); } //静态的日志类LogFactory private static final Log logger= LogFactory.getLog(UserController.class); //该方法映射的请求为http://localhost:8080/RequestMappingTest/user/register,该方法 //支持GET请求 @RequestMapping(value="/register", method=RequestMethod.GET) public String registerForm(){ logger.info("register Get 方法被调用...."); //跳转到注册页面 return "registerForm"; } //该方法映射的请求为http://localhost:8080/RequestMappingTest/user/register, //该方法支持POST请求 @RequestMapping(value="/register", method=RequestMethod.POST) //将请求中的loginname参数的值赋给loginname变量,password和username同样处理 public String login( @RequestParam("loginname") String loginname, @RequestParam("password") String password, @RequestParam("username") String username ){ logger.info("regidter POST方法被调用....."); //创建User对象 User user =new User(); user.setLoginname(loginname); user.setPassword(password); user.setUsername(username); logger.info("username"+username); //模拟数据库存储User信息 userList.add(user); //跳转到登录页面 return "loginForm"; } //该方法映射的请求为http://localhost:8080/RequestMappingTest/user/login @RequestMapping("/login") public String login( //将请求中的loginname参数的值赋给loginname变量,password同样处理 @RequestParam("loginname") String loginname, @RequestParam("password") String password, Model model ){ logger.info("登录名:"+loginname + "密码" + password); //到集合中查找用户是否存在,此处用来模拟数据库验证 for(User user : userList){ if(user.getLoginname().equals(loginname)&&user.getPassword().equals(password)){ model.addAttribute("user",user); return "welcome"; } } return "loginForm"; } }
UserController类的代码解释如下:
(1)UserController类使用了@Controller注解,是一个控制器类。
(2) UserController类上面使用了@RequestMapping(value="/user") 注解,表示该控制器处理的所有请求都被映射到user路径下。
(3)本来没有使用数据库存储用户注册信息,所以定义了一个静态的List集合userList用来代替数据库存储用户数据。
(4)registerForm方法使用了@RequestMapping(value="/register", method=RequestMethod.GET)注解,表示该方法映射的请求为http://localhost:8080/RequestMappinTest/user/register,并且只支持GET请求。该方法返回字符串"registerForm", 参考springmvc-config.xml中的配置信息,可以知道该方法只是跳转到registerForm.jsp注册页面。
(5)register方法使用了@RequestMapping(value="/register",method=RequestMethod.POST)注解,表示该方法映射的请求为http://localhost:8080/RequestMappinTest/user/register,并且只支持POST请求。该方法使用@RequestParam注解将指定的请求参数赋值给方法中形参,之后创建一个User对象保存用户传递的注册信息,最后将User对象存储到userList集合当中,之后的登录页面就可以到userList集合当中进行用户登录业务逻辑的判断。该方法返回字符串“loginForm”,并跳转到loginForm.jsp登录页面。
(6)login方法使用了@RequestMapping("/login")注解,表示该方法映射的请求为http://localhost:8080/RequestMappingTest/user/login,这里没设置method属性表示支持所有方式的请求。该方法也使用@RequestParam注解将指定的请求参数赋值给方法中的形参。之后到集合中查找用户是否存在,此处用来模拟数据库验证。login方法中还有一个参数Model对象,调用该对象的addAttribute方法可以将数据添加到Request当中(关于Model对象的知识,后面在重点讲)。最后如果用户登陆成功则返回字符串“welcome”,并跳转到welcome.jsp欢迎页面:登录失败则返回字符串“loginForm”,并跳转到“loginForm.jsp”登录页面。
新建registerForm.jsp:
代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>registerFrom</title> </head> <body> <h3>注册页面</h3> <br> <form action="register" 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><label>真实姓名:</label></td> <td><input type="text" id="username" name="username"></td> </tr> <tr> <td><input id="submit" type="submit" value="注册"></td> </tr> </table> </form> </body> </html>
registerForm.jsp是一个注册页面,用户可以输入登录名,密码和真实姓名,该表单被提交到register请求。注意,这里使用的是POST方式,响应请求的是UserController类的register方法。
新建loginForm.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>loginForm</title> </head> <body> <h3>登录页面</h3> <br> <form action="login" 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>
loginForm.jsp是一个登录页面,用户可以输入登录名和密码,该表单被提交到login请求。这里使用的是POST方式,响应请求的是UserController类的login方法。
新建welcome.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>welcome</title> </head> <body> <!-- 页面可以访问Controller传递传递出来的模型User对象 --> <h3>欢迎[${requestScope.user.username }]登录</h3> <br> </body> </html>
welcome.jsp是一个欢迎页面,用户登录成功后跳转到该页面,该页面使用了EL表达式访问request当中的user对象的username属性。
此外,还需要在web.xml文件中配置Spring MVC的前端控制器DispatcherServlet,因为每次配置基本一致,故此处不在赘述,可自行配置。
部署RequestMappingTest这个web应用,在浏览器中输入URL来测试应用:
http://localhost:8080/RequestMappingTest/user/register
可看到注册页面:
输入登录名“test”,密码“123456”,真实姓名“测试用户”,单击"注册"按钮。请求将会被提交UserController类的register方法进行注册,注册的用回信息会保存到UserController类的userList静态集合中。注册成功,将会跳转到如图所示的登录界面。
输入登录名“test”,密码“123456”,单击"登录"按钮。请求将会被提交到UserController类的login方法进行登录验证,验证成功,将会跳转到如图所示的欢迎界面。
2.@PahVariable注解
org.springframework.web.bind.annotation.PathVariable 注解类型可以非常方便地获得请求URL中的动态参数。@PathVariable注解只支持一个属性value,类型为String, 表示绑定的名称,如果省略则默认绑定同名参数。示例代码如下:
@RequestMapping(value="/pathVariableTest/{userId}") public void pathVariableTest(@PathVariable Integer userId)
假如请求的URL为“http://localhost:8080/DataBindingTest/pathVariableTest/1”,则自动将URL中模板变量{userId}绑定到通过@PathVariable注解的同名参数上,即userId变量将被赋值为1。
3.@RequestHeader注解
org.springframework.web.bind.annotation.RequestHeader注解类型用于将请求的头信息区数据映射到功能处理方法的参数上。
使用@RequestHeader注解可指定如下的属性。
属性 | 类型 | 是否必要 | 说明 |
name | String | 否 | 指定请求头绑定的名称 |
value | String | 否 | name属性的别名 |
required | boolean | 否 | 指示参数是否必须绑定 |
defaultValue | String | 否 | 如果没有传递参数而使用的默认值 |
@RequestHeader注解示例代码如下:
@RequestMapping(value="/requestHeaderTest") public void requestHeaderTest( @RequestHeader("User-Agent") String userAgent, @RequestHeader(value="Accept") String[] accepts)以上配置自动将请求头“User-Agent” 的值赋给userAgent变量上,并将“Accept”请求头的值赋给accepts参数上。
4.@CookieValue注解
org.springframework.web.bind.annotation.Cookie.Value 用于将请求的Cookie数据映射到功能处理方法参数上。
使用@CookieValue注解可指定如下所示的属性。
属性 | 类型 | 是否必要 | 说明 |
name | String | 否 | 指定请求头绑定的名称 |
value | String | 否 | name属性的别名 |
requried | boolean | 否 | 指示参数是否必须绑定 |
defaultValue | String | 否 | 如果没有传递参数而使用的默认值 |
@CookieValue注解示例代码如下:
@RequestMapping(value="/cookieValueTest") public void cookieValueTest(@CookieValue(value="JESSIONID", defaultValue="") String sessionId)
以上配置会自动将JESSIONID值设置到sessionId参数上,defaultValue表示Cookie中没有JESSIONID时默认为空。
示例:@PathVariable、@RequestHeader和@CookieValue注解的使用
新建一个项目DataBindingTest,加入所需的jar文件,在src下新建DataBindingController类。
package org.fkit.controller; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; //controller注解用于指示该类是一个控制器,可以同时处理多个请求动作 @Controller public class DataBindingController { //静态的日志类LogFactory private static final Log logger= LogFactory.getLog(DataBindingController.class); //测试@PathVariable注解 //该方法映射的请求为http://localhost:8080/DataBindingTest/pathVariableTest/{userId} @RequestMapping(value="/pathVariableTest/{userId}") public void pathVariableTest(@PathVariable Integer userId){ logger.info("通过@PathVariable获得数据: "+ userId); } //测试@RequestHeader注解 //该方法映射的请求为http://localhost:8080/DataBindingTest/requestHeaderTest @RequestMapping(value="/requestHeaderTest") public void requestHeaderTest( @RequestHeader("User-Agent") String userAgent, @RequestHeader(value="Accept") String[] accepts){ logger.info("通过@requestHeaderTest获得数据: " + userAgent); for(String accept : accepts){ logger.info(accept); } } //测试@CookieValue注解 @RequestMapping(value="/cookieValueTest") public void cookieValueTest( @CookieValue(value="JSESSIONID", defaultValue="") String sessionId){ logger.info("通过@requestHeaderTest获得数据: " + sessionId); } }
DataBindingTest类的代码解释如下:
(1) pathVariableTest(@PathVariable Integer userId)方法用于测试@PathVariable注解,它会将请求路径"/pathVariable/{userId}"中userId的值设置到方法参数的userId变量中。
(2) requestHeaderTest(@RequestHeader("User-Agent") String userAgent ,@RequestHeader(value="Accept") String[] accepts)方法用于测试@RequestHeader注解,它会将请求头"User-Agent"的值赋给到userAgent变量上,并将"Accept"请求头的值赋给到accepts参数上。
(3) cookieValueTest(@CookieValue(value="JSESSIONID",defaultValue="") String sessionId())方法会自动将JSESSIONID值入参到sessionId参数上,defaultValue表示Cookie中没有JSESSIONID时默认为空。
在webContent(webRoot)下新建index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>welcome</title> </head> <body> <h2>数据绑定测试</h2> <a href="pathVariableTest/1">测试@PathVariable注解</a><br><br> <a href="requestHeaderTest">测试@RequestHeader注解</a><br><br> <a href="cookieValueTest">测试@CookieValue注解</a><br><br> </body> </html>
此外,还需要在web.xml文件中配置Spring MVC的前端控制器DispatcherServlet,因为每次配置一致,故此处不在赘述,读者可自行配置。
同时Spring MVC还需要springmvc-config.xml配置文件,该文件内容和ControllerTest项目中的springmvc-config.xml文件一致,读者可自行配置。
部署DataBindingTest这个Web应用,在浏览器中输入如下URL来测试应用:
http://localhost:8080/DataBindingTest/index.jsp
会看到如下图所示的界面,表示SpringMVC成功跳转到初始页面index.jsp。
测试:
(1)点击“测试@PathVariable注解”超链接发送请求,将调用pathVariableTest方法,控制台输出结果如下:
可以看到,<a href="pathVariableTest/1">测试@PathVariable注解</a>的数据1被传递到方法的变量userId并输出打印在控制台。
(2) 点击"测试@RequestHeader注解" 超链接发送请求,此操作将引起调用requestHeaderTest方法,控制台输出结果如下:
可以看到。<a href="requestHeaderTest"> 测试@RequestHeader注解</a>请求头d "User-Agent"和"Accept"被传递到方法的userAgent和accepts变量并输出打印在控制台。
(3) 点击“测试@CookieValue注解”超链接发送请求,此操作将引用调用cookieValueTest方法,控制台输出结果如下:
可以看到,<a href="cookieValueTest"> 测试@CookieValue注解</a>请求中的sessionId的值被传递到方法的sessionId变量并输出打印在控制台。
5.@SessionAttributes注解
org.springframework.web.bind.annotation.SessionAttributes注解类型允许我们有选择地指定Model中的哪些属性需要转存到HttpSession对象当中。
使用@SessionAttributes注解可指定如下表所示的属性。
属性 | 类型 | 是否必要 | 说明 |
names | String[] | 否 | Model中属性的名称,即存储在HttpSession当中的属性名称 |
value | String[] | 否 | names属性的别名 |
types | Class<?>[] | 否 | 指示参数是否必须绑定 |
@SessionAttributes只能声明在类上,而不能声明在方法上。
示例:@SessionAttributes注解的使用
新建SesssionAttributesController类
package org.fkit.controller; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.fkit.domain.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.SessionAttributes; //Controller注解用于指示该类是一个控制器,可以同时处理多个请求动作 @Controller //将Model中的属性名为user的属性放入HttpSession对象当中 @SessionAttributes("user") public class SessionAttributesController { //静态日志类LogFactory private static final Log logger= LogFactory.getLog(SessionAttributesController.class); //该方法映射请求为http://localhost:8080/DataBindingTest/{formName} @RequestMapping(value="/{formName}") public String loginForm(@PathVariable String formName){ //动态跳转页面 return formName; } //该方法映射的请求为http://localhost:8080/DataBindingTest/login @RequestMapping(value="/login") public String login( @RequestParam("loginname") String loginname, @RequestParam("password") String password, Model model){ //创建User对象,装载用户信息 User user=new User(); user.setLoginname(loginname); user.setPassword(password); user.setUsername("admin"); //将user对象添加到Model当中 model.addAttribute("user",user); return "welcome"; } }
新建user类,该代码域RequestMappingTest的代码相同。
接下来创建一个登录页面loginForm.jsp,该页面代码和前面RequestMappingTest的代码相同,可参考配置
创建welcome.jsp,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>welcome</title> </head> <body> <!-- 页面可以访问Controller传递传递出来的模型User对象 --> 访问request作用域中的user对象 :${requestScope.user.username }<br> 访问session作用域中的user对象:${sessionScope.user.username }<br> </body> </html>
在浏览器输入如下url来测试应用:
http://localhost:8080/DataBindingTest/loginForm
会看到如下界面。
输入登录名"test",密码“123456”,单击“登录”按钮。请求将会被提交到SessionAttributesController类的login方法,该方法将会创建User对象来保存数据,并将其设置到Model当中。因为类上面使用了@SessionAttributes注解,故User同时也会被设置到HttpSession作用域当中。方法执行完跳转到如下所示界面。
可以看到,User对象被成功设置到了HttpSession作用域当中。
@SessionAttributes还有如下写法:
@SessionAttributes(types={User.class},value="user")
还可以设置多个对象到HttpSession当中:
@SessionAttributes(types={User.class,Dept.class},value={"user","dept"})
types属性用来指定放入HttpSession当中的对象类型。
6.@ModelAttribute注解
org.springframework.web.bind.annotation.ModelAttribute注解类型将请求参数绑定到Model对象。
@ModelAttribute注解只支持一个属性value,类型为String,表示绑定的属性名称。
@ModelAttribute注解的使用方式有很多种,下面为读者逐一介绍。
示例 :@ModelAttribute注解的使用
新建ModelAttributeTest项目,在项目下新建index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>welcome</title> </head> <body> <h3>测试@ModelAttribute的不同用法</h3> <a href="loginForm1">测试@ModelAttribute(value="")注解返回具体类的方法</a><br><br> <a href="loginForm2">测试@ModelAttribute注释void返回值的方法</a><br><br> <a href="loginForm3">测试@ModelAttribute注释返回具体类的方法</a><br><br> <a href="loginForm4">测试@ModelAttribute和@RequestMapping同时注释一个方法</a><br><br> <a href="loginForm5">测试@ModelAttribute注释一个方法的参数</a><br><br> </body> </html>
新建FormController:
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 { //该方法映射的请求为http://localhost:8080/ModelAttributeTest/{formName} @RequestMapping(value="/{formName}") public String loginForm(@PathVariable String formName){ //动态跳转页面 return formName; } }1.测试@ModelAttribute(value="")注释返回具体类的方法
新建loginForm1.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>loginForm</title> </head> <body> <h3>登录页面</h3> <br> <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:
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注释的value属性,来指定model属性的名称,model属性的值就是方法的返回值 @ModelAttribute("loginname") public String userModel1( @RequestParam("loginname") String loginname){ return loginname; } @RequestMapping(value="/login1") public String login1(){ return "result1"; } }
ModelAttributeController类中除了@RequestMapping映射的login1方法之外,还提供了一个userModel1方法,该方法上有一个@ModelAttribute注解,此外@ModelAttribute注解默认的value值为“loginname”,用来指定model属性的名称,而model属性的值就是userModel1方法的返回值。被@ModelAttribute注解的userModel1方法会先于login1调用,它把请求参数loginname的值赋给loginname变量,并设置了一个属性loginname到Model当中,而属性的值就是loginname变量的值。
新建result1.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>loginForm</title> </head> <body> 访问request作用范围域中的loginname对象:${requestScope.loginname }<br> </body> </html>
在跳转的reult1.jsp中可以访问到由@ModelAttribute设置的loginname的值。
此外,还需要在web.xml文件中配置Spring MVC的前端控制器DispatcherServlet.因为配置基本一致,故此处不在赘述,读者可自行配置。
同时,SpringMVC还需要springmvc-config.xml配置文件,该文件内容和ControllerTest项目中的springmvc-config.xml文件一致,读者可自行配置。
部署ModelAttributeTest这个Web应用,在浏览器中输入如下URL来测试应用:
http://localhost:8080/ModelAttributeTest/index.jsp
会看到如下页面,表示成功跳转index.jsp:
点击“测试@ModelAttribute(value="")注释返回具体类的方法”超链接发送请求,跳转到loginForm1.jsp,如图所示。
输入“test”,单击“登录”按钮发送请求,而后将先调用userModel1方法,在调用login1方法,并跳转到result1.jsp,如图所示
可以看到,在request作用域中访问到了Model的值。
2.测试@ModelAtribute注释void返回值的方法
新建loginForm2.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>loginForm</title> </head> <body> <h3>测试@ModelAttribute注释void返回值的方法</h3> <br> <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="text" id="password" name="password"></td> </tr> <tr> <td><input id="submit" type="submit" value="登录"></td> </tr> </table> </form> </body> </html>
新建ModelAttribute2Controller:
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 { //model属性名称和值由model.addAttribute()实现,前提是要在方法中加入一个Model类型的参数 @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类中除了@RequesytMapping映射的login2方法之外,还提供了一个userModel2方法,该方法上有一个@ModelAttribute注解。userModel2方法会先于llogin2调用,它把请求参数值赋给对应变量,model属性名称和值由model.addAttribute()方法实现,前提是要在方法中加入一个Model类型的参数。
新建result2.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>loginForm</title> </head> <body> 访问request作用范围域中的loginname对象:${requestScope.loginname }<br> 访问request作用范围域中的password对象:${requestScope.password }<br> </body> </html>
在跳转的result2.jsp中可以访问到由@ModelAttribute设置的loginname和password的值。
在浏览器中输入如下URL来测试应用:http://localhost:8080/ModelAttributeTest/index.jsp,将会跳转到如下页面,点击“测试@ModelAttribute注释void返回值的方法”超链接发送请求,将会跳转到loginForm2.jsp页面,如图所示:
输入登录名“test”,密码“123456”,单击"登录"按钮发送请求,而后将先调用userModel2方法,在调用login2方法,并跳转到result2.jsp页面,如图所示:
可以看到,在request作用域中访问到了Model的值。
3.测试@ModelAttribute作用域中访问到了Model的值。
新建loginForm3.jsp:
loginForm3.jsp和loginForm2.jsp页面内容一致,读者可自行参考,此处不再赘述。
新建ModelAttribute3Controller.java:
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 { //静态List<User>集合,此处代替数据库用来保存注册的用户信息 private static List<User> userList; //UserController类的构造器,初始化List<User>集合 public ModelAttribute3Controller(){ super(); userList = new ArrayList<User>(); User user1 = new User("test","123456","测试用户"); User user2 = new User("admin", "123456", "管理员"); //存储User用户,用于模拟数据库数据 userList.add(user1); userList.add(user2); } //根据登录名和密码查询用户,用户存在返回包含用户信息的User对象,不存在返回null public User find(String loginname,String password){ for(User user: userList) { if(user.getLoginname().equals(loginname) && user.getPassword().equals(password)){ return user; } } return null; } //model属性的名称没有被指定,它由返回类型隐含表示,如这个方法返回User类型,那么这个model //属性的名称是User. @ModelAttribute public User userModel3( @RequestParam("loginname") String loginname, @RequestParam("password") String password){ return find(loginname, password); } @RequestMapping(value="/login3") public String login3(){ return "result3"; } }
ModelAttribute3Conroller类中除了@RequestMapping映射的login3方法之外,还提供了一个userModel3方法,该方法上有一个@ModelAttribute注解。userModel3方法会先于login3方法调用,这里model属性的名称没有被指定。它由@ModelAttribute注解的userModel3方法的返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称就是user.此处find(loginname,password)方法是模拟数据库根据登录名和密码查询用户功能实现。
编写result3.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>loginForm</title> </head> <body> 访问request作用范围域中的user对象:${requestScope.user.username }<br> </body> </html>
在跳转的result3.jsp中可以访问到由@ModelAttribute设置的loginname和password的值。
在浏览器中输入如下URL来测试应用:http://localhost:8080/ModelAttributeTest/index.jsp,跳转到如图3.8所示页面,点击“测试@ModelAttribute注释返回具体类的方法”超链接发送请求,将跳转到loginForm3.jsp页面,如图3.11所示,输入登录名“test”密码“123456”,单击“登录”按钮发送请求,而后将先调用userModel3方法,在调用login3方法,并跳转到result3.jsp页面,如图3.13所示。
4.测试@ModelAttribute和@RequestMapping同时注释一个方法
新建loginForm4.jsp
loginForm4.jsp和loginForm2.jsp页面内容一致,读着
新建ModelAttribute4Controller
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 { //此时login4方法的返回值并不是一个视图名称,而是model属性的值,视图名称是@RequestMapping //的value值"/login4". //Model的属性名称由@ModelAttribute(value="")指定,相当于request中封装了 //username(key)=admin(value) @RequestMapping(value="/login4") @ModelAttribute(value="username") public String login4(){ return "admin"; } }
在ModelAttribute4Controller中,@ModelAttribte和 @RequetsMapping同时注释一个方法,此时login4方法的返回值并不是一个视图名称,而是model属性的值,视图名称是@RequestMapping的value值"/login4".Model的属性名称由@ModelAttribute的value值指定,这相当于在request中封装了username(key)=admin(value).
注意,此处login4方法跳转的结果是“login4”。
新建login4.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>loginForm</title> </head> <body> 访问request作用范围域中的user对象:${requestScope.username }<br> </body> </html>在浏览器中输入如下URL来测试应用:http://localhost:8080/ModelAttributeTest/index.jsp,跳转到如下页面,点击"测试@ModelAttribute和@RequestMapping同时注释一个方法"超链接发送请求,而后跳转到loginForm4.jsp页面,如下所示。输入登录名“test”,密码“123456”,单击“登录”按钮发送请求,将调用login4方法,跳转到login4.jsp页面,如下所示。
可以看到,在request作用域中访问到了username的值,也就是login4方法的返回值“admin”。
5.测试@ModelAttribute注释一个方法的参数
新建loginForm5.jsp和loginForm2.jsp页面内容一致,此处不在赘述。
新建ModelAttribute5Controller:
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; import org.springframework.web.bind.annotation.RequestParam; @Controller public class ModelAttribute5Controller { //model属性名称就是value值,即"user", model属性对象就是方法的返回值 @ModelAttribute("user") public User userModel5( @RequestParam("loginname") String loginname, @RequestParam("password") String password){ User user = new User(); user.setLoginname(loginname); user.setPassword(password); return user; } //@ModelAttribute("user") User user 注释方法参数,参数user的值就是userModel5() //方法中的model属性 @RequestMapping(value="/login5") public String login5(@ModelAttribute("user") User user){ user.setUsername("管理员"); return "result5"; } }
ModelAttribute5Controller类中除了@RequestMapping映射的login5方法之外,还提供了一个userModel5方法,该方法上有一个@ModelAttribute("user")注解。userModel5方法会先于login5调用,这里model属性名称就是value值,即“user”, model属性对象就是userModel5方法的返回值User。
login5方法的参数User使用了@ModelAttribute("user")注解,表示参数user的值就是userModel5()方法中的model属性。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>loginForm</title> </head> <body> 访问request作用范围域中的user对象:${requestScope.user.username }<br> </body> </html>
在浏览器中输入如下URL来测试应用:http://localhost:8080/ModelAttributeTest/index.jsp,跳转到如图所示的页面,点击“测试@ModelAttribute注释一个方法的参数”超链接发送请求,跳转到loginForm5.jsp页面,输入登录名“test”,密码“123456”,单击“登录”按钮发送请求,而后将调用login5方法,跳转到result5.jsp页面。如下所示
可以看到在request作用域中访问到了User对象。