无状态HTTP的“记忆”方案核心原理

HTTP协议本身是无状态的,但通过Cookie和Session机制可实现状态保持。Cookie是客户端存储的小型文本数据,Session是服务端存储的用户会话数据,二者常结合使用。

Spring Boot中Cookie的实现

在Controller中通过HttpServletResponse添加Cookie:

@GetMapping("/setCookie")
public String setCookie(HttpServletResponse response) {
    Cookie cookie = new Cookie("user", "JohnDoe");
    cookie.setMaxAge(3600); // 1小时有效期
    cookie.setPath("/");
    response.addCookie(cookie);
    return "Cookie set";
}

读取Cookie通过HttpServletRequest

@GetMapping("/getCookie")
public String getCookie(@CookieValue(value = "user", defaultValue = "") String user) {
    return "Cookie value: " + user;
}

Spring Session配置与使用

添加Maven依赖:

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-core</artifactId>
</dependency>

配置Redis作为Session存储:

spring:
  session:
    store-type: redis
    timeout: 1800s
  redis:
    host: localhost
    port: 6379

在Controller中操作Session:

@PostMapping("/login")
public String login(HttpSession session, @RequestParam String username) {
    session.setAttribute("user", username);
    return "Logged in";
}

@GetMapping("/profile")
public String profile(HttpSession session) {
    String user = (String) session.getAttribute("user");
    return "Current user: " + user;
}

Cookie与Session的联合作战方案

实现自动登录功能时组合使用:

@PostMapping("/autoLogin")
public String autoLogin(HttpServletRequest request, HttpServletResponse response, 
                       @RequestParam String username) {
    // Session存储核心信息
    request.getSession().setAttribute("user", username);
    
    // Cookie存储辅助标识
    Cookie cookie = new Cookie("REMEMBER_ME", UUID.randomUUID().toString());
    cookie.setMaxAge(2592000); // 30天
    response.addCookie(cookie);
    
    return "Auto login configured";
}

安全增强策略

设置安全Cookie属性:

Cookie cookie = new Cookie("SECURE_ID", token);
cookie.setHttpOnly(true);
cookie.setSecure(true); // 仅HTTPS
cookie.setPath("/api");

Session固定攻击防护:

@Configuration
public class SessionConfig implements HttpSessionIdResolver {
    @Override
    public List<String> resolveSessionIds(HttpServletRequest request) {
        return Collections.singletonList(request.getSession().getId());
    }
}

分布式环境解决方案

使用Spring Session实现跨服务共享:

@EnableRedisHttpSession 
public class SessionConfig {
    @Bean
    public RedisConnectionFactory connectionFactory() {
        return new LettuceConnectionFactory(); 
    }
}

自定义Session序列化:

@Bean
public RedisSerializer<Object> springSessionSerializer() {
    return new GenericJackson2JsonRedisSerializer();
}

性能优化技巧

Cookie压缩策略:

Cookie cookie = new Cookie("COMPRESSED", Base64.getEncoder().encodeToString(gzipCompress(data)));

Session数据最小化:

session.setAttribute("user", new MiniUserDTO(id, name));

异步Session存储配置:

spring:
  session:
    redis:
      flush-mode: on_save
      save-mode: on_get_attribute

监控与调试方案

通过Actuator监控Session:

management:
  endpoints:
    web:
      exposure:
        include: sessions

日志跟踪Session生命周期:

@EventListener
public void sessionCreated(SessionCreatedEvent event) {
    log.info("Session created: {}", event.getSessionId());
}

以上方案完整实现了从基础应用到高级场景的无状态HTTP状态管理,兼顾了功能实现与系统安全,适合在各种复杂度的Spring Boot项目中实施。

更多推荐