Guice 3.0 @ScopeSession Пользовательский объект не является недействительным по истечении времени ожидания сеанса - PullRequest
0 голосов
/ 12 марта 2011

У меня есть класс:

@SessionScoped
public class LoggedUser {
    private User user;
    ...
}  

, который я использую для отслеживания входа пользователя в мое приложение.

В моем приложении Struts2 у меня есть Перехватчик, чтобы проверить, зарегистрирован ли пользователь, если он не перенаправлен на страницу входа.

public class LoggedUserInterceptor extends AbstractInterceptor {

    private static final long serialVersionUID = 2822434409188961460L;

    @Inject
    private LoggedUser loggedUser;

    @Override
    public String intercept(ActionInvocation invocation) throws Exception { 
        if(loggedUser==null || !loggedUser.isLogged()){
            return "login";
        }
        return invocation.invoke();
    }

}

Проблема возникает при превышении времени ожидания сеанса. Объект LoggdeUser никогда не является нулевым или удаленным. У меня всегда последний экземпляр.

Я добавил слушателя сессии.

public class SessionListener implements HttpSessionListener {

    private static Logger logger = Logger.getLogger(SessionListener.class.getName());

    @Override
    public void sessionCreated(HttpSessionEvent event) {
        logger.info("sessionCreated = " + event.getSession().getId());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        logger.info("sessionDestroyed = " + event.getSession().getId());
    }

}

Я вижу, что sessionDestroyed вызывается, но когда я снова вхожу в мой перехватчик ... LoggedUser никогда не воссоздается для нового сеанса.

почему?

Мой Struts2 Действие для входа в систему это

public class LoginUserAction extends ActionSupport implements ModelDriven<LoggedUser>, ServletRequestAware {
    ...
    @Inject
    private LoggedUser loggedUser;

    public String execute() throws Exception {
        ...
        loggerUser.setLoggedTime(now);
        ...
        return SUCCESS;
    }

Я тоже добавляю это в web.xml

session-config
    session-timeout 2 /session-timeout
    /session-config

Ответы [ 3 ]

1 голос
/ 12 марта 2011

Я ничего не знаю о Struts2, но я предполагаю, что область перехватчика шире, чем область сеанса.Другими словами, экземпляр перехватчика хранится дольше, чем сеанс.Guice не может и не будет устанавливать для введенного поля значение null по окончании сеанса, и при этом он никогда не будет повторно вводить объект автоматически.

Что вам нужно сделать, если вы используете объект сболее короткий жизненный цикл внутри объекта с более длинным жизненным циклом (например, объект RequestScoped внутри объекта SessionScoped или объект SessionScoped внутри одиночного объекта) вводит Provider для объекта с более коротким сроком службы.

В вашем случае, я думаю, это, вероятно, то, что вам нужно:

public class LoggedUserInterceptor extends AbstractInterceptor {
    private static final long serialVersionUID = 2822434409188961460L;

    @Inject
    private Provider<LoggedUser> loggedUserProvider;

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        LoggedUser loggedUser = loggedUserProvider.get();
        if(loggedUser==null || !loggedUser.isLogged()){
            return "login";
        }
        return invocation.invoke();
    }
}
0 голосов
/ 12 апреля 2011

самый простой способ сделать это, наконец, поместить токен в сеанс при входе в систему и проверить его с помощью перехватчика

</p> <pre> @Override public String intercept(ActionInvocation invocation) throws Exception { loggedUser = (LoggedUser) invocation.getInvocationContext().getSession().get(LoggedUser.SESSIONTOKEN); if(loggedUser==null || !loggedUser.isLogged()){ logger.info("loggedUser not present in session"); return "login"; } return invocation.invoke(); } </pre> <p>

в действии

</p> <pre> request.getSession().setAttribute(LoggedUser.SESSIONTOKEN, loggedUser); </pre> <p>

0 голосов
/ 12 марта 2011

Я не знаю хитрости, но сеанс доступен для перехватчика и может быть легко доступен для действия через SessionAware:

ActionInvocation обеспечивает доступ к сеансу. Следующее является частью перехватчика «Аутентификация». Если объект «Пользователь» отсутствует, возвращается Action.LOGIN.

public String intercept(ActionInvocation invocation) throws Exception {
    Map session = invocation.getInvocationContext().getSession();
    appLayer.User user = (appLayer.User) session.get("User");
    if (user == null){
        return Action.LOGIN;
    }
    return invocation.invoke();
}

Я помещаю объект пользователя в сеанс только при входе пользователя в систему.

В действии входа в систему я помещаю объект пользователя в сеанс:

public class Login extends ActionSupport implements SessionAware {
  private Map<String, Object> session;
  private String userName;
  private String password;

  public String execute() {
    //use DB authentication once this works
    //if ("ken".equalsIgnoreCase(userName) && "ken".equalsIgnoreCase(password)){
    try {
        User user = new User(userName, password);
        session.put("User", user);
        return ActionSupport.SUCCESS;
    } catch (Exception e) {
        System.out.println("There was an exception" + e.getMessage());
        return ActionSupport.LOGIN;
    }
  } 

  public void validate() {
    String user = this.getUserName();
    String pass = this.getPassword();
    //This block is a bit redundant but I couldn't figure out how
    //to get just the hibernate part to report an exception on Username/pass
    if (!StringUtils.isBlank(this.getUserName()) && !StringUtils.isBlank(this.getPassword())) {
        try {
            Class.forName("com.ibm.as400.access.AS400JDBCDriver").newInstance();
            String url = "jdbc:as400://192.168.1.14";
            DriverManager.getConnection(url, user, pass).close();
        } catch (Exception e) {
            addFieldError("login.error.authenticate", "Bad Username / Password");
        }
      }
      if (StringUtils.isBlank(getUserName())) {
        addFieldError("login.error.name", "Missing User Name");
      }
      if (StringUtils.isBlank(getPassword())) {
        addFieldError("login.error.password", "Missing Password");
      }
    //else both are blank don't report an error at this time
  }

  ... getters/setters....
  }//end class

Если я правильно помню, это происходит по крайней мере частично из "Struts2 in Action". В любом случае, я большой сторонник DI, но так как Сессия довольно доступна для перехватчиков и действия, я не беспокоюсь.

...