Spring 事件会话 bean 初始化
Spring session bean initialization on event
在我的项目中,我需要 SessionBean 来存储与当前会话关联的对象。在会话已创建且用户已通过身份验证时,我想将对象设置为我的 bean。
Bean 定义:
<bean scope="session" class="org.example.SessionBean">
<aop:scoped-proxy/>
</bean>
身份验证侦听器:
public class SpringAuthenticationListener implements ApplicationListener<ApplicationEvent> {
private LogService logService;
private UserService userService;
@Autowired
private SessionBean sessionBean;
public SpringAuthenticationListener(LogService logService, UserService userService) {
this.logService = logService;
this.userService = userService;
}
@Override
public void onApplicationEvent(ApplicationEvent e) {
LogEvent logEvent = new LogEvent();
if (e instanceof AuthenticationSuccessEvent) {
AuthenticationSuccessEvent event = (AuthenticationSuccessEvent) e;
UserDetails userDetails = (UserDetails) event.getAuthentication().getPrincipal();
User loggedUser = userService.getUser( userDetails.getUsername() );
sessionBean.setLoggedUser(loggedUser);
}
}
}
但是,问题是我无法获取当前 SessionBean 实例的实例。那是我的错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.org.example.SessionBean#0': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
我该怎么做?什么事件或侦听器会让我用当前用户初始化 SessionBean。
Spring 使用 Filter
过滤器的安全操作在任何 Servlet
之前执行,因此也在 DispatcherServlet
之前执行。为了能够使用 request
或 session
作用域 bean,需要 RequestContext
。这通常是由DispatcherServlet
编写的。当想要在 DispatcherServlet
之外使用作用域 bean 时,您需要进行一些额外的设置。正如例外所述:
use RequestContextListener or RequestContextFilter to expose the current request.
要修复,请将 RequestContextListener
or RequestContextFilter
添加到您的 web.xml
。使用后者时,确保它在 springSecurityFilterChain
之前执行,否则它不会生效。侦听器始终在任何过滤器之前执行。
在我的项目中,我需要 SessionBean 来存储与当前会话关联的对象。在会话已创建且用户已通过身份验证时,我想将对象设置为我的 bean。
Bean 定义:
<bean scope="session" class="org.example.SessionBean">
<aop:scoped-proxy/>
</bean>
身份验证侦听器:
public class SpringAuthenticationListener implements ApplicationListener<ApplicationEvent> {
private LogService logService;
private UserService userService;
@Autowired
private SessionBean sessionBean;
public SpringAuthenticationListener(LogService logService, UserService userService) {
this.logService = logService;
this.userService = userService;
}
@Override
public void onApplicationEvent(ApplicationEvent e) {
LogEvent logEvent = new LogEvent();
if (e instanceof AuthenticationSuccessEvent) {
AuthenticationSuccessEvent event = (AuthenticationSuccessEvent) e;
UserDetails userDetails = (UserDetails) event.getAuthentication().getPrincipal();
User loggedUser = userService.getUser( userDetails.getUsername() );
sessionBean.setLoggedUser(loggedUser);
}
}
}
但是,问题是我无法获取当前 SessionBean 实例的实例。那是我的错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.org.example.SessionBean#0': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
我该怎么做?什么事件或侦听器会让我用当前用户初始化 SessionBean。
Spring 使用 Filter
过滤器的安全操作在任何 Servlet
之前执行,因此也在 DispatcherServlet
之前执行。为了能够使用 request
或 session
作用域 bean,需要 RequestContext
。这通常是由DispatcherServlet
编写的。当想要在 DispatcherServlet
之外使用作用域 bean 时,您需要进行一些额外的设置。正如例外所述:
use RequestContextListener or RequestContextFilter to expose the current request.
要修复,请将 RequestContextListener
or RequestContextFilter
添加到您的 web.xml
。使用后者时,确保它在 springSecurityFilterChain
之前执行,否则它不会生效。侦听器始终在任何过滤器之前执行。