Spring MVC是一款非常优秀的前端开发框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性。Spring MVC框架提供了构建 Web 应用程序的全功能 MVC 模块,而Web应用通常会引入Session,用来在服务端和客户端之间保存一系列动作/消息的状态。本文主要就Spring MVC中Session用法展开讨论。
Web应用中用到Session的例子多如牛毛,比如网上购物维护 user 登录信息直到 user 退出。在 user 登录后,Session 周期里有很多 action 都需要从 Session 中得到 user,再验证身份权限,或者进行其他的操作。这其中就会涉及到程序去访问 Session属性的问题。在java中,Servlet 规范提供了 HttpSession对象来满足这种需求。开发人员可以从 HttpServletRquest对象得到 HttpSession,再从HttpSession中得到状态信息。
关于Spring中Session用法,这里甚至建议直接使用HttpSession。但这种方法显然违背了Spring “technology agnostic”(这个名词我理解意思就是无论你是在什么具体的应用中使用类似的控制逻辑,Servlet、一个本地JVM程序或者其他,你的Controller都可以得到复用)的初衷。
Spring MVC中使用Session的几个要点:
1. Spring框架会在调用完Controller之后、渲染View之前检查Model的信息,并把@SessionAttributes()注释标明的属性加入Session中
2. @ModelAttribute在声明Controller的参数的时候,可以用来表明此参数引用某个存在在Model中的对象,如果这个对象已经存在于Model中的话(Model可以在调用Controller之前就已经保存有数据,这应该不仅仅因为HandlerInterceptor或者@ModelAttribute标记的方法已经显式的将一些对象加入到了Model对象中,也因为Spring会默认将一些对象加入到Model中,这一点很重要)。
3. 如果Session中已经存在某个对象,那么可以直接使用ModelAttribute声明Controller的参数,在Controller中可以直接使用它。
通过上面的三点我们可以得出结论:
Spring会在调用Controller之前将Session中的对象填入Model中
下面是代码是实例:
@Controller
@RequestMapping("/user")
@SessionAttributes("userId")
public class UserController {
@RequestMapping(value="/login", method=GET)
public String login (
int id, Model model, HttpServletRequest request, HttpSession session) {
model.addAttribute("userId", id);
System.out.println("");
System.out.println("");
System.out.println("inside login");
System.out.println("");
System.out.println("--- Model data ---");
Map modelMap = model.asMap();
for (Object modelKey : modelMap.keySet()) {
Object modelValue = modelMap.get(modelKey);
System.out.println(modelKey + " -- " + modelValue);
}
System.out.println("");
System.out.println("*** Session data ***");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String s = e.nextElement();
System.out.println(s + " == " + session.getAttribute(s));
}
return "/test";
}
@RequestMapping(value="/check", method=GET)
public String check (
Model model, HttpServletRequest request, HttpSession session) {
System.out.println("");
System.out.println("");
System.out.println("inside check");
System.out.println("");
System.out.println("--- Model data ---");
Map modelMap = model.asMap();
for (Object modelKey : modelMap.keySet()) {
Object modelValue = modelMap.get(modelKey);
System.out.println(modelKey + " -- " + modelValue);
}
System.out.println("");
System.out.println("*** Session data ***");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String s = e.nextElement();
System.out.println(s + " == " + session.getAttribute(s));
}
return "/test";
}
}
而test.jsp的作用就是把Session中的对象打印出来。调用的顺序是,在首先保证Session为空的情况下,先后输入以下链接:
http://localhost:8080/XX/user/check
http://localhost:8080/XX/user/login?id=1
http://localhost:8080/XX/user/check
页面的显示结果分别为:
而Tomcat的输出结果为:
inside check
--- Model data ---
*** Session data ***
inside login
--- Model data ---
userId -- 1
*** Session data ***
inside check
--- Model data ---
userId -- 1
*** Session data ***
userId == 1
从输出结果中我们可以看出,首先Session中并没有userId属性,在某个Controller加入了它之后,随后的Controller中的Model会自动加入已经存在于Session的对象。虽然确实有很多很多资料提到了@SessionAttributes并不是使用session的正确方法,但是如实验所得,使用它使得最终属性都加入到了HttpSession对象中,夫复何求?那么,在Spring MVC中使用Session的一个相对比较“technology agnostic”的方法就是:
1.使用@SessionAttributes提示框架哪些属性需要存在Session中
2 .在某些Controller中将这些属性加入到Model中
3 .在另外一些Controler中直接使用这些属性
4 .在其他Controller中判断Model中是否存在相应属性,以确定Session中是否已经注册了这个属性
通过本文的理论和实例论证,我们对Spring MVC中Session用法有了新的认识和提升。这只是Spring MVC中的一个很小的知识盲点,在本站的Spring MVC视频教程中还有大量的知识能够全方位让你掌握Spring MVC!
QCode09-04 14:38
Code大师09-04 14:50
不写代码你养我啊08-23 11:14
不写代码你养我啊09-17 18:02
要学习了06-18 18:13