如请求的URL为“控制器URL/users/123/topics/456”,则自动将URL中模板变量{userId}和{topicId}绑定到通过@PathVariable注解的同名参数上,即入参后userId=123、topicId=456
n@CookieValue
功能:用于将请求的Cookie数据映射到功能处理方法的参数上
例子1:
public String test(@CookieValue(value="JSESSIONID", defaultValue="") String sessionId)
如上配置将自动将JSESSIONID值入参到sessionId参数上,defaultValue表示Cookie中没有JSESSIONID时默认为空。
例子2:
public String test2(@CookieValue(value="JSESSIONID", defaultValue="") Cookie sessionId)
传入参数类型也可以是javax.servlet.http.Cookie类型。
@CookieValue也拥有和@RequestParam相同的三个参数,含义一样。
n@RequestHeader
功能:用于将请求的头信息区数据映射到功能处理方法的参数上
例子:
@RequestMapping(value="/header")
public String test(
@RequestHeader("User-Agent") String userAgent,
@RequestHeader(value="Accept") String[] accepts)
如上配置将自动将请求头“User-Agent”值入参到userAgent参数上,并将“Accept”请求头值入参到accepts参数上。
@RequestHeader也拥有和@RequestParam相同的三个参数,含义一样。
n@ModelAttribute
@ModelAttribute一般具有如下三个作用:
1:绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用;
2:暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用;
3:暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。
n
一、绑定请求参数到命令对象
如实现用户登录,需要捕获用户s登录的请求参数(用户名、密码)并封装为用户对象,此时可以使用@ModelAttribute绑定多个请求参数到我们的命令对象。
例子:public String test1(@ModelAttribute("user") UserModel user)
说明:1:和前面命令/表单对象一样,只是此处多了一个注解@ModelAttribute(“user”),它的作用是将该绑定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用${user.username}来获取绑定的命令对象的属性。
2:绑定请求参数到命令对象支持对象图导航式的绑定,如请求参数包含“?username=zhang&password=123&workInfo.city=bj”自动绑定到user中的workInfo属性的city属性中。
3:@RequestMapping(value="/model2/{username}")
public String test2(@ModelAttribute("model") UserModel model) {
URI模板变量也能自动绑定到命令对象中,当你请求的URL中包含“&username=zhang”会自动绑定到命令对象上。
当URI模板变量和请求参数同名时, 请求参数 具有高优先权。
n
二、暴露表单引用对象为模型数据
例子1:
@ModelAttribute("cityList")
public List cityList() {
return Arrays.
asList("北京", "山东");
}
如上代码会在执行功能处理方法之前执行,并将其自动添加到模型对象中,在功能处理方法中可以使用Model入参,则可以在处理方法中使用citylist了,如:
public ModelAndView handleRequest(Model m) {
List list = (List)m.asMap().get("cityList");
for(String s : list){
System.out.println("s==="+s);
}
......
}
例子2:
@ModelAttribute("user") //①
public UserModel getUser(@RequestParam(value=“username", defaultValue="") String username) { //TODO 去数据库根据用户名查找用户对象 }
如你要修改用户资料时一般需要根据用户的编号/用户名查找用户来进行编辑,此时可以通过如上代码查找要编辑的用户。也可以进行一些默认值的处理。
@RequestMapping(value="/model1") //②
public String test1(@ModelAttribute("user") UserModel user, Model model)
说明:
此处我们看到①和②有同名的命令对象,那Spring Web MVC内部如何处理的呢:
1、首先执行@ModelAttribute注解的方法,准备视图展示时所需要的模型数据;@ModelAttribute注解方法形式参数规则和@RequestMapping规则一样,如可以有@RequestParam等;
2、执行@RequestMapping注解方法,进行模型绑定时首先查找模型数据中是否含有同名对象,如果有直接使用,如果没有通过反射创建一个,因此②处的user将使用①处返回的命令对象。即②处的user等于①处的user。
n
三、暴露@RequestMapping方法返回值为模型数据
例子:
public @ModelAttribute("user2") UserModel test3(@ModelAttribute("user2") UserModel user)
大家可以看到返回值类型是命令对象类型,而且通过@ModelAttribute(“user2”)注解,此时会暴露返回值到模型数据(名字为user2)中供视图展示使用。
可能有同学会注意到,此时@RequestMapping注解方法的入参user暴露到模型数据中的名字也是user2,那么到底user2代表哪一个呢?
规则是:@ModelAttribute注解的返回值会覆盖@RequestMapping注解方法中的@ModelAttribute注解的同名命令对象
n
四、匿名绑定命令参数
例子1:
public String test4(@ModelAttribute UserModel user, Model model)
或 public String test5(UserModel user, Model model)
说明:
此时我们没有为命令对象提供暴露到模型数据中的名字,此时的名字是什么呢?Spring Web MVC自动将简单类名(首字母小写)作为名字暴露,如“cn.javass.springmvc.model.UserModel”暴露的名字为“userModel”。
例子2:
public @ModelAttribute List test6()
或 public @ModelAttribute List test7()
说明:
对于集合类型(Collection接口的实现者们,包括数组),生成的模型对象属性名为“简单类名(首字母小写)”+“List”,如List生成的模型对象属性名为“stringList”,List生成的模型对象属性名为“userModelList”。
其他情况一律都是使用简单类名(首字母小写)作为模型对象属性名,如Map类型的模型对象属性名为“map”。
n
@SessionAttributes :绑定命令对象到session
//1、在控制器类头上添加@SessionAttributes注解
@SessionAttributes(value = {"user"}) //①
public class SessionAttributeController
//2、@ModelAttribute注解的方法进行表单引用对象的创建
@ModelAttribute("user") //②
public UserModel initUser()
//3、@RequestMapping注解方法的@ModelAttribute注解的参数进行命令对象的绑定
@RequestMapping("/session1") //③
public String session1(@ModelAttribute("user") UserModel user)
//4、通过SessionStatus的setComplete()方法清除@SessionAttributes指定的会话数据
@RequestMapping("/session2") //③
public String session(@ModelAttribute("user") UserModel user, SessionStatus status) {
if(true) { //④
status.setComplete(); }
return "success";
}