0

我有两个网页index.xhtmlsessionExpiry.xhtml. sessionExpiry.xhtml目标是在超时时将用户重定向到页面。我已将会话超时设置为 1 分钟web.xml。我正在使用http-equiv=refresh标签在超时时重定向用户。 有一个必填文本字段,如果未输入任何内容,则会index.xhtml显示错误消息。onblur event添加了一个HttpSessionListener记录会话创建和销毁。

测试场景:在浏览器中打开网页,服务器日志显示会话创建时间,15秒后点击输入文本框,点击外部,显示丰富的错误信息。让网页空闲,网页sessionExpiry.xhtml在 1 分钟后重定向到(我预计这会在 1 分 15 秒后发生),但服务器日志上的会话被破坏消息发生在 2-3 分钟左右。

为什么会话销毁延迟?如何在 AJAX 事件后 1 分钟不活动后使会话到期?以下是源代码。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<session-config>
    <session-timeout>
        1
    </session-timeout>
</session-config>
<listener>
    <listener-class>com.sessiontimeout.HttpSessionChecker</listener-class>
</listener>
<welcome-file-list>
    <welcome-file>index.xhtml</welcome-file>
</welcome-file-list>

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:rich="http://richfaces.org/rich">
    <h:head>
        <title>Facelet Title</title>
        <meta http-equiv="refresh" content="#{session.maxInactiveInterval};url=./sessionExpiry.xhtml" />
    </h:head>
    <h:body>
        <h:form>
            Hello from Facelets
            <h:panelGrid columns="3">
                Enter some text:
                <h:inputText id="txt" required="true" maxlength="16" size="20"
                             autocomplete="off" requiredMessage="Text is Required">
                    <f:ajax event="blur" render="txtmsg" />
                </h:inputText>
                <rich:message id="txtmsg" for="txt" />
            </h:panelGrid>
        </h:form>
    </h:body>
</html>

sessionExpiry.xhtml

<h:body>
        Session Timed out after ${session.maxInactiveInterval/60} minutes of inactivity.
</h:body>

HttpSessionChecker.java

public class HttpSessionChecker implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent event) {
        System.out.println("Session ID " + event.getSession().getId() + " created at " + new Date());
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        System.out.println("Session ID " + event.getSession().getId() + " destroyed at " + new Date());
    }

}
4

1 回答 1

0

我原以为这会在 1 分 15 秒后发生

您将超时设置为一分钟,因此它在一分钟后超时。当 ajax 调用成功时,您需要进行同步回发以更新该元元素或通过 JS 更新该元素,这可能会延长事件(请参阅是否可以使用 javascript 更改页面的元标记?)。

服务器日志上的会话被破坏消息发生在 2-3 分钟左右

对于超时事件时容器何时使会话失效没有限制(请参阅识别会话超时)。合同告诉它在某个时间失效,但不完全是在它超时的时候,它不再被视为有效。对于即时失效,可以使用 invalidate-and-send-redirect 方法(请参阅JSF logout using session.invalidate does not clear the current username?)。

为什么会话销毁延迟?如何在 AJAX 事件后 1 分钟不活动后使会话到期?

以上这些问题基本都回答了。另请参阅以下有关如何正确处理会话过期事件的问题:

  1. 如何在 JSF 2 中处理会话过期和 ViewExpiredException?
  2. javax.faces.application.ViewExpiredException:无法恢复视图
  3. JSF/PrimeFaces ajax 请求上的会话超时和 ViewExpiredException 处理
于 2013-08-01T20:13:23.633 回答