Struts 2 + Spring将一个托管的spring bean放入会话中

时间:2015-11-16 13:48:41

标签: java spring spring-mvc session struts2

考虑Struts 2 + Spring 4项目。

对于每次登录,User对象都会被放入会话中。作为一个非常简单的动作,它将看起来

public class LoginProcess implements ServletRequestAware {

  @Inject
  private AuthenticationServices authenticationServices;

  public String execute() {
    //The login method makes a new User and fills its setters
    User newUser = authenticationServices.login(....);
    getServletRequest().getSession().setAttribute("USER_SESSION", user);
  }
}

当我们手动创建一个新的User对象,因此它不是托管的spring bean,我们无法在User类中使用spring功能:@Inject@Value ,...

我尝试将用户更改为:

@Named
@Scope(value="session")
public class User { ...
    @Inject
    private AccountServices accountServices;

}

并注入User而不是调用new User,但我收到错误:

Caused by: 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.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
    at org.springframework.web.context.request.SessionScope.get(SessionScope.java:91)

虽然它描述了错误,但我找不到如何解决它,我不确定这是否是正确的方法。当我使用session scope

时,我似乎只能使用spring spring mvc

有任何意见吗?!

为什么我需要这个? (简化情况)

用户对象具有getAccounts()个方法,可以获取所有用户帐户。获取用户帐户是一项昂贵的操作,并且用户可能在登录期间不需要其帐户。

因此,我们不会在用户登录后立即获取用户帐户,而是让get方法获取用户帐户(如果没有用户帐户):

public class User() {
  private Accounts accounts;

  @Inject
  private AccountServices accountServices;

  Accounts getAccounts() {
    if (accounts == null) {
      accounts = accountServices.getUserAccountsFromDB(...)
    }
    return accounts;
  }

1 个答案:

答案 0 :(得分:2)

不要自己创建User的新实例,而是从Spring上下文中获取bean。

例如,您可以通过实现ApplicationContextAware接口并调用getBean方法之一来实现它。

User user = applicationContext.getBean(User.class);
// populate user and put it into session

以这种方式,它是一个Spring托管bean,应该注入所有必需的属性。

但请考虑将您的User更改为简单的POJO并将所有业务逻辑(例如提取用户帐户)移动到更合适的位置,这样您的模型层就会更清晰,更容易测试。