如何在Java Web应用程序中动态设置会话超时时间?

49

我需要为用户提供一个网页界面来更改会话超时时间间隔。因此,Web应用程序的不同安装将能够为其会话设置不同的超时时间,但它们的web.xml不能不同。

是否有一种编程方式设置会话超时时间,以便我可以在应用程序启动时使用例如ServletContextListener.contextInitialized()读取配置的时间间隔并进行设置?

4个回答

79

可以使用 HttpSessionListener 替代 ServletContextListener。

sessionCreated() 方法中,您可以以编程方式设置会话超时时间:

public class MyHttpSessionListener implements HttpSessionListener {

  public void sessionCreated(HttpSessionEvent event){
      event.getSession().setMaxInactiveInterval(15 * 60); // in seconds
  }

  public void sessionDestroyed(HttpSessionEvent event) {}

}

不要忘记在部署描述符中定义监听器

<webapp>
...      
  <listener>                                  
    <listener-class>com.example.MyHttpSessionListener</listener-class>
  </listener>
</webapp>

(或者从Servlet版本3.0开始,您可以使用@WebListener注释代替。)


尽管如此,我建议为每个应用程序创建不同的web.xml文件,并在其中定义会话超时时间:

<webapp>
...
  <session-config>
    <session-timeout>15</session-timeout> <!-- in minutes -->
  </session-config>
</webapp>

1
有没有一种方法可以通过从网页传递给HTTP监听器的变量来替换静态的15 * 60(以选择将影响所有新创建的会话的超时时间)? - user2133558
虽然我看到很多赞,但这真的可靠吗?会话管理器(一个自定义的管理器)在调用监听器之前将会话保存在持久性存储中。当会话被保存时,超时已经设置好了。因此,我不确定在保存后设置值如何根据编程设置导致会话值过期。 - dpkg

36

有没有一种方法可以通过编程方式设置会话超时时间?

基本上有三种方法可以设置会话超时值:

  • 使用标准的web.xml文件中的session-timeout ~或~
  • 在缺少此元素的情况下,通过获取服务器的默认session-timeout值(从而在服务器级别上进行配置)~或~
  • 通过在Servlet或JSP中使用HttpSession.setMaxInactiveInterval(int seconds)方法进行编程。

但请注意,后一选项仅为当前会话设置超时值,这不是全局设置。


2

正如其他答案所说,你可以在Session监听器中进行更改。但是你也可以直接在你的servlet中进行更改,例如:

getRequest().getSession().setMaxInactiveInterval(123);

3
可以实现,但不能保证何时发生。它取决于您的servlet的生命周期,这是一种选择。请注意,监听器将始终在创建事件上进行设置。 - Eduardo Fabricio

0
我需要为我的用户提供一个网页界面来更改会话超时时间间隔。因此,Web应用程序的不同安装可以为其会话设置不同的超时时间,但它们的web.xml文件不能不同。
你的问题很简单,你需要在运行时可配置会话超时时间间隔,并且配置应通过Web界面进行,而不需要重新启动服务器的开销。
我正在扩展Michael的答案以回答你的问题。
逻辑:你需要将配置的值存储在.properties文件或数据库中。在服务器启动时读取存储的值并复制到一个变量中,在服务器运行期间使用该变量。当配置更新时,也更新变量。
就是这样。
解释:
在MyHttpSessionListener类中, 1. 创建一个名为globalSessionTimeoutInterval的静态变量。
  1. 创建一个静态块(仅在第一次访问类时执行),从config.properties文件中读取超时值,并将该值设置为globalSessionTimeoutInterval变量。

  2. 现在使用该值来设置maxInactiveInterval

  3. 现在Web部分,即管理员配置页面

    a. 将配置的值复制到静态变量globalSessionTimeoutInterval中。

    b. 将相同的值写入config.properties文件。 (考虑服务器重新启动后,globalSessionTimeoutInterval将加载config.properties文件中存在的值)

  4. 备用.properties文件或将其存储到数据库中。选择权在您手中。

实现相同逻辑的代码:

public class MyHttpSessionListener implements HttpSessionListener 
{
  public static Integer globalSessionTimeoutInterval = null;

  static
  {
      globalSessionTimeoutInterval =  Read value from .properties file or database;
  }
  public void sessionCreated(HttpSessionEvent event)
  {
      event.getSession().setMaxInactiveInterval(globalSessionTimeoutInterval);
  }

  public void sessionDestroyed(HttpSessionEvent event) {}

}

在您的配置控制器或配置servlet中

String valueReceived = request.getParameter(timeoutValue);
if(valueReceived  != null)
{
    MyHttpSessionListener.globalSessionTimeoutInterval = Integer.parseInt(timeoutValue);
          //Store valueReceived to config.properties file or database
}

直接访问MyHttpSessionListener.globalSessionTimeoutInterval而不进行同步是非常危险的。 - Lluis Martinez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接