网上的帖子弗成偻指算,中文的快速上手,英文的深入浅出。这样看来,Spring的学习切实其实是一个轻松愉快的过程。
但是!
!
关于Spring中session的利用,大部分资料都讳莫如深。大概这个问题太过随意马虎推断出?大部分资料都没有包括我下面所将要陈述的内容。关于Spring中session的精确利用方法,这里乃至建议直策应用HttpSession。但这种方法显然违背了Spring “technology agnostic” (这个名词我理解意思便是无论你是在什么详细的运用中利用类似的掌握逻辑,servlet、一个本地JVM程序或者其他,你的Controller都可以得到复用)的初衷。
于是我开始从弘大的网络资源和书本中搜索关于Session的精确用法及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中可以直策应用它。
个中1很明确,我提到的那篇文章紧张就在解释这一点。而从2和3我们也容许以大胆地推出一个结论:
Spring会在调用Controller之前将session中的工具填入Model中
由于想从2得到3,这个结论就显得比较自然。那么事实上是不是如此呢?可以做一个小实验。仿效我所引用的那篇文章,我写了如下代码:
@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<String> 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<String> 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
页面的显示结果分别为:
1
2
3
而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工具中,夫复何求?(这里大概须要更多的谈论,我倒希望能有什么更值得信服的说法让我乖乖用回HttpSession)。那么,在Spring中利用Session的一个相比拟较“technology agnostic”的方法便是:
1 利用@SessionAttributes提示框架哪些属性须要存在Session中
2 在某些Controller中将这些属性加入到Model中
3 在其余一些Controler中直策应用这些属性
4 在其他Controller中止定Model中是否存在相应属性,以确定Session中是否已经注册了这个属性
Done,初学而已,随便谈谈,欢迎谈论。