SpringMVC+ mybatis 企业级开发实战连载(四)

参数绑定注解

       

        1.  @RequestParam 注解

                org.springframework.web.bind.annotation.RequestParam  注解类型用于将指定的请求参数赋值给方法中的形参。

             使用@RequestParam注解可指定如下表所示的属性:

             

@RequestMapping注解支持的属性
属性 类型 是否必要 说明
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注解可指定如下的属性。

@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注解可指定如下所示的属性。

@CokieValue注解支持的属性
属性 类型 是否必要 说明
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注解可指定如下表所示的属性。

@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对象。



猜你喜欢

转载自blog.csdn.net/u014645946/article/details/80406490