什么时候在JSF登录期间创建会话?

时间:2013-02-12 13:45:42

标签: jsf-2 session-state

在JSF中,似乎会在成功登录之前创建。即只是请求登录页面就会导致创建一个新会话。

为每个收到的请求创建会话而不是每个成功登录用户似乎非常浪费(并且容易受到DDoS攻击)。

下面的代码非常通用,但显示了我所指的那种简单场景。

的index.xhtml:

<html>
    <body>
        <h:form id="login">
            <h:outputLabel for="username">Username</h:outputLabel>
            <p:inputText id="username" name="username" value="#{userController.username}"/>
            <h:outputLabel for="password">Password</h:outputLabel>
            <p:password id="password" name="password" value="#{userController.password}"/>

            <p:commandButton id="loginButton" value="login" action="#{loginController.login}"/>
        </h:form>
    </body>
</html>

LoginController.java

@ViewScoped
public class LoginController implements Serializable {

    String username;
    String password;

    public void login(){
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        if (request.getSession(false) == null){
            System.out.println("No session.");
        } else {
            System.out.println("Session already exists.");
        }

        try {
            request.login(username, password);
        } catch (ServletException e) {
            FacesContext.getCurrentInstance.addMessage(null, new FacesMessage("Login failure", e.getMessage()));
        }
    }

    // username and password getters/setters

}

编辑:修复了shambolic代码示例

1 个答案:

答案 0 :(得分:8)

首先,您的测试方法完全错误。

if (request.getSession() == null){
    System.out.println("No session.");
} else {
    System.out.println("Session already exists.");
}

请仔细阅读无争论getSession()方法的javadoc。你会意识到永远不会返回null

回到具体问题,默认情况下JSF会自动创建会话,因为JSF视图状态必须存储在那里。如果将JSF状态保存方法设置为client而不是server,则它将不会存储在会话中,因此不需要创建会话。

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

在即将推出的JSF 2.2中,您也可以将bean放在请求范围内,并使用<f:view transient="true">完全无状态。这是针对当前的JSF 2.1版本,仅在Mojarra 2.1.19之后可用。另见例如来自Mojarra开发人员的this blog