本文目录导读:

- 原生Servlet(JSP/Servlet)
- Spring MVC
- Spring Boot
- 使用Spring Session(分布式Session)
- 安全获取Session数据的最佳实践
- Session数据操作示例(完整流程)
- 注意事项
在Java中获取Session数据主要取决于你使用的框架(如Servlet、Spring MVC、Spring Boot等),以下是几种常见场景的实现方式:
原生Servlet(JSP/Servlet)
在Servlet中获取
@WebServlet("/example")
public class ExampleServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
// 获取Session
HttpSession session = request.getSession();
// 获取Session中的数据
String username = (String) session.getAttribute("username");
Integer age = (Integer) session.getAttribute("age");
// 获取所有属性名
java.util.Enumeration<String> attributeNames = session.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String name = attributeNames.nextElement();
Object value = session.getAttribute(name);
}
}
}
在JSP中获取
<%-- 使用表达式 --%>
用户名:<%= session.getAttribute("username") %>
<%-- 使用EL表达式 --%>
用户名:${sessionScope.username}
<%-- 使用JSTL --%>
<c:out value="${sessionScope.username}" />
Spring MVC
在Controller中获取
@Controller
public class UserController {
// 方式1:通过HttpServletRequest
@GetMapping("/getSession1")
public String getSession1(HttpServletRequest request) {
HttpSession session = request.getSession();
String username = (String) session.getAttribute("username");
return "success";
}
// 方式2:直接注入HttpSession
@GetMapping("/getSession2")
public String getSession2(HttpSession session) {
String username = (String) session.getAttribute("username");
return "success";
}
// 方式3:使用@SessionAttribute注解
@GetMapping("/getSession3")
public String getSession3(@SessionAttribute("username") String username) {
System.out.println("用户名:" + username);
return "success";
}
}
Spring Boot
使用注解方式
@RestController
public class SessionController {
// 方式1:直接使用HttpSession
@GetMapping("/getData")
public String getData(HttpSession session) {
String username = (String) session.getAttribute("username");
return "Hello, " + username;
}
// 方式2:使用@SessionAttribute
@GetMapping("/getData2")
public String getData2(@SessionAttribute("username") String username) {
return "Hello, " + username;
}
// 方式3:使用@SessionAttributes在类级别
@GetMapping("/getData3")
public String getData3(Model model) {
// 如果类上使用了@SessionAttributes,model会自动同步到session
String username = (String) model.getAttribute("username");
return "Hello, " + username;
}
}
// 配合@SessionAttributes使用
@Controller
@SessionAttributes("username")
public class SessionAttributesController {
@GetMapping("/login")
public String login(Model model) {
model.addAttribute("username", "张三");
return "redirect:/home";
}
}
使用Spring Session(分布式Session)
配置Redis存储Session
// 添加依赖
// spring-session-data-redis
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class RedisSessionConfig {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
}
// 获取Session方式不变
@RestController
public class SessionController {
@GetMapping("/getData")
public String getData(HttpSession session) {
String username = (String) session.getAttribute("username");
return "Hello, " + username;
}
}
安全获取Session数据的最佳实践
使用Optional避免空指针
public class SessionUtil {
public static String getSessionAttribute(HttpSession session, String key) {
return Optional.ofNullable(session)
.map(s -> (String) s.getAttribute(key))
.orElse("");
}
// 通用方法
public static <T> T getAttribute(HttpSession session, String key, Class<T> type) {
return Optional.ofNullable(session)
.map(s -> s.getAttribute(key))
.filter(type::isInstance)
.map(type::cast)
.orElse(null);
}
}
// 使用示例
HttpSession session = request.getSession(false);
String username = SessionUtil.getAttribute(session, "username", String.class);
封装Session工具类
@Component
public class SessionManager {
private final HttpSession session;
@Autowired
public SessionManager(HttpSession session) {
this.session = session;
}
public <T> T get(String key) {
return (T) session.getAttribute(key);
}
public void set(String key, Object value) {
session.setAttribute(key, value);
}
public boolean exists(String key) {
return session.getAttribute(key) != null;
}
public void remove(String key) {
session.removeAttribute(key);
}
public void clear() {
session.invalidate();
}
}
// 使用
@RestController
public class DemoController {
@Autowired
private SessionManager sessionManager;
@GetMapping("/demo")
public String demo() {
String username = sessionManager.get("username");
return "Hello, " + username;
}
}
Session数据操作示例(完整流程)
@RestController
@RequestMapping("/user")
public class UserController {
// 保存Session数据
@PostMapping("/login")
public String login(@RequestParam String username, HttpSession session) {
// 设置Session属性
session.setAttribute("username", username);
session.setAttribute("loginTime", new Date());
session.setMaxInactiveInterval(3600); // 设置过期时间1小时
return "登录成功";
}
// 获取Session数据
@GetMapping("/info")
public UserInfo getUserInfo(HttpSession session) {
UserInfo info = new UserInfo();
info.setUsername((String) session.getAttribute("username"));
info.setLoginTime((Date) session.getAttribute("loginTime"));
info.setSessionId(session.getId());
info.setCreationTime(new Date(session.getCreationTime()));
info.setLastAccessedTime(new Date(session.getLastAccessedTime()));
info.setMaxInactiveInterval(session.getMaxInactiveInterval());
return info;
}
// 清除Session数据
@PostMapping("/logout")
public String logout(HttpSession session) {
// 移除单个属性
session.removeAttribute("username");
// 或者使session失效
// session.invalidate();
return "已退出登录";
}
}
// 用户信息类
class UserInfo {
private String username;
private Date loginTime;
private String sessionId;
private Date creationTime;
private Date lastAccessedTime;
private int maxInactiveInterval;
// getters and setters 省略...
}
注意事项
- 空指针处理:在获取Session前检查
request.getSession(false)是否为null - 线程安全:Session不是线程安全的,避免在并发环境下同时修改
- 内存考虑:不要存储大量数据到Session中,避免内存溢出
- 序列化:存储在Session中的对象需要实现
Serializable接口 - 性能优化:尽量减少Session中的数据量和访问频率
// 安全获取Session示例
public HttpSession getSessionSafe(HttpServletRequest request) {
return request.getSession(false); // false表示如果不存在不创建
}
// 使用
HttpSession session = getSessionSafe(request);
if (session != null) {
String username = (String) session.getAttribute("username");
}
根据你的具体框架和需求选择合适的方式即可,Spring Boot项目推荐使用HttpSession直接注入或@SessionAttribute注解的方式。