我是JSF编程的新手,我的登录/会话有问题,登录后会丢失。
我想实现一种简单的登录方式,使用户可以输入用户名和密码。所以我写了一个LoginController:
@ManagedBean
@SessionScoped
public class LoginController extends AbstractController{
@PostConstruct
public void initialiseSession() {
FacesContext.getCurrentInstance().getExternalContext().getSession(true);
}
private String username = "null";
private String password;
private boolean loggedIn = false;
@Inject
private EmployeeService employeeService;
public static final String employeeSessionKey = "user";
public LoginController() {
}
public String login() {
//check username and password and if true redirect to "/"
}
我的login.xhtml看起来像:
<h:form id="loginForm">
<h:outputLabel style="font-size:24px" value="Bitte melden Sie sich an!"/>
<p:panelGrid columns="2">
<p:outputLabel id="userOutput" for="userInput" value="Benutzername"/>
<p:inputText id="userInput" value="#{loginController.username}"></p:inputText>
<p:outputLabel id="passwordOutput" for="passwordInput" value="Passwort"/>
<p:inputText id="passwordInput" type="password" value="#{loginController.password}"></p:inputText>
<h:outputText value="Logindaten merken?" id="outputRememberLogin">
<p:selectBooleanCheckbox id="loginCheckbox">
</p:selectBooleanCheckbox>
<p:spacer width="10" id="loginFormLittleSpacer"></p:spacer>
</h:outputText>
<p:commandButton id="loginButton" value="Anmelden" action="#{loginController.login()}" ajax="false" >
</p:commandButton>
</p:panelGrid>
</h:form>
因此,当我登录时重定向有效。但是,当我转到另一个.xhtml页面时,会话会丢失。
为了测试这一点,我把
<p:outputLabel value="#{loginController.username}"/>
在我的页面上。登录后,用户名变为“ null”。
我在这个问题上疯了。
有任何想法吗?
之前感谢。
您的LoginController
bean看起来像它的注释还可以,并且代码看起来应该可以工作。但是,您可能还需要检查其他几件事。其中一些可能是显而易见的,但是您的问题缺少一些细节,因此我不确定您可能具有什么经验水平以及从这个答案开始的地方。因此,我从头开始(几乎)...
1.域名配置
要使用会话,必须使用合格的域名。将请求发送到IP地址将不允许会话工作,因为客户端浏览器仅将会话信息发送到完全限定的域名(http://example.com/)。如果您使用IP(例如“ http://127.0.0.1:8080/MyApp ”)调用Web应用,则会话数据将永远不会发送到您的Web应用,并且每个会话都会创建一个新的会话要求。确保对应用程序的每个请求都使用完全限定的域名和路径,例如“ http:// localhost:8080 / MyApp ”。
2.应用程序配置
检查您的Web应用程序的<session-config>
配置是否正确设置。默认配置应允许您的代码工作而不必添加任何特定内容,因此,如果您未添加任何内容,请不必为此担心。但是,您可能要确保没有任何事情可以阻止会话被重用。
<tracking-mode>COOKIE</tracking-mode>
)<session-timeout>60</session-timeout>
)之前不会过期<path>/</path>
)以下是我使用的常见会话配置…
<session-config>
<session-timeout>60</session-timeout>
<tracking-mode>COOKIE</tracking-mode>
<cookie-config>
<path>/</path>
<http-only>true</http-only>
<secure>false</secure>
</cookie-config>
</session-config>
3.客户端上的会话Cookie跟踪
如果以上几点仍不能解决问题,您可以通过监视应用程序与客户端浏览器之间的请求和响应流量来真正开始进入会话跟踪。会话信息通过名为“ JSESSIONID”的cookie(或查询字符串参数,如果禁用cookie)来回传递。其值将是唯一会话的ID,并且对于每个请求都必须相同,以确保您的Web应用程序跟踪相同的会话。以下重点介绍了一些需要寻找的东西……
确保将“ JSESSIONID”会话Cookie正确发送到客户端浏览器,并随每个后续请求一起发送回去。您可以使用Chrome或Safari的网络开发人员工具(在“网络”标签下)或单独的实用程序(例如Wireshark)来执行此操作。
<path>
上面指示的配置项进行更改。4. Bean中的会话管理(附加信息)
在您的initialiseSession()
方法中,FacesContext.getCurrentInstance().getExternalContext().getSession(true);
不会保存返回的会话对象,并且此行实际上什么也不做。该@SessionScoped
注释将已经创建了一个会话,并增加了“JSESSIONID” cookie来响应之前initialiseSession()
被调用。因此,调用的唯一原因getSession(true)
是要将会话保存到Bean中的私有对象,就像这样...
@ManagedBean
@SessionScoped
public class LoginController extends AbstractController{
// Create a global, private member for storing the session data...
private HttpSession session;
@PostConstruct
public void initialiseSession() {
// Assign the session to the global member…
session = FacesContext.getCurrentInstance().getExternalContext().getSession(true);
}
…
同样,getSession(true)
在您的示例中不需要调用,因为SessionScoped
Bean已经创建了会话。仅当您打算更新或使用会话对象(例如,添加属性或修改设置)时,才需要以上代码。
总之
仔细检查上述1 – 3点。我认为在以后的请求中不会将“ JSESSIONID” cookie发送回去。如果您可以确认每个请求中都包含“ JSESSIONID” cookie(具有相同的值),则问题与会话无关,并且可能与login()
方法中的代码有关。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句