2. @Controller、@RequestMapping注解应用
2.5 Model 和ModelAndView
2.5.3 ModelAndView
既包含模型数据信息又包含视图信息
//将User对象添加到ModelAndView中
modelAndView.addObject(String attributeName, Object attributeValues);
//设置返回视图名称
modelAndView.setViewName(String viewName);
@Controller
public class UserModelAndViewTestController {
//@ModelAttribute修饰的方法会优先login调用
@ModelAttribute
public void userModel(String loginName,String password
,ModelAndView modelAndView) {
//创建User对象存储jsp页面传入的参数
User user = new User();
user.setLoginName(loginName);
user.setPassword(password);
//将User对象添加到ModelAndView中
modelAndView.addObject("user", user);
}
@RequestMapping(value="/login_modelAndView")
public ModelAndView login(ModelAndView modelAndView) {
//从ModelAndView的Model中取出之前存入的名为user的对象
User user = (User) modelAndView.getModel().get("user");
//设置user对象的userName属性
user.setUserName("测试输出模型ModelAndView");
//设置返回视图名称
modelAndView.setViewName("requestMappingTest/loginResult");
return modelAndView;
}
}
3. 参数绑定注解
常用类型根据处理的request的不同内容部分可以分为四类:
- 处理
request body
部分的注解:@RequestParam、@RequestBody。 - 处理
request uri
部分的注解:@pathVariable。 - 处理
request header
部分的注解:@RequestHeader、@CookieValue。 - 处理
attribute
类型的注解:@SessionAttributes、@ModelAttribute。
3.1 @RequestParam
- @RequestParam支持的属性
属性 | 类型 | 说明 |
---|---|---|
name | String | 指定请求头绑定的名称 |
value | String | name属性的别名 |
required | boolean | 指示参数是否必须绑定 |
defaultValue | String | 如果没有传递参数而使用的默认值 |
@Controller
@RequestMapping(value="/requestParamTest")//所有方法都映射为相对于类级别的请求
public class RequestParamTestController {
//静态集合,代替数据库用来保存注册的用户信息
private static List<User> userList;
//初始化集合
public RequestParamTestController() {
super();
userList = new ArrayList<User>();
}
//方法映射请求路径:http://localhost:8080/maven-springMVC/requestParamTest/register
//本方法支持GET请求
@RequestMapping(value="/register",method=RequestMethod.GET)
public String registerForm() {
//跳转到注册页面
return "paramTest/registerForm";
}
//方法映射请求路径:http://localhost:8080/maven-springMVC/requestParamTest/register
//本方法支持POST请求
@RequestMapping(value="/register",method=RequestMethod.POST)
public String register(@RequestParam("loginName") String loginName,//将请求参数loginName的值赋值给loginName
@RequestParam("password") String password,
@RequestParam("userName") String userName){
User user = new User();
user.setLoginName(loginName);
user.setPassword(password);
user.setUserName(userName);
userList.add(user);
//跳转到登录页面
return "paramTest/loginForm";
}
//方法映射请求路径:http://localhost:8080/maven-springMVC/requestParamTest/login
@RequestMapping(value="/login")
public String login(@RequestParam("loginName") String loginName,//将请求参数loginName的值赋值给loginName
@RequestParam("password") String password,Model model) {
//从集合中查找用户是否存在,用来模拟数据库验证
for(User user :userList) {
if(user.getLoginName().equals(loginName)&&
user.getPassword().equals(password)) {
model.addAttribute("user", user);
return "paramTest/welcome";
}
}
return "paramTest/loginForm";
}
3.2 @pathVariable
@pathVariable只支持一个属性value,类型为String,表示绑定的名称,省略则默认绑定同名参数
@RequestMapping(value="/pathVariableTest/{userId}")
public String pathVariableTest(@RequestParam("userId") String userId)
//请求url:http://localhost:8080/maven-springMVC/pathVariableTest/user01
//userId=user01
3.3 @RequestHeader
用于将请求头信息区书记映射到功能处理方法的参数上。
- @RequestHeader注解支持的属性
属性 | 类型 | 说明 |
---|---|---|
name | String | 指定请求头绑定的名称 |
value | String | name属性的别名 |
required | boolean | 指示参数是否必须绑定 |
defaultValue | String | 如果没有传递参数而使用的默认值 |
@RequestMapping(value="/requestHeaderTest")
public String requestHeaderTest(@RequestHeader("User-Agent") String userAgent,
@RequestHeader(value="Accept") String[] accepts)
//以上配置自动将请求头"User-Agent"的值赋值到userAgent变量上,将"Accept"请求头的值赋到accepts上
3.4 @CookieValue
- @CookieValue注解支持的属性
属性 | 类型 | 说明 |
---|---|---|
name | String | 指定请求头绑定的名称 |
value | String | name属性的别名 |
required | boolean | 指示参数是否必须绑定 |
defaultValue | String | 如果没有传递参数而使用的默认值 |
@RequestMapping(value="/cookieValueTest")
public String cookieValueTest(
@CookieValue(value="JSESSIONID",defaultValue="") String sessionId)
//以上配置自动将JSESSIONID的值赋值到sessionId变量上,defaultValue表示Cookie中没有JSESSIONID时默认为空
3.5 @SessionAttributes
@SessionAttributes注解允许指定Model中的哪些对象属性需要转存到HttpSession对象中
@SessionAttributes注解只能声明在类上,不能声明在方法上
@SessionAttributes注解支持的属性
属性 | 类型 | 说明 |
---|---|---|
names | String[] | Model中的属性名称,即存到HttpSession当中的属性名称 |
value | String | names属性的别名 |
types | Class<?>[] | 指示参数是否必须绑定 |
@Controller
@RequestMapping(value="/sessionAttributesTest")
@SessionAttributes("user")//将Model属性中user的属性放入HttpSession对象当中
public class SessionAttributesTest {
//方法映射请求路径:http://localhost:8080/maven-springMVC/sessionAttributesTest/loginForm
@RequestMapping(value="/{formName}")
public String registerForm(@PathVariable String formName) {
//跳转页面
return "paramTest/"+formName;
}
//方法映射请求路径:http://localhost:8080/maven-springMVC/sessionAttributesTest/login
@RequestMapping(value="/login")
public String login(@RequestParam("loginName") String loginName,
@RequestParam("password") String password,Model model) {
User user = new User();
user.setLoginName(loginName);
user.setPassword(password);
user.setUserName("测试sessionAttributesTest");
model.addAttribute(user);
return "paramTest/welcome";
}
}
- 其他写法
@SessionAttributes(types= {User.class},value="user")
@SessionAttributes(types= {User.class,Dept.class},value={"user","dept"})
3.5 @ModelAttribute
@ModelAttribute将参数绑定到Model对象
只支持一个属性value,类型为String,表示绑定的名称。
被@ModelAttribute注释的的方法会在Controller每个方法执行之前被执行,因此,一个Controller映射多个URL时,要谨慎。
3.5.1 @ModelAttribute(value="")注释返回具体类的方法
- controller
@Controller
@RequestMapping(value="/modelAttr")
public class ModelAttribute1Controller {
//使用@ModelAttribute注释的value属性,来指定model属性的名称,model属性的值就是方法的返回值
@ModelAttribute("loginName")
public String UserModel1(@RequestParam("loginName") String loginName) {
return loginName;
}
//该方法映射的请求为:http://localhost:8080/maven-springMVC/modelAttr/login1
@RequestMapping(value="/login1")
public String login1() {
return "modelAttr/loginResult";
}
}
- loginForm
<h1>测试@ModelAttribute(value="")注释返回具体类的方法</h1>
<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 type="submit" id="submit" value="登录"></td>
</tr>
</table>
</form>
- loginResult
${requestScope.loginName}
3.5.2 ModelAttribute注释void返回值的方法
- controller
@Controller
@RequestMapping(value="/modelAttr")
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);
}
//该方法映射的请求为:http://localhost:8080/maven-springMVC/modelAttr/login2
@RequestMapping(value="/login2")
public String login2() {
return "modelAttr/loginResult";
}
}
- loginForm
<h1>测试@ModelAttribute注释void返回值的方法</h1>
<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 type="submit" id="submit" value="登录"></td>
</tr>
</table>
</form>
- loginResult
${requestScope.loginName}
${requestScope.password}
3.5.3 @ModelAttribute注释返回具体类的方法
- controller
@Controller
@RequestMapping(value="/modelAttr")
public class ModelAttribute3Controller {
//静态集合,代替数据库用来保存注册的用户信息
private static List<User> userList;
//初始化List<User>集合
public ModelAttribute3Controller() {
super();
userList = new ArrayList<User>();
User user1 = new User("test", "123456", "测试用户");
User user2 = new User("admin", "789012", "管理员");
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;
}
//使用Model属性名的名称没有被指定,它由UserModel3返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称就是User
@ModelAttribute
public User UserModel3(@RequestParam("loginName") String loginName,@RequestParam("password") String password) {
return this.find(loginName, password);
}
//该方法映射的请求为:http://localhost:8080/maven-springMVC/modelAttr/login3
@RequestMapping(value="/login3")
public String login3() {
return "modelAttr/loginResult";
}
}
- loginForm
<h1>测试@ModelAttribute注释具体类的方法</h1>
<br>
<form action="login3" 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 type="submit" id="submit" value="登录"></td>
</tr>
</table>
</form>
- loginResult
${requestScope.user.userName}
${requestScope.user.loginName}
${requestScope.user.password}
3.5.4 @ModelAttribute和@RequestMapping同时注释一个方法
- controller
@Controller
@RequestMapping(value="/modelAttr")
public class ModelAttribute4Controller {
//该方法映射的请求为:http://localhost:8080/maven-springMVC/modelAttr/login4
//此时login4方法返回的值并不是一个视图名称,而是model属性的值,视图名称是@RequestMapping的value值"/login4"
//使用Model属性名的名称由@ModelAttribute(value="userName")指定,相当于在request中封装了userName(key)= admin (value)
@RequestMapping(value="/login4")
@ModelAttribute(value="userName")
public String login4() {
return "modelAttr/loginResult";
}
}
- loginForm
<h1>测试@ModelAttribute和@RequestMapping同时注释一个方法</h1>
<br>
<form action="login4" 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 type="submit" id="submit" value="登录"></td>
</tr>
</table>
</form>
- loginResult==>login4.jsp
${requestScope.user.userName}
3.5.5 @ModelAttribute注释一个方法的参数
- controller
@Controller
@RequestMapping(value="/modelAttr")
public class ModelAttribute5Controller {
//使用Model属性名就是value的值,即"user",model属性对象就是方法的返回值
@ModelAttribute("user")
public User UserModel2(@RequestParam("loginName") String loginName,@RequestParam("password") String password) {
User user = new User();
user.setLoginName(loginName);
user.setPassword(password);
return user;
}
//该方法映射的请求为:http://localhost:8080/maven-springMVC/modelAttr/login5
//@ModelAttribute("user") User user 注释方法参数,参数user的值就是userModel5()方法中的model值
@RequestMapping(value="/login5")
public String login5( @ModelAttribute("user") User user) {
user.setUserName("测试@ModelAttribute注释一个方法的参数");
return "modelAttr/loginResult";
}
}
- loginForm
<h1>测试@ModelAttribute注释一个方法的参数</h1>
<br>
<form action="login5" 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 type="submit" id="submit" value="登录"></td>
</tr>
</table>
</form>
- loginResult
${requestScope.user.userName}
${requestScope.user.loginName}
${requestScope.user.password}