2010-02-06 191 views
20

在Spring 3.0下有没有办法在访问HttpSession时不将其包含在方法签名中?我真正想做的是能够从可以为空的HttpSession传入值。春季MVC会话属性访问

事情是这样的:

@RequestMapping("/myHomePage") 
public ModelAndView show(UserSecurityContext ctx) {} 

,而不是这样的:

@RequestMapping("/myHomePage") 
public ModelAndView show(HttpSession session) { 
     UserSecurityContext ctx = (UserSecurityContext) session.getAttribute("userSecurityCtx"); 
} 
+1

相关:http://stackoverflow.com/questions/3621266/how-to-pass-a-session-attribute-as-method-argument-parameter-with-spring-mvc – Bozho 2010-09-01 19:12:51

+0

这里是春季门票[#SPR- 4452](HTTPS://jira.springsource。org/browse/SPR-4452)。 Upvote票以加快解析速度。 – 2011-09-07 12:18:24

回答

25

通过@uthark提到的@SessionAttribute标注不适合这个任务 - 我认为这是也是,但是bit of reading sh OWS否则:如使用 这个注解表明

会话属性对应一个特定 处理程序的模型属性, 越来越透明地储存在 对话会议。那些 属性将被删除,一旦 处理程序指示其会话会话完成其 。因此,在特定的 处理程序的对话过程中,使用 此设施可以存储临时会话 中的这种对话 属性,该属性应该是 。

对于永久会话属性,例如, 用户身份验证对象,请使用传统的session.setAttribute 方法代替。或者, 考虑使用WebRequest接口的通用 管理功能的属性 。

换句话说,@SessionAttribute是用于在会话中存储会话MVC-模型对象(而不是将其存储为请求属性)。它不打算用于任意会话属性。正如您发现的那样,只有在会话属性始终存在的情况下才有效。

我不知道任何其他可替代的,我想你坚持HttpSession.getAttribute()

+0

我实际上最终使用了@uthark解决方案的一部分。为防止由空用户上下文对象引起的异常,我在前面放置了一个ServletFilter以确保它已被填充。对于这个特定工作流程的解决方案,我很满意,但你似乎很奇怪你不能自己处理空值,而不是Spring为你处理它。 谢谢大家的帮助和见解。 – Mark 2010-02-06 20:26:00

+0

@Mark:这似乎很奇怪,是的。 – skaffman 2010-02-06 20:37:20

+0

@skaffman是否有一个原因,文件不会出来,并说控制器,而不是使用术语'处理程序? – 2016-05-26 00:15:57

5

是的,可以。

@SessionAttributes("userSecurityContext") 
public class UserSecurityContext { 
} 

@RequestMapping("/myHomePage") 
public String show(@ModelAttribute("userSecurityContext") UserSecurityContext u) { 
    // code goes here. 
} 

详情请参见:

  1. http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/SessionAttributes.html

  2. http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/ModelAttribute.html

+0

感谢您的回复。我最初使用session.putAttribute()添加我的安全性上下文。当我尝试你的代码时,上下文对象为空。 – Mark 2010-02-06 18:07:01

+3

对不起,当我将@SessionAttributes(“userSecurityContext”)添加到控制器时,这确实结束了工作。简单地将它添加到实际的UserSecurityContext pojo中并没有为我做任何事情。然而,当属性为null时,Spring引发了一个异常,这是我试图避免的。 org.springframework.web.HttpSessionRequiredException:需要会话属性'userSecurityContext' - 未在会话中找到 – Mark 2010-02-06 18:51:33

+0

@Mark如果此答案不合适,请移动接受的标志(或删除它),如下面答案中的建议(由* skaffman *)。这是误导性的,因为许多人只阅读接受的答案。 (请在下面阅读您的评论 - 您的电话!) – 2011-02-02 09:02:14

8

你可以使用一个RequestContextHolder

class SecurityContextHolder { 
    public static UserSecurityContext currentSecurityContext() { 
     return (UserSecurityContext) 
      RequestContextHolder.currentRequestAttributes() 
      .getAttribute("userSecurityCtx", RequestAttributes.SCOPE_SESSION)); 
    } 
} 
... 
@RequestMapping("/myHomePage")   
public ModelAndView show() {   
    UserSecurityContext ctx = SecurityContextHolder.currentSecurityContext(); 
} 

跨领域问题,例如安全性这种方法更好,因为你不需要修改你的控制器签名。

+0

我也有这样的解决方案。它有点类似于ThreadLocal模式。谢谢! – Mark 2010-02-07 17:41:05