Tomcat 会话超时 web.xml
Posted
技术标签:
【中文标题】Tomcat 会话超时 web.xml【英文标题】:Tomcat Session Timeout web.xml 【发布时间】:2012-11-07 22:04:51 【问题描述】:这是我的 web.xml 文件,它位于WEB-INF/lib
。它指定会话超时为 1 分钟,但它不会在用户活动 1 分钟后超时。
Web.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>
我在我的jsp文件中使用了session.getMaxInactiveInterval()
这一行,它输出了1800
(30分钟)。有谁为什么它默认为 30 而不是使用我的 web.xml 文件中指定的时间?
编辑:
我在我的 jsp 页面上有代码检查会话属性,如果确实存在,则在一分钟后将用户重定向到登录页面,即使在页面刷新时,用户也不会被重定向。
if(session.getAttribute("username") != null)
out.println(session.getAttribute("username"));
else
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", "index.jsp");
编辑完整代码(Login.java):
package com.labs.xmlgenerator.controller.managesession;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.labs.xmlgenerator.model.dbconnection.*;
/**
* Servlet implementation class Login
*/
@WebServlet(description = "Verifies Users Credentials", urlPatterns = "/Login" )
public class Login extends HttpServlet
private static final long serialVersionUID = 1L;
private DbLoginQueries query = new DbLoginQueries();
/**
* @see HttpServlet#HttpServlet()
*/
/*
public Login()
super();
// TODO Auto-generated constructor stub
*/
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
try
validateLoginCredentials(request.getParameter("liUsr"),request.getParameter("liPwd"),request,response);
catch (ClassNotFoundException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (SQLException e)
// TODO Auto-generated catch block
e.printStackTrace();
private void validateLoginCredentials (String username, String password, HttpServletRequest request, HttpServletResponse response) throws IOException, ClassNotFoundException, SQLException
Boolean valid = true;
int resultSize;
HashMap<String, String> userDetails = null;
HttpSession session = request.getSession(true);
String location = "index.jsp";
Cookie usernameErrorCookie;
Cookie passwordErrorCookie;
Cookie usernameCookie;
if(username == null || username == "")
valid = false;
usernameErrorCookie = new Cookie("liUsrErrCookie","Please enter a valid username");
response.addCookie(usernameErrorCookie);
else
usernameCookie = new Cookie("liUsrCookie",username);
response.addCookie(usernameCookie);
if(password == null || password == "")
valid = false;
passwordErrorCookie = new Cookie("liPwdErrCookie","Please enter a valid password");
response.addCookie(passwordErrorCookie);
if(valid == true)
userDetails = query.loginQuery(username);
resultSize = userDetails.size();
if(resultSize < 4)
valid = false;
usernameErrorCookie = new Cookie("liUsrErrCookie","The username entered is not valid");
response.addCookie(usernameErrorCookie);
else if(resultSize > 4)
valid = false;
usernameErrorCookie = new Cookie("liUsrErrCookie","The username is returning more than one result, please contact admin");
response.addCookie(usernameErrorCookie);
else if(resultSize == 4)
if(!userDetails.get("Password").equals(password))
valid = false;
passwordErrorCookie = new Cookie("liPwdErrCookie","The entered password is incorrect");
response.addCookie(passwordErrorCookie);
if(valid == true)
session.setAttribute("username", userDetails.get("Username"));
session.setAttribute("permission", userDetails.get("AdminPermissions"));
session.setAttribute("email", userDetails.get("Email"));
location = "home.jsp";
else
location = "index.jsp#login";
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", location);
home.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Home</title>
<link rel="stylesheet" href="resources/css/Common.css" type="text/css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="resources/js/Common.js"></script>
</head>
<body>
<header>
<div id="actionsMenu">
<ul id="actionLinks">
<li><a class="linkButtons" id="userNameLink">
<%
System.out.println(session.getMaxInactiveInterval());
if(session.getAttribute("username") != null)
out.println(session.getAttribute("username"));
else
out.println("no user");
/*
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", "index.jsp");*/
%>
</a></li>
<li><a class="linkButtons" href="Logout">Log Out</a></li>
<li><a class="linkButtons" href="#">Update</a></li>
</ul>
</div>
</header>
<nav class="tabs">
<section id="generateSection">
<h2 class="selectedTab" id="generateTab">
<a id="gene" href="#generateXML">Generate XML</a>
</h2>
<div class="selectedContent" id="generateNav">
<ul id="links">
<li><a class="navLink" href="#graphic">Graphic Interface</a></li>
<li><a class="navLink" href="#xml">XML Interface</a></li>
</ul>
</div>
</section>
<section id="adminSection">
<h2 class="normalTab" id="adminTab">
<a href="#admin">Admin</a>
</h2>
<div class="normalContent" id="adminNav">
<ul id="links">
<li><a class="navLink" href="#images">Manage Images</a></li>
<li><a class="navLink" href="#keywords">Manage Keywords</a></li>
<li><a class="navLink" href="#users">Manage Users</a></li>
</ul>
</div>
</section>
</nav>
<div id="content">
<noscript><p id="javascriptError">This website requires JavaScript to be enabled.</p></noscript>
</div>
<div id="updateUserDetails"></div>
<div id="popup">
<input type="button" value="X" id="exitButton">
<p class="pageTitle" style="float:left; margin:0px;">Update Details</p>
<form id="updateForm" action="Update" onsubmit="return updateValidation()" method="post" >
<p id="user">Username :</p>
<p id="userNameUpdate"><%
if(session.getAttribute("username") != null)
out.println(session.getAttribute("username"));
%></p>
<p class="error" id="updCurrentPwdErr">
<%
Cookie[] currentPassEror = null;
currentPassEror = request.getCookies();
if(currentPassEror != null)
for(int i = 0; i < currentPassEror.length; i++)
Cookie cookie = currentPassEror[i];
if(cookie.getName().equals("updCurrentPwdErrCookie"))
out.println(cookie.getValue());
cookie.setMaxAge(0);
response.addCookie(cookie);
%>
</p>
<label for="updCurrentPwdLbl">Current Password :</label>
<br />
<input type="password" name="updCurrentPwd" id="updCurrentPwd">
<br />
<p class="error" id="updNewPwdErr">
<%
Cookie[] newPassCookies = null;
newPassCookies = request.getCookies();
if(newPassCookies != null)
for(int i = 0; i < newPassCookies.length; i++)
Cookie cookie = newPassCookies[i];
if(cookie.getName().equals("updNewPwdErrCookie"))
out.println(cookie.getValue());
cookie.setMaxAge(0);
response.addCookie(cookie);
%></p>
<label for="updNewPwdLbl">New Password :</label>
<br />
<input type="password" id="updNewPwd" name="updNewPwd">
<br />
<p class="error" id="updReNewPwdErr">
<%
Cookie[] reNewPassCookies = null;
reNewPassCookies = request.getCookies();
if(reNewPassCookies != null)
for(int i = 0; i < reNewPassCookies.length; i++)
Cookie cookie = reNewPassCookies[i];
if(cookie.getName().equals("updReNewPwdErrCookie"))
out.println(cookie.getValue());
cookie.setMaxAge(0);
response.addCookie(cookie);
%>
</p>
<label for="updReNewPwdLbl">Re-Enter New Password :</label>
<br />
<input type="password" id="updReNewPwd" name="updReNewPwd">
<br />
<p class="error" id="updEmailErr">
<%
Cookie[] emailErrCookies = null;
emailErrCookies = request.getCookies();
if(emailErrCookies != null)
for(int i = 0; i < emailErrCookies.length; i++)
Cookie cookie = emailErrCookies[i];
if(cookie.getName().equals("updEmailErrCookie"))
out.println(cookie.getValue());
cookie.setMaxAge(0);
response.addCookie(cookie);
%>
</p>
<label for="updEmailLbl">Email :</label>
<br />
<input type="text" id="updEmail" name="updEmail" value="<%
boolean foundEmailCookie = false;
Cookie[] emailCookies = null;
emailCookies = request.getCookies();
if(emailCookies != null)
for(int i = 0; i < emailCookies.length; i++)
Cookie cookie = emailCookies[i];
if(cookie.getName().equals("updEmailCookie"))
foundEmailCookie = true;
out.println(cookie.getValue());
cookie.setMaxAge(0);
response.addCookie(cookie);
if(!foundEmailCookie)
if(session.getAttribute("email") != null)
out.println(session.getAttribute("email"));
%>">
<input type="hidden" id="updUrl" name="updUrl" value="">
<br />
<input type="submit" value="UPDATE">
</form>
</div>
</body>
</html>
【问题讨论】:
您是否测试过会话是否真的超过 1 分钟? 你确定你使用的是同一个会话吗? @RomanC 我怎么确定? 我想更好的测试方法是使用纯System.out.println("someText")
而不是更改响应数据。如果您想在会话过期时重定向,请使用 request
而不是 response
。
@Colin747 如果您不确定那是您的代码是否按预期正常工作。
【参考方案1】:
会话超时层次结构:
TOMCAT_HOME/conf/web.xml WebApplication/webapp/WEB-INF/web.xml 在 Java 中硬编码会话超时:HttpSession.setMaxInactiveInterval(int)会话超时配置顺序:
HttpSession.setMaxInactiveInterval(int) > $WebApplication/webapp/WEB-INF/web.xml
> $TOMCAT_HOME/conf/web.xml
每个后续条目都会覆盖上述配置。
最好的问候。
【讨论】:
【参考方案2】:web.xml
应该直接在WEB-INF
中,而不是在 WEB-INF/lib 中。
【讨论】:
部署文件夹下,因为可能有很多地方存在。【参考方案3】:一分钟是非常低的会话超时。应该是几个小时。
超时发生在那么多不活动之后,没有那么多活动。
正确的测试是request.getSession(false) == null
,或request.getSession(true).isNew()
。
【讨论】:
我知道它处于不活动状态。时间短得离谱,所以我可以测试它而无需等待大量时间。我现在就试试你的解决方案。 您能否更详细地描述您的解决方案? @Colin747 解决方案在#3。我什至给了你代码。不确定您可能还需要什么。 几个小时是一个高得离谱的会话超时:1)您将为那些只需关闭选项卡而不是注销的用户存储更多的会话上下文(使用太多内存)。 2)就安全性而言,这是一个非常糟糕的主意。 15 - 30 分钟很划算 @Anthony 这对用户来说是一件很痛苦的事情。我与几个主要供应商打交道,其中一个网站的超时时间为一两个小时,我可以向您保证,我会尽可能使用另一个。【参考方案4】:如果您的目标是测试会话到期,您根本不必等待。您的应用程序服务器可能会提供一种手动使会话过期的方式。例如,在Tomcat
中,您可以通过管理器应用程序执行此操作。每个应用程序旁边都有一个“过期会话”按钮,旁边有一个字段,您可以在其中指定空闲时间阈值。所有空闲时间超过阈值的会话都将失效。要使所有会话无效,只需输入0
并按回车键;无论web.xml
中的值如何,所有会话都将过期。
如果您不使用 Tomcat,请查看应用程序服务器的文档,您可能会通过管理控制台或命令行找到一种方法。
【讨论】:
以上是关于Tomcat 会话超时 web.xml的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring Boot 嵌入式 tomcat 设置会话超时
部署到 Tomcat 时,Grails 3 会话超时不起作用