You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebClient如何获取服务端响应的Session Cookie用于后续请求

WebClient 会话保持实现方案

Spring WebClient 默认不会自动持久化响应返回的 Cookie,你可以根据需求选择以下两种方案实现认证后的会话保持:


方案1:开启自动Cookie管理(推荐)

直接给 WebClient 绑定支持Cookie存储的Reactor Netty客户端,同域名下的Cookie会自动存储、自动携带,完全不需要手动解析和写入请求头,代码可维护性最高。

import io.netty.handler.codec.http.cookie.ClientCookieDecoder;
import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.client.cookie.InMemoryCookieStore;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

// 初始化全局复用的WebClient实例,不要每次请求都新建
HttpClient httpClient = HttpClient.create()
        .responseTimeout(Duration.ofSeconds(10))
        // 配置Cookie编解码和内存存储
        .cookieCodec(ServerCookieEncoder.STRICT, ClientCookieDecoder.STRICT)
        .cookieStore(new InMemoryCookieStore());

WebClient webClient = WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .build();

// 认证请求:正常携带x-api-key发起请求即可,认证成功返回的Session Cookie会自动存入内存
String authResp = webClient.get()
        .uri("http://localhost:8081/authenticate")
        .header("x-api-key", "123456789")
        .accept(MediaType.APPLICATION_JSON)
        .retrieve()
        .bodyToMono(String.class)
        .block();

Map<String, Object> query = new HashMap<>();
query.put("collection", "student");
// 查询请求:无需手动加Cookie头,客户端会自动把之前存储的Session Cookie带过去
String queryResp = webClient.post()
        .uri("http://localhost:8081/query")
        .contentType(MediaType.APPLICATION_JSON)
        .body(BodyInserters.fromValue(query))
        .retrieve()
        .bodyToMono(String.class)
        .block();

方案2:手动提取并写入Cookie

如果你需要自定义Cookie处理逻辑(比如持久化Cookie到外部存储、打印调试Cookie内容),可以手动从认证响应的Set-Cookie头中提取会话标识,再写入后续请求的Cookie头中。

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

WebClient webClient = WebClient.builder().build();
// 用数组存Cookie值,适配lambda的变量只读要求
final String[] sessionCookie = {null};

String authResp = webClient.get()
        .uri("http://localhost:8081/authenticate")
        .header("x-api-key", "123456789")
        .accept(MediaType.APPLICATION_JSON)
        // 从响应中提取Set-Cookie头
        .exchangeToMono(response -> {
            List<String> cookieHeaders = response.headers().get(HttpHeaders.SET_COOKIE);
            if (cookieHeaders != null && !cookieHeaders.isEmpty()) {
                // 截取Cookie键值对,去掉Path、HttpOnly、过期时间等属性
                // 如果有多个有效Cookie,遍历后用分号拼接即可
                sessionCookie[0] = cookieHeaders.get(0).split(";")[0];
            }
            return response.bodyToMono(String.class);
        })
        .block();

Map<String, Object> query = new HashMap<>();
query.put("collection", "student");
String queryResp = webClient.post()
        .uri("http://localhost:8081/query")
        .contentType(MediaType.APPLICATION_JSON)
        // 手动写入Cookie头
        .header(HttpHeaders.COOKIE, sessionCookie[0])
        .body(BodyInserters.fromValue(query))
        .retrieve()
        .bodyToMono(String.class)
        .block();

注意事项

  • 优先选择自动Cookie管理方案,手动处理时需要自行适配Cookie的作用域、过期时间、Path匹配规则,容易遗漏逻辑导致会话失效
  • WebClient实例建议全局单例复用,频繁新建实例会导致Cookie存储随实例销毁,无法实现会话保持

内容的提问来源于stack exchange,提问作者Aws AbuObeid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 02:46:12