`
bugyun
  • 浏览: 557077 次
社区版块
存档分类
最新评论

Spring MVC中Session的正确用法(转)

 
阅读更多

 

转自:http://www.cnblogs.com/waytofall/p/3460533.html

 

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中是否已经注册了这个属性

分享到:
评论

相关推荐

    spring MVC No Session found for current thread

    当我们在Controller方法中尝试获取session时,如果当前请求没有与之关联的session,Spring MVC就会抛出“No Session found for current thread”的异常。 1. **配置问题**: - **DispatcherServlet配置**:确保你...

    Spring MVC 中获取session的几种方法(小结)

    在 Spring MVC 中,我们可以使用 @Autowired 注解来将 HttpServletRequest 注入到我们的控制器中,然后通过 request.getSession() 方法获取 Session 对象。例如: ```java @Autowired private HttpServletRequest ...

    Spring MVC框架简介和使用

    为了展示如何使用 Spring MVC 构建一个简单的 Web 应用,我们可以通过实现一个基本的 HelloWorld 示例来快速入门。 #### 步骤: 1. **添加必要的 JAR 包**:首先,需要在项目中添加 Spring MVC 及其依赖库。这些库...

    Spring MVC简单例子

    Spring MVC 是一个强大的Java web开发框架,用于构建可维护、可扩展且结构良好的Web应用程序。这个框架基于Spring IoC(Inversion of ...实践中遇到的问题和解决方法也会加深对Spring MVC的理解,有助于提升开发技能。

    最简单的用户登录与注册系统 spring mvc spring jdbc

    这个项目是一个基于Spring MVC和Spring JDBC的简单用户管理应用,旨在帮助初学者理解如何在实际开发中实现用户登录、注册以及信息修改功能。Spring MVC是Spring框架的一个模块,主要用于构建Web应用程序,而Spring ...

    Spring中自定义session管理,SpringSession的使用

    3. 使用Session:在Controller方法中,可以使用`@SessionAttributes`注解声明需要在Session中存储的模型属性,然后通过`HttpSession`接口获取或设置Session属性。 五、高级用法 1. 自定义SessionId生成器:通过实现...

    Spring mvc+hibernate+mysql Demo

    在这个"Spring mvc+hibernate+mysql Demo"项目中,可能包含了一个简单的示例应用,展示了如何配置和使用这三个技术。"test"文件可能是测试代码或者测试数据,用于验证整个系统的正确性。测试可能涵盖了CRUD操作,...

    spring mvc login demo

    这个"spring mvc login demo"项目旨在提供一个基础的登录功能示例,帮助开发者理解如何在Spring MVC环境中实现用户身份验证。在这个教程中,我们将深入探讨相关知识点。 首先,Spring MVC 的核心组件包括...

    spring mvc + spring + hibernate 全注解整合开发视频教程 12

    在本教程中,我们将深入探讨如何使用Spring MVC、Spring和Hibernate三大框架进行全注解的整合开发。这个视频教程系列的第12部分,将帮助开发者掌握如何在Java Web项目中高效地集成这三个核心框架,实现松耦合、可...

    bbs.zip_Spring mvc bbs_hibernate bbs_spring mvc_spring mvc hiber

    Spring MVC的Model对象可以用来存储业务数据,而View则可以使用JSP、Thymeleaf等模板引擎进行渲染,呈现用户界面。 Hibernate,作为一个优秀的对象关系映射(ORM)框架,消除了Java代码与数据库之间的直接交互,...

    基于jpa+hibernate+spring+spring mvc注解方式项目

    在Spring项目中,通常会使用`LocalSessionFactoryBean`配置Hibernate,并通过`SessionFactory`实例来创建`Session`。而使用Spring Data JPA时,只需要配置数据源、JPA供应商(如Hibernate)以及实体扫描路径即可。...

    Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)所有实验及实验报告.zip

    本教程专注于使用Spring、Spring MVC和MyBatis这三个关键组件进行实战教学。这三者构成了Java EE开发中的重要支柱,为开发者提供了强大的功能和灵活性。 Spring框架是Java EE开发的核心,它是一个全功能的容器,...

    spring mvc+spring+hibernaate+bootstrap+maven通用后台部门员工管理系统.zip

    这是一个基于Java技术栈的通用后台管理系统,主要使用了Spring MVC、Spring、Hibernate、Bootstrap和Maven等技术。这些技术在IT行业中广泛应用于企业级Web应用开发,构建高效、可维护的系统。下面将分别详细解释这些...

    基于Spring Mvc的JavaWeb项目

    在JavaWeb中,通常会使用JSP配合Servlet或者Spring MVC的ModelAndView对象来实现分页,同时需要数据库查询支持分页参数,如LIMIT和OFFSET。 3. **删除操作**:项目支持单个和批量删除功能。这需要在后台编写对应的...

    spring mvc,spring,hibernate框架开发

    Spring MVC、Spring 和 Hibernate 是 Java 开发中三个非常重要的框架,它们共同构成了企业级应用的基石,尤其是在构建大型、复杂的Web应用程序时。Spring MVC 作为Spring框架的一部分,负责处理HTTP请求,提供MVC...

    Servlet JSP Spring MVC初学指南(alin书签).pdf

    9. **RESTful服务**:使用Spring MVC创建RESTful API,理解HTTP方法(GET、POST、PUT、DELETE)在资源操作中的应用。 10. **视图技术**:除了JSP,还可以使用FreeMarker、Thymeleaf等模板引擎作为视图。 在"Servlet...

    spring mvc mybatis项目源码

    在Spring MVC和MyBatis整合的项目中,通常会使用Spring的`@Autowired`注解来注入MyBatis的SqlSessionTemplate或SqlSessionFactory,这样可以在Controller中直接调用Mapper接口的方法进行数据操作。同时,Spring的...

    spring mvc + spring + hibernate 全注解整合开发视频教程 09

    【标题】"Spring MVC + Spring + Hibernate 全注解整合开发视频教程 09" 提供了一次深入了解Java企业级应用开发的机会,特别是在使用Spring MVC、Spring和Hibernate这三大核心框架进行全注解配置的场景下。...

    spring mvc整合hibernate

    Spring MVC 和 Hibernate 是两个在Java Web开发中广泛使用的框架。Spring MVC 用于构建应用程序的前端控制器,提供模型-视图-控制器(MVC)架构,而 Hibernate 是一个强大的对象关系映射(ORM)框架,负责数据库操作...

    spring mvc项目后端源码

    19. **Spring Boot**:Spring MVC 常与 Spring Boot 结合使用,简化项目的初始化和配置。 这个"spring mvc项目后端源码"可能包含了上述部分或全部概念的实现,通过学习和分析这些代码,可以加深对 Spring MVC 框架...

Global site tag (gtag.js) - Google Analytics