【转】Spring MVC中Session的正确用法之我见
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性、可复用性与易集成性。优良的设计模式遍及各处,使得其框架虽然学习曲线陡峭,但一旦掌握则欲罢不能。初学者并不需要过多了解框架的实现原理,随便搜一下如何使用“基于注解的controller”就能很快上手,而一些书籍诸如“spring in action”也给上手提供了非常优良的选择。
网上的帖子多如牛毛,中文的快速上手,英文的深入浅出。这样看来,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,初学而已,随便谈谈,欢迎讨论。
【转】Spring MVC中Session的正确用法之我见的更多相关文章
- Spring MVC中Session的正确用法之我见
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
- Spring MVC中Session的正确用法<转>
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
- Spring MVC中各个filter的用法
转载:http://blog.csdn.net/qyp1314/article/details/42023725 Spring MVC中各个filter的用法 2014-12-19 09:08 105 ...
- JAVA Spring MVC中各个filter的用法
spring mvc的org.springframework.web.filter包下的Java文件如下: 类的结构如下: AbstractRequestLoggingFilter及其子类 Abstr ...
- Spring mvc中@RequestMapping 6个基本用法
Spring mvc中@RequestMapping 6个基本用法 spring mvc中的@RequestMapping的用法. 1)最基本的,方法级别上应用,例如: Java代码 @Reques ...
- Spring mvc中@RequestMapping 6个基本用法小结(转载)
小结下spring mvc中的@RequestMapping的用法. 1)最基本的,方法级别上应用,例如: @RequestMapping(value="/departments" ...
- Spring mvc中@RequestMapping 6个基本用法小结
Spring mvc中@RequestMapping 6个基本用法小结 小结下spring mvc中的@RequestMapping的用法. 1)最基本的,方法级别上应用,例如: @RequestMa ...
- 转:Spring mvc中@RequestMapping 6个基本用法小结
Spring mvc中@RequestMapping 6个基本用法小结 发表于3年前(2013-02-17 19:58) 阅读(11698) | 评论(1) 13人收藏此文章, 我要收藏 赞3 4 ...
- Spring MVC 中获取session的几种方法
Spring MVC 中使用session是一种常见的操作,但是大家上网搜索一下可以看到获取session的方式方法五花八门,最近,自己终结了一下,将获取session的方法记录下来,以便大家共同学习 ...
随机推荐
- 在Windows7 下调试CodeSmith 注意事项
编写CodeSmith模板和编写程序一样,也需要进行调试,CodeSmith支持使用CLR’s Just-in-Time debugger调试模板. 要调试模板,首先要在CodeTemplate声明中 ...
- 谁动了我的特征?——sklearn特征转换行为全记录
目录 1 为什么要记录特征转换行为?2 有哪些特征转换的方式?3 特征转换的组合4 sklearn源码分析 4.1 一对一映射 4.2 一对多映射 4.3 多对多映射5 实践6 总结7 参考资料 1 ...
- #笔记# CSS工作流
目录 明确代码规范 CSS Reset 关于前缀 浮动闭合 CSS的前处理器(Preprocessor)和后处理器(Postprocessor) 明确代码规范 目的是确保跨平台协作多人开发的代码显示界 ...
- 如何使用BHO定制你的Internet Explorer浏览器
原文出处:Browser Helper Objects: The Browser the Way You Want It一.简介 有时,你可能需要一个定制版本的浏览器.在这种情况下,你可以自由地把一些 ...
- Extjs的学习及MIS系统实践应用(系列文章)
本系列文章从Extjs的实际运用出发,结合系统开发的实践经验,详细解释Extjs的基本控件及控件扩展的用法,和在平时的学习运用中一步一步查阅的资料.积累经验的集锦.标题及链接奉上,用一个小程序,开启了 ...
- Python-变量
1.Python的变量是什么 变量是用来存储计算机程序中的信息,唯一的目的是将数据存储在内存中. 2.Python变量的组成 变量由字母.数字.下划线组成: 变量的第一位不能是数字,可以是字母或下划线 ...
- vpn找不到设备,win7建立新的VPN总时显示错误711,无法启动 Remote Access Connection Manager 及 Remote Access Auto Connection Manager 错误1068
试试相关服务!一.remote access connection manager是网络连接的服务,它依赖于Technology服务,现在你的这个服务已经启动,而Secure Socket Tunne ...
- apache httpclient cache 实现可缓存的http客户端
这里的cache storage 采用ehcache,而不是默认的内存式的cache storage.采用ehcache可以将内容缓存到磁盘上. maven <dependency> &l ...
- 算法:Astar寻路算法改进
早前写了一篇<RCP:gef智能寻路算法(A star)> 出现了一点问题. 在AStar算法中,默认寻路起点和终点都是N x N的方格,但如果用在路由上,就会出现问题. 如果,需要连线的 ...
- 【WEB】初探Spring MVC框架
Spring MVC框架算是当下比较流行的Java开源框架.但实话实说,做了几年WEB项目,完全没有SpringMVC实战经验,乃至在某些交流场合下被同行严重鄙视“奥特曼”了.“心塞”的同时,只好默默 ...