方法形参如何绑定 URL参数(一)
1.处理方法入参,如何绑定URL参数
??? (1)按参数名匹配绑定
??? ??? 例如:
??? ??? listBoardTopic(int topicId):和 topicId URL 请求参数绑定;?
??? ??? listBoardTopic(int topicId,String boardName):分别和 topicId、boardName URL 请求参数绑定;?
??? ??? 请注意,如果入参是基本数据类型(如 int、long、float 等),URL 请求参数中一定要有对应的参数,否则将抛出 TypeMismatchException 异常,提示无法将 null 转换为基本数据类型。
??? (2)使用 JavaBean 作为请求处理方法的入参
??? ??? 例如:
??? ??? public String listBoardTopic(int topicId,User user)
??? ??? 这时,如果我们使用以下的 URL 请求:http://localhost/bbtForum.do?method=listBoardTopic&topicId=1&userId=10&userName=tom
??? ??? topicId URL 参数将绑定到 topicId 入参上,而 userId 和 userName URL 参数将绑定到 user 对象的 userId 和 userName 属性中。
??? ??? 和 URL 请求中不允许没有 topicId 参数不同,虽然 User 的 userId 属性的类型是基本数据类型,但如果 URL 中不存在 userId 参数,Spring 也不会报错,此时 user.userId 值为 0。
??? ??? 如果 User 对象拥有一个 dept.deptId 的级联属性,那么它将和 dept.deptId URL 参数绑定
??? (3)通过注解指定绑定的 URL 参数(@RequestParam)
??? ??? 例如:
??? ??? public String listBoardTopic(@RequestParam("id") int topicId, User user)
??? ??? 这里@RequestParam注解可以用来提取url中名为“id”的属性,并将其注入到topicId参数中。
??? ??? @RequestParam支持类型转换,还有必需和可选参数。类型转换目前支持所有的基本Java类型,你可通过定制的PropertyEditors 来扩展它的范围。下面是一些例子,其中包括了必需和可选参数:
??? ??? @RequestParam(value="number", required=false) String number
??? ??? @RequestParam("id") Long id
??? ??? @RequestParam("balance") double balance
??? ???
2.将数据模型保存到request范围
??? (1)绑定模型对象中某个属性—ModelMap
??? ??? 例如:
??? ??? 我们可以在请求处理方法中声明一个 ModelMap 类型的入参,Spring 会将本次请求模型对象引用通过该入参传递进来,这样就可以在请求处理方法内部访问模型对象了。来看下面的例子:
?
??? ??? 对于当次请求所对应的模型对象来说,其所有属性都将存放到 request 的属性列表中。
??? ??? 象上面的例子,ModelMap 中的 currUser 属性将放到 request 的属性列表中,所以可以在 JSP 视图页面中通过 request.getAttribute("currUser") 或者通过 ${currUser} EL 表达式访问模型对象中的 user 对象。
??? ??? 从这个角度上看, ModelMap 相当于是一个向 request 属性列表中添加对象的一条管道,借由 ModelMap 对象的支持,我们可以在一个不依赖 Servlet API 的 Controller 中向 request 中添加属性。
3.数据模型在session范围的保存和获取
??? (1)使模型对象的特定属性具有 Session 范围的作用域(保存)
??? ??? 在默认情况下,ModelMap 中的属性作用域是 request 级别,也就是说,当本次请求结束后,ModelMap 中的属性将销毁。
??? ??? 如果希望在多个请求中共享 ModelMap 中的属性,必须将其属性转存到 session 中,这样 ModelMap 的属性才可以被跨请求访问。
??? ??? Spring 允许我们有选择地指定 ModelMap 中的哪些属性需要转存到 session 中,以便下一个请求属对应的 ModelMap 的属性列表中还能访问到这些属性。
??? ??? 这一功能是通过类定义处标注 @SessionAttributes 注解来实现的。请看下面的代码:?
??? ???
??? ??? 我们在 ② 处添加了一个 ModelMap 属性,其属性名为 currUser,而 ① 处通过 @SessionAttributes 注解将 ModelMap 中名为 currUser 的属性放置到 Session 中,所以我们不但可以在 listBoardTopic() 请求所对应的 JSP 视图页面中通过 request.getAttribute(“currUser”) 和 session.getAttribute(“currUser”) 获取 user 对象,还可以在下一个请求所对应的 JSP 视图页面中通过 session.getAttribute(“currUser”) 或 ModelMap#get(“currUser”) 访问到这个属性。
??? ??? 1)这里我们仅将一个 ModelMap 的属性放入 Session 中,其实 @SessionAttributes 允许指定多个属性:
??? ??? ???? 你可以通过字符串数组的方式指定多个属性,如 @SessionAttributes({“attr1”,”attr2”})。
??? ??? 2)此外,@SessionAttributes 还可以通过属性类型指定要 session 化的 ModelMap 属性:
??? ??? ???? 如 @SessionAttributes(types = User.class),
??? ??? ?? 当然也可以指定多个类,如 @SessionAttributes(types = {User.class,Dept.class}),
??? ??? 3)还可以联合使用属性名和属性类型指定:
??? ??? ??? @SessionAttributes(types = {User.class,Dept.class},value={“attr1”,”attr2”})。
??? ??? ???
??? (2)使模型对象的特定属性具有 Session 范围的作用域(获取)
??? ??? 还请看上面这段代码的第③部分。
??? ??? 上面讲述了如何往ModelMap中放置属性以及如何使ModelMap中的属性拥有Session域的作用范围。除了在JSP视图页面中通过传统的方法访问ModelMap中的属性外,读者朋友可能会问:是否可以将ModelMap中的属性绑定到请求处理方法的入参中呢?答案是肯定的。Spring为此提供了一个@ModelAttribute的注解,下面是使用@ModelAttribute注解的例子
??? ??? 在 ② 处,我们向 ModelMap 中添加一个名为 currUser 的属性,
??? ??? 而 ① 外的注解使这个 currUser 属性拥有了 session 级的作用域。
??? ??? 所以,我们可以在 ③ 处通过 @ModelAttribute 注解将 ModelMap 中的 currUser 属性绑定以请求处理方法的 user 入参中。
??? ??? 所以当我们先调用以下 URL 请求:
??? ??? http://localhost/bbtForum.do?method=listBoardTopic&id=1&userName=tom&dept.deptId=12 以执行listBoardTopic()请求处理方法,
??? ??? 然后再访问以下URL: http://localhost/sample/bbtForum.do?method=listAllBoard
??? ??? 你将可以看到 listAllBoard() 的 user 入参已经成功绑定到 listBoardTopic() 中注册的 session 级的 currUser 属性上了