在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代码示例
答案 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。