Forest Forest
💒 首页
  • v1.5.30
  • v1.5.28
  • 🎄 ForestX
🌰 案例
💖 支持
🛫 更新记录
🧢 开发团队
⚒️ 参与贡献
  • MaxKey - 业界领先的身份管理和认证产品 (opens new window)
  • Snowy - 国内首个国密前后端分离快速开发平台 (opens new window)
  • Eoapi - 一个开源、可拓展的 API 工具平台 (opens new window)
  • Gitee (opens new window)
  • Github (opens new window)
💒 首页
  • v1.5.30
  • v1.5.28
  • 🎄 ForestX
🌰 案例
💖 支持
🛫 更新记录
🧢 开发团队
⚒️ 参与贡献
  • MaxKey - 业界领先的身份管理和认证产品 (opens new window)
  • Snowy - 国内首个国密前后端分离快速开发平台 (opens new window)
  • Eoapi - 一个开源、可拓展的 API 工具平台 (opens new window)
  • Gitee (opens new window)
  • Github (opens new window)
  • 序言

    • 🎁 新手介绍
    • 📖 文档
    • 🌰 使用案例
    • 🕵️‍ 关于作者
    • 👨‍🎓 贡献者列表
  • 入门

    • 🎬 安装配置说明
    • 🏹 Springboot环境安装
    • 📐 Springboot环境配置
    • 🎯 Springboot环境使用
    • 🏹 Springboot3环境安装
    • 📐 Springboot3环境配置
    • 🎯 Springboot3环境使用
    • 🏹 Spring环境安装
    • 📐 Spring环境配置
    • 🎯 Spring环境使用
    • 🏹 Solon环境安装
    • 📐 Solon环境配置
    • 🎯 Solon环境使用
    • 🏹 原生Java环境安装
    • 📐 原生Java环境配置
    • 🎯 原生Java环境使用
    • 🧬 编程式接口
  • 配置项

    • 👜 Springboot环境配置项
    • 👝 Spring环境配置项
    • 👜 Solon环境配置项
    • 🎒 原生Java环境配置项
    • 📚 配置优先级/作用域
  • 声明式接口

    • 🧱 构建接口
    • 🍀 请求方法
    • 🚚 请求地址
    • 🎈 URL 参数
    • 🍭 请求头
    • 👔 请求体
    • 🍮 后端框架
    • 🧁 接口注解
    • 📬 接收数据
    • 🍛 数据转换
    • 🍓 成功/失败条件
    • 🍌 重试机制
    • 🥂 重定向
    • 🍔 Gzip解压
    • 🎂 日志管理
    • ⚽ 回调函数
    • 🍟 异步请求
    • 🛡️ HTTPS
    • 🍪 使用Cookie
      • 回调函数方式
      • 拦截器方式
      • 严格匹配模式 (v1.5.25)
    • 🛸 使用代理
    • 🍉 上传下载
    • 🚑 异常处理
  • 编程式接口

    • 请求API

      • 🚀 请求对象
      • 🚢 请求属性
      • ✨ 执行请求
      • 🎊 后端框架
      • 🎪 请求类型
      • 🔮 请求地址
      • 🧀 URL 参数
      • 🚅 请求头
      • 🚋 请求体
      • ⚓ 回调函数
      • 🚁 异步请求
      • 🥯 Cookie
      • 🍜 成功/失败条件
      • 🌶️ 重试机制
      • ⛵ 重定向
      • 🛰️ 请求代理
    • 响应API

      • 🌠 响应对象
      • ✒️ 读取数据
      • 🦋 响应状态码
      • 🏥 响应错误处理
      • 🎧 响应头
      • 🥞 Cookie
  • 模板表达式

    • 🍬 Hello World
    • 🍹 配置属性引用
    • 🍖 变量引用
    • 🥃 动态变量绑定
    • 🥗 参数序号引用
    • 🍍 引用对象属性
    • 🥝 调用对象方法
  • 高级特性

    • 🥪 拦截器
    • 🍏 自定义注解
    • 🍇 组合注解
    • 🥑 自定义转换器
  • v1.5.30文档
  • 声明式接口
公子骏
2022-07-01
目录

🍪 使用Cookie

Cookie是由服务器端生成,发送给客户端(一般为浏览器),并以key-value形式处理和保存在客户端的一组数据。在下次请求同一域名网站时,会将该Cookie数据再次发送到服务端。

Forest从1.5.0-RC1版本开始支持Cookie,可以通过回调函数和拦截器两种方式来处理Cookie。

# 回调函数方式

在请求接口的参数列表中加入OnSaveCookie 和 OnLoadCookie 回调函数

OnSaveCookie: 在请求响应成功后,需要保存Cookie时调用该回调函数

OnLoadCookie: 在发送请求前,需要加载Cookie时调用该回调函数


/**
 * 登入接口(需要接受Cookie)
 */
@Post("http://localhost:8080/login?username=foo")
ForestResponse testLogin(@Body UserLoginDTO userLogin, OnSaveCookie onSaveCookie);

/**
 * 登入后测试接口(需要传入Cookie)
 */
@Post("http://localhost:8080/test")
ForestResponse testAfterLogin(OnLoadCookie onLoadCookie);

1
2
3
4
5
6
7
8
9
10
11
12
13

Forest不会自动处理或持久化服务端传来的Cookie数据,需要自己在回调函数中接到Cookie后自行处理。


AtomicReference<ForestCookie> cookieAtomic = new AtomicReference<>(null);

// 调用登入接口
testClient.testLogin(userLogin, (request, cookies) -> {
    // 将服务端传来的Cookie放入cookieAtomic
    cookieAtomic.set(cookies.allCookies().get(0));
});

// 获取Cookie
ForestCookie cookie = cookieAtomic.get();

// 调用登入后的测试接口
ForestResponse response = testClient.testAfterLogin((request, cookies) -> {
    // 将之前调用登入接口获得的Cookie传入请求发送到服务端
    cookies.addCookie(cookie);
});

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 拦截器方式

拦截器方式原理上和回调函数方式一样,只不过OnSaveCookie 和 OnLoadCookie 回调函数接口变成了拦截器中的 onSaveCookie(ForestRequest, ForestCookies) 方法和 onLoadCookie(ForestRequest, ForestCookies) 方法。

/**
 * 处理Cookie的拦截器
 */
public class CookieInterceptor implements Interceptor {
    
    // Cookie在本地存储的缓存
    private Map<String, List<ForestCookie>> cookieCache = new ConcurrentHashMap<>();

    /**
     * 在请求响应成功后,需要保存Cookie时调用该方法
     *
     * @param request Forest请求对象
     * @param cookies Cookie集合,通过响应返回的Cookie都从该集合获取
     */
    @Override
    public void onSaveCookie(ForestRequest request, ForestCookies cookies) {
        // 获取请求URI的主机名
        String host = request.getURI().getHost();
        // 将从服务端获得的Cookie列表放入缓存,主机名作为Key
        cookieCache.put(host, cookies.allCookies());
    }

    /**
     * 在发送请求前,需要加载Cookie时调用该方法
     *
     * @param request Forest请求对象
     * @param cookies Cookie集合, 需要通过请求发送的Cookie都添加到该集合
     */
    @Override
    public void onLoadCookie(ForestRequest request, ForestCookies cookies) {
        // 获取请求URI的主机名
        String host = request.getURI().getHost();
        // 从缓存中获取之前获得的Cookie列表,主机名作为Key
        List<ForestCookie> cookieList = cookieCache.get(host);
        // 将缓存中的Cookie列表添加到请求Cookie列表中,准备发送到服务端
        // 默认情况下,只有符合条件 (和请求同域名、同URL路径、未过期) 的 Cookie 才能被添加到请求中
        cookies.addAllCookies(cookieList);
    }

    @Override
    public void onError(ForestRuntimeException ex, ForestRequest request, ForestResponse response) {
        // ... ...
    }

    @Override
    public void onSuccess(Object data, ForestRequest request, ForestResponse response) {
        // ... ...
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

# 严格匹配模式 (v1.5.25)

默认情况下,只有符合条件 (和请求同域名、同URL路径、未过期) 的 Cookie 才能被添加到请求中

这是因为 Forest 的 Cookie 集合默认为严格匹配模式,如果想添加符合匹配要求的 Cookie,只需修改严格匹配为false即可

@Override
public void onLoadCookie(ForestRequest request, ForestCookies cookies) {
    cookies.strict(false) // 设置为非严格匹配模式
        .addCookie(new ForestCookie("attr1", "foo")) // 不设域名,默认情况下也能添加
        .addCookie(new ForestCookie("attr2", "bar")) // 不设域名,默认情况下也能添加
        // 不设域名,只有在非严格匹配模式下可以添加到请求中
        .addCookie(new ForestCookie("attr3", "foobar").setDomain("xxx.com"));
}
1
2
3
4
5
6
7
8
帮助我们改善此文档 (opens new window)
上次更新: 2023/03/13, 15:28:40
🛡️ HTTPS
🛸 使用代理

← 🛡️ HTTPS 🛸 使用代理→

Theme by Vdoing | Copyright © 2016-2023 公子骏 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式