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

Posted

技术标签:

【中文标题】如何在 Java Web 应用程序中动态设置会话超时?【英文标题】:How to set session timeout dynamically in Java web applications? 【发布时间】:2011-02-26 23:51:44 【问题描述】:

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

有没有办法以编程方式设置会话超时,以便我可以使用 ServletContextListener.contextInitialized() 来读取配置的间隔并在应用程序启动时设置它?

【问题讨论】:

【参考方案1】:

不要使用 ServletContextListener,而是使用 HttpSessionListener

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>

【讨论】:

有没有办法将静态 15*60 替换为从网页传递到 http 侦听器的变量(以便选择会影响所有新创建的会话的超时?)? 虽然我看到很多赞成票,但这真的可靠吗?会话管理器(我看到的一个自定义)在调用侦听器之前将会话保存在持久性中。并且在保存会话时已经设置了超时。所以我不确定如何在保存后设置值会导致会话值根据编程设置过期【参考方案2】:

有没有办法以编程方式设置会话超时

设置会话超时值基本上有三种方式:

使用标准web.xml文件中的session-timeout~or~ 在没有此元素的情况下,通过获取服务器的默认session-timeout 值(并因此在服务器级别对其进行配置)~or~ 通过在您的 Servlet 或 JSP 中使用HttpSession. setMaxInactiveInterval(int seconds) 方法以编程方式进行。

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

【讨论】:

【参考方案3】:

正如另一个回答者所说,您可以更改会话侦听器。但是,例如,您可以直接在 servlet 中更改它。

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

【讨论】:

是的,这是可能的,但是它不能保证它“何时”发生..并且取决于您的 servlet 的生命周期..这是一个选项..好的.. Nore:侦听器将设置它总是在创建事件。【参考方案4】:
我需要为我的用户提供一个 Web 界面来更改会话超时间隔。因此,Web 应用程序的不同安装可以有不同的会话超时,但它们的 web.xml 不能不同。

您的问题很简单,您需要在运行时配置会话超时间隔,并且应该通过 Web 界面完成配置,并且不应该有重新启动服务器的开销。

我正在扩展 Michaels 的答案以解决您的问题。

逻辑:您需要将配置值存储在 .properties 文件或数据库中。在服务器启动时读取存储的值并复制到一个变量,使用该变量直到服务器启动。随着配置的更新,也更新了变量。 就是这样。

解释

在 MyHttpSessionListener 类中 1. 创建一个名为 globalSessionTimeoutInterval 的静态变量。

    创建一个静态块(仅在第一次访问类时执行)并从 config.properties 文件中读取超时值并将值设置为 globalSessionTimeoutInterval 变量。

    现在使用该值设置 maxInactiveInterval

    现在是 Web 部分,即管理配置页面

    一个。将配置的值复制到静态变量 globalSessionTimeoutInterval。

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

    替代 .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 非常危险。

以上是关于如何在 Java Web 应用程序中动态设置会话超时?的主要内容,如果未能解决你的问题,请参考以下文章

Java web 会话技术 cookie与session

Java Web学习总结Cookie/Session

Tomcat会话超时时怎样记录操作日志,满足安全审计要求

Java Web 应用程序中的会话过期时如何重定向到登录页面?

java的框架struts2的Action如何接收超链接的参数

Java JPA:如何跨 HTTP 请求保持会话活动?