本文目录导读:

我来提供一个完整的Java会话管理案例,包括登录、会话跟踪和登出功能。
Servlet会话管理示例
项目结构
session-management/
├── src/
│ └── com/example/
│ ├── LoginServlet.java
│ ├── LogoutServlet.java
│ ├── DashboardServlet.java
│ └── SessionListener.java
└── web/
└── WEB-INF/
└── web.xml
LoginServlet.java
package com.example;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
// 模拟用户数据库
private static final String VALID_USERNAME = "admin";
private static final String VALID_PASSWORD = "password123";
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 验证用户凭据
if (VALID_USERNAME.equals(username) && VALID_PASSWORD.equals(password)) {
// 获取或创建会话
HttpSession session = request.getSession(true);
// 设置会话属性
session.setAttribute("username", username);
session.setAttribute("loginTime", System.currentTimeMillis());
session.setAttribute("role", "USER");
// 设置会话超时时间(秒)
session.setMaxInactiveInterval(30 * 60); // 30分钟
// 重定向到仪表板
response.sendRedirect("dashboard");
} else {
// 登录失败
request.setAttribute("errorMessage", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 显示登录页面
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
DashboardServlet.java
package com.example;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/dashboard")
public class DashboardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取会话
HttpSession session = request.getSession(false);
// 检查用户是否已登录
if (session == null || session.getAttribute("username") == null) {
// 未登录,重定向到登录页面
response.sendRedirect("login");
return;
}
// 用户已登录,显示仪表板
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String username = (String) session.getAttribute("username");
long loginTime = (long) session.getAttribute("loginTime");
String role = (String) session.getAttribute("role");
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>用户仪表板</title>");
out.println("<style>");
out.println("body { font-family: Arial, sans-serif; margin: 40px; }");
out.println(".session-info { background: #f0f0f0; padding: 20px; border-radius: 5px; }");
out.println("</style>");
out.println("</head>");
out.println("<body>");
out.println("<h1>欢迎," + username + "!</h1>");
out.println("<div class='session-info'>");
out.println("<h2>会话信息</h2>");
out.println("<p>用户名: " + username + "</p>");
out.println("<p>角色: " + role + "</p>");
out.println("<p>登录时间: " + new java.util.Date(loginTime) + "</p>");
out.println("<p>会话ID: " + session.getId() + "</p>");
out.println("<p>会话超时时间: " + session.getMaxInactiveInterval() + " 秒</p>");
out.println("</div>");
out.println("<br>");
out.println("<a href='logout'>退出登录</a>");
out.println("</body>");
out.println("</html>");
}
}
LogoutServlet.java
package com.example;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取会话(不创建新会话)
HttpSession session = request.getSession(false);
if (session != null) {
// 清除所有会话属性
session.invalidate(); // 使会话失效
}
// 重定向到登录页面
response.sendRedirect("login");
}
}
SessionListener.java
package com.example;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class SessionListener implements HttpSessionListener {
private static int activeSessions = 0;
@Override
public void sessionCreated(HttpSessionEvent se) {
activeSessions++;
System.out.println("会话创建 - 当前活跃会话数: " + activeSessions);
System.out.println("会话ID: " + se.getSession().getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
activeSessions--;
System.out.println("会话销毁 - 当前活跃会话数: " + activeSessions);
System.out.println("会话ID: " + se.getSession().getId());
// 清理会话相关的资源
HttpSession session = se.getSession();
String username = (String) session.getAttribute("username");
if (username != null) {
System.out.println("用户 " + username + " 已登出");
}
}
public static int getActiveSessions() {
return activeSessions;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Session Management Demo</display-name>
<!-- 全局会话超时设置(分钟) -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- 欢迎页面 -->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
登录页面 (login.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">用户登录</title>
<style>
body { font-family: Arial, sans-serif; margin: 50px; }
.login-form {
width: 300px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
}
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; }
input[type="text"], input[type="password"] {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
.error { color: red; margin-bottom: 10px; }
button {
background: #4CAF50;
color: white;
padding: 10px 15px;
border: none;
cursor: pointer;
width: 100%;
}
button:hover { background: #45a049; }
</style>
</head>
<body>
<div class="login-form">
<h2>用户登录</h2>
<% if(request.getAttribute("errorMessage") != null) { %>
<div class="error"><%= request.getAttribute("errorMessage") %></div>
<% } %>
<form action="login" method="post">
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">登录</button>
</form>
<p style="text-align: center; margin-top: 15px;">
默认账号: admin / password123
</p>
</div>
</body>
</html>
使用Spring Boot的会话管理
Spring Boot应用配置
// 在application.properties中配置 server.servlet.session.timeout=30m server.servlet.session.cookie.name=MYAPP_SESSIONID server.servlet.session.cookie.http-only=true server.servlet.session.cookie.secure=true server.servlet.session.tracking-modes=cookie
Spring Security配置示例
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.session.HttpSessionEventPublisher;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login", "/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.sessionManagement()
.maximumSessions(1) // 每个用户最多一个会话
.maxSessionsPreventsLogin(false) // 允许新登录,使旧会话失效
.expiredUrl("/login?expired");
}
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
}
关键会话管理最佳实践
安全建议
// 1. 创建会话后的安全设置
public static void secureSession(HttpSession session) {
// 生成新的会话ID(防止会话固定攻击)
session.invalidate(); // 使旧会话失效
session = session.getRequest().getSession(true); // 创建新会话
// 设置会话属性
session.setAttribute("user", user);
session.setAttribute("ipAddress", request.getRemoteAddr());
session.setAttribute("userAgent", request.getHeader("User-Agent"));
}
// 2. 验证会话上下文
public static boolean validateSession(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) return false;
String storedIp = (String) session.getAttribute("ipAddress");
String currentIp = request.getRemoteAddr();
String storedAgent = (String) session.getAttribute("userAgent");
String currentAgent = request.getHeader("User-Agent");
// 验证IP和User-Agent是否变化
return storedIp != null && storedIp.equals(currentIp) &&
storedAgent != null && storedAgent.equals(currentAgent);
}
// 3. 会话失效处理
public static void invalidateSession(HttpSession session) {
if (session != null) {
// 清除所有属性
Enumeration<String> attributeNames = session.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String attributeName = attributeNames.nextElement();
session.removeAttribute(attributeName);
}
// 使会话失效
session.invalidate();
}
}
这个示例展示了Java中会话管理的核心概念,包括:
- 创建和销毁会话
- 会话属性管理
- 会话超时控制
- 会话监听器
- 安全最佳实践
- Spring Boot集成示例
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播