62

在 JSF 2.0 应用程序中使会话无效的最佳方法是什么?我知道 JSF 本身不处理会话。到目前为止我能找到

private void reset() {
    HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
            .getExternalContext().getSession(false);
    session.invalidate();
}
  1. 这种方法正确吗?有没有办法不接触 ServletAPI?
  2. 考虑一个@SessionScopedUserBean 处理用户登录-注销的场景。我在同一个bean中有这个方法。reset()现在,当我在完成必要的数据库更新后调用该方法时,我当前的会话范围 bean 会发生什么?因为即使是 bean 本身也存储在HttpSession?
4

3 回答 3

125

首先,这种方法正确吗?有没有办法不接触 ServletAPI?

您可以使用ExternalContext#invalidateSession()使会话无效而无需获取 Servlet API。

@ManagedBean
@SessionScoped
public class UserManager {

    private User current;

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "/home.xhtml?faces-redirect=true";
    }

    // ...

}

我当前的会话范围 bean 会发生什么?因为即使是 bean 本身也存储在 HttpSession 中?

在当前响应中仍然可以访问它,但在下一个请求中将不再存在。因此,在无效后触发重定向(新请求)很重要,否则您仍然会显示旧会话中的数据。可以通过添加faces-redirect=true到结果来完成重定向,就像我在上面的示例中所做的那样。另一种发送重定向的方法是使用ExternalContext#redirect().

public void logout() throws IOException {
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.invalidateSession();
    ec.redirect(ec.getRequestContextPath() + "/home.xhtml");
}

然而,在这种情况下,它的使用是有问题的,因为使用导航结果更简单。

于 2011-04-11T11:25:54.213 回答
13
public void logout() {
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
}
于 2012-07-19T09:57:04.027 回答
-1

前端代码为:

<h:form>
<h:commandLink action="#{userManager.logout()}">
       <span>Close your session</span>
</h:commandLink>
</h:form>

后端代码是:

public String logout() {
    HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
    if (session != null) {
        session.invalidate();
    }
    return "/login.xhtml?faces-redirect=true";  
}
于 2020-12-11T11:21:29.230 回答