JSF / primefaces Session - 会话丢失

时间:2015-02-17 10:15:11

标签: jsf session jsf-2 primefaces login

我是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”。

我对这个问题发疯了。

有什么想法吗?

之前谢谢。

1 个答案:

答案 0 :(得分:3)

你的LoginController bean看起来很合适,代码看起来应该可行。但是,您可能还需要检查其他一些事项。其中一些可能是显而易见的,但你的问题是缺少一些细节,所以我不确定你可能有什么样的经验以及从哪里开始这个答案。因此,我从一开始就开始(差不多)......


<强> 1。域名配置

要使用会话,您必须使用合格的域名。向IP地址发送请求将不允许会话工作,因为客户端浏览器仅将会话信息发送到完全限定的域名(http://example.com/)。如果您使用IP(例如“http://127.0.0.1:8080/MyApp”)调用您的Web应用程序,会话数据将永远不会发送到您的Web应用程序,您将为每个请求创建一个新会话。确保您对应用程序的每个请求使用完全限定的域名和路径,例如“http://localhost:8080/MyApp”。


<强> 2。应用程序配置

检查您的网络应用程序的<session-config>配置是否设置正确。默认配置应允许您的代码工作而无需添加任何特定的内容,因此如果您没有添加任何内容,请不要担心这一点。但是,您可能希望确保没有任何可能阻止会话被重用的内容。

  • 应启用会话Cookie(<tracking-mode>COOKIE</tracking-mode>
  • 超时应该足够长,以便在第二个请求(<session-timeout>60</session-timeout>
  • 之前不会过期
  • 应正确设置Cookie路径以供您使用(<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)执行此操作。

  • 确保&#39; JSESSIONID&#39; cookie存在于第一个请求的响应中......这将让您知道您的Web应用程序至少创建了会话和响应cookie。
  • 确保来自客户端浏览器的第二个请求正在传递&#39; JSESSIONID&#39; cookie back ...这是您的网络应用程序知道使用哪个现有会话的唯一方式。
  • 确保&#39; JESSIONID&#39; cookie有一条&#39; /&#39;的路径(可能会在浏览器中显示为“N / A&#39;”或您的网络应用的路径(例如,&#39; / MyApp&#39;)...客户端浏览器只会向您发送Cookie与每个域相关联的域和路径。例如,如果您的登录页面是&#39; http://example.com/MyApp/login&#39;,那么&#39; JSESSIONID&#39; Cookie可能有一条&#39; / MyApp&#39; (默认情况下),如果对&#39; http://example.com/&#39;进行了以下请求,则不会返回(没有&#39; / MyApp&#39;路径)。默认路径是您的Web应用程序的名称('/ MyApp'),可以使用上面指出的<path>配置项进行更改。

<强> 4。 Bean中的会话管理(附加信息)

initialiseSession()方法中,FacesContext.getCurrentInstance().getExternalContext().getSession(true);返回的会话对象未被保存,此行基本上什么都不做。 @SessionScoped注释已经创建了一个会话,并在调用initialiseSession()之前将“JSESSIONID”cookie添加到响应中。因此,调用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()方法中的代码相关。

相关问题