你提出了一个非常好的问题! 确实,使用 request.getSession().getAttribute(Constants.ADMIN_ID)
也能从 Session 中获取属性,那么 @SessionAttribute
注解和这种方式到底有什么区别呢?
request.getSession().getAttribute(Constants.ADMIN_ID)
的工作方式
- 手动获取 Session:
request.getSession()
: 首先,你需要通过HttpServletRequest
对象获取HttpSession
对象。getAttribute(Constants.ADMIN_ID)
: 然后,你需要调用HttpSession
的getAttribute
方法,并传入 Session 属性的名称 (这里是Constants.ADMIN_ID
)。
- 类型转换:
getAttribute
返回一个Object
对象, 你需要手动将其强制转换为你需要的类型,例如Integer
。
- 空值处理:
- 你需要自己判断
getAttribute
是否返回了null
,并且做相应的处理 (例如设置默认值)。
- 你需要自己判断
@SessionAttribute
的工作方式
- 声明式 Session 获取:
@SessionAttribute(value = Constants.ADMIN_ID, required = false) Integer adminId
: 你只需要在方法参数上添加@SessionAttribute
注解,并指定属性名称,Spring MVC 会自动从 Session 中获取数据。
- 自动类型转换:
- Spring 会自动将 Session 中的属性值转换为方法参数的类型 (
Integer
在此例中)。
- Spring 会自动将 Session 中的属性值转换为方法参数的类型 (
- 可选属性:
- 你可以通过
required
属性来控制 Session 属性是否是必须的, 如果为false
, 并且 Session 中没有这个属性,则方法参数会被注入null
。
- 你可以通过
- 简洁性:
@SessionAttribute
提供一种声明式的、更加简洁的方式来获取 Session 属性, 减少了繁琐的获取和类型转换代码。
主要区别
Feature | request.getSession().getAttribute(Constants.ADMIN_ID) | @SessionAttribute(value = Constants.ADMIN_ID, required = false) Integer adminId |
---|---|---|
获取方式 | 手动通过 HttpServletRequest 获取 HttpSession , 然后再调用 getAttribute 。 | 声明式地使用注解,Spring MVC 自动处理。 |
代码量 | 代码较多,需要手动处理获取 session、获取属性值、类型转换和空值判断。 | 代码简洁,只需注解声明,Spring 自动处理。 |
类型转换 | 需要手动进行类型转换。 | 自动进行类型转换。 |
空值处理 | 需要手动判断是否返回 null 。 | 使用 required 属性,可以指定是否需要处理空值。 |
异常处理 | 需要手动处理 getAttribute 返回 null 或类型转换失败的异常。 | Spring 会抛出异常如果 Session 中找不到属性或者类型转换失败 (当 required=true 时)。 |
可读性 | 代码较为冗长,可读性较差。 | 代码简洁,更易读懂。 |
维护性 | 需要自己编写处理 Session 属性的代码。 | 依赖于 Spring 的注解处理,维护性更高。 |
测试性 | 测试代码需要模拟 HttpServletRequest 和 HttpSession 。 | 测试代码更简洁,可以使用 MockMvc 测试 Spring MVC 控制器。 |
总结
request.getSession().getAttribute(Constants.ADMIN_ID)
: 是一种传统的、手动的方式来获取 Session 属性。 你需要编写很多代码来完成获取、类型转换、以及空值处理。@SessionAttribute(value = Constants.ADMIN_ID, required = false) Integer adminId
: 是一种声明式的、更简洁的方式来获取 Session 属性。 Spring 会帮助你自动获取,转换类型, 和处理空值问题。
通常情况下,我们 推荐使用 @SessionAttribute
,因为它更加简洁、类型安全、可读性更强, 并且更加符合 Spring 的编程风格。 request.getSession().getAttribute
这种方式, 更加适合于没有使用 Spring MVC 框架的场景, 例如原生 Servlet 的场景。
简单来说, @SessionAttribute
是 Spring MVC 提供的一个语法糖,简化了从 Session 获取属性的操作。 它更符合 Spring 的编程风格, 也更简洁易维护。