web.xml中的会话超时

70

我正试图理解Web.xml中会话配置在会话超时方面的真实目的。

<!-- Session Configuration -->
<session-config>
        <session-timeout>60</session-timeout>
</session-config>

现在让我告诉你我的问题。

我的应用程序正在导入/上传一个 .txt 文件,这将需要超过1小时的时间,因为有数百万条记录需要导入。 但是会话在1小时后超时,尽管我的应用程序仍在导入该正在进行中的 .txt 文件。 这样的应用程序不应该超时,因为应用程序正在后台执行一些任务。


在session-timeout标签中增加您的数字。如果您有任何问题,请与我联系。谢谢。 - Adalarasan_Serangulam
7
如果有任何进程正在运行,我认为会话不会过期。只有当应用程序空闲一段时间后,会话才会过期。如果有一些后台进程在运行,你的应用程序就不是空闲状态。 - Jeevan Patil
4
我不确定你的应用程序导入如何工作。 如果应用程序正在等待I / O完成,则肯定处于空闲状态并将超时。 - Joe2013
你在客户端设置了一个JavaScript定时器来请求60分钟后的注销页面吗?如果是这样,你需要在开始上传之前禁用它。 - jt.
只需要一个简单的计时器,每10分钟轮询一次网站,一个Servlet什么也不做,只返回一个真/假的心跳值。然后一旦您的文档上传完成,就可以移除计时器了。 - user3586195
9
我想知道为什么在答案中没有人提到这可能是设计缺陷的问题。如果您正在进行如此长时间的处理,很可能没有理由将其与用户会话耦合。将文件上传到服务器,然后异步处理它即可。 - JanM
12个回答

47

设置一个从不过期的会话超时时间并不理想,因为你会依赖用户在每次完成操作后按下注销按钮以防止服务器负载过大(这取决于用户数量和硬件)。此外,您可能会遇到一些安全问题,最好是避免。

会话在服务器仍在处理任务时失效的原因是客户端(用户浏览器)与服务器端之间没有通过例如http请求进行通信。 因此,服务器无法了解用户的状态,认为他正在空闲,并在web.xml中设置的时间后使会话无效。

为了解决这个问题,您有几种可能性:

  • 您可以在任务运行时对后端进行“ping”操作以触摸会话并防止其过期
  • 增加服务器内部的<session-timeout>,但我不建议这样做
  • 在专用线程中运行任务,该线程在工作时会扩展会话或在线程完成时通知用户

曾经有人问过类似的问题,也许您可以在项目中使用此解决方案的某些部分。请参考此网页.

希望这可以帮助您,祝您愉快!


3
请注意,用户登录和会话是两个独立的事情。通常情况下Servlets没有“注销”功能。服务器需要一个“注销”页面,明确调用_HttpSession_的 invalidate() 方法。 - David Balažic

40
<session-config>
    <session-timeout>-1</session-timeout>
</session-config>
您可以使用“-1”表示会话永不过期。因为您不知道线程完成需要多长时间。

2
@PeakGen:请友善一些,不要只是反对。所以它会过期?多久后会过期? - zb226
@zb226:在发表评论之前,请确保检查帖子的日期 :) - PeakGen
2
@PeakGen:我认为线程日期并不重要。其他信息可能更相关。 - zb226
@zb226: 线程日期是相关的,因为我甚至都记不起这个问题是什么了。无论如何,我真的没有时间争论3年前的记录,如果你想把这个用户的答案视为正确的,那就没问题,完全由你决定。 - PeakGen
9
我非常赞同@zb226的观点,即评论“错误,会话已过期”并没有提供足够的信息。会话何时过期?你基于什么做出这个观察?尽管这些答案已经几年了,但人们现在仍然参考这些答案! - skrii
如果会话永不过期,它们会释放线程吗?线程会被垃圾回收吗?增长的线程会占用内存吗? - magicbacon

9

通过javascript定期向服务器发送AJAX HTTP请求(例如每60秒一次),以保持与服务器的会话,直到文件上传完成。


9

非正规的方法:

当预计需要大量上传/下载时,您可以通过编程方式增加会话超时时间。

session.setMaxInactiveInterval(TWO_HOURS_IN_SECONDS)

当进程结束时,您可以将超时设置回默认值。
但是...当您使用Java EE时,如果上传/下载不需要完整一小时,更好的方法是通过异步方式运行任务(例如通过JMS)。

9

您可以看到许多选项作为您问题的答案,但是您可以使用“-1”来表示会话永不过期。因为您不知道线程需要多长时间才能完成。例如:

   <session-config>
        <session-timeout>-1</session-timeout>
    </session-config>

如果您不希望出现超时等待的情况:

<session-config>
    <session-timeout>0</session-timeout>
</session-config>

另一个选项可能是将数量增加到1000,等等,嘟嘟嘟。

但是,如果您真的想停止,并且您认为强制用户注销对于您的应用来说是不必要的,只需添加注销按钮,用户将决定何时离开。

如果您不需要强制注销,并且正在加载可能基于服务器和计算机速度以及文件大小而花费时间的文件,则可以执行以下操作来解决问题。

<!-- sets the default session timeout to 60 minutes. -->
   <!-- <session-config>
     <session-timeout>60</session-timeout>
   </session-config> -->

只需注释或删除它即可!Tan tararantan,tan tan!


(注:该文本已经是中文,无需翻译)

8
0和-1之间有区别吗? - efirat

8
<session-config>
        <session-timeout>-1</session-timeout>
</session-config>

在上述代码中,"60"代表分钟数。会话在60分钟后过期。因此,如果您需要更多的时间,例如-1,那么会话将永不过期。

问题是,尽管会话处于活动状态(正在进行某些操作),但为什么会在 60 分钟后过期? - Suresh Atta

6
文档中写道:

session-timeout元素定义了此Web应用程序中创建的所有会话的默认会话超时间隔。指定的超时时间必须以整分钟为单位表示。如果超时时间为0或更少,容器将确保会话的默认行为永远不会超时。如果未指定此元素,则容器必须设置其默认超时期。


3
你可以通过两种方式声明时间来解决这个问题。
1) 给予足够长的时间,确保你的文件读取在这段时间内完成。
<session-config>
    <session-timeout> 1000 </session-timeout>
</session-config>

2) 声明一个永不过期的会话时间。

<session-config>
    <session-timeout>-1</session-timeout>
</session-config>

1
这是一个不错的提示。非常感谢 +1 - Khanh Tran

1

我建议的另一个选项是创建一个无状态的单独应用程序,该应用程序将接收大文件。在您的主应用程序中打开一个新窗口或iframe,以接收文件并通过该窗口发送文件,然后使用Javascript隐藏窗口或iframe一旦上传已经开始。


0
你应该考虑将大文件分成块,并依靠多线程能力来同时处理多个文件, 或者 让整个过程作为后台任务运行,使用TimerTask,并编写另一个查询来了解它的状态,包括进度条,如果您可以知道文件或记录的处理时间。

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