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 参数
    • 🍭 请求头
    • 👔 请求体
    • 🍮 后端框架
      • 为何需要不同的后端框架
      • 全局后端框架
      • 接口/请求后端框架
        • 后端快捷注解
        • @Backend 注解
      • 自定义后端 Client 对象
        • OkHttpClient
        • HttpClient
      • 后端 Client 缓存
    • 🧁 接口注解
    • 📬 接收数据
    • 🍛 数据转换
    • 🍓 成功/失败条件
    • 🍌 重试机制
    • 🥂 重定向
    • 🍔 Gzip解压
    • 🎂 日志管理
    • ⚽ 回调函数
    • 🍟 异步请求
    • 🛡️ HTTPS
    • 🍪 使用Cookie
    • 🛸 使用代理
    • 🍉 上传下载
    • 🚑 异常处理
  • 编程式接口

    • 请求API

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

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

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

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

🍮 后端框架

在之前的章节中我们已经介绍过,Forest分为前端和后端两部分,而后端是由okhttp3和httpclient这样的后端HTTP框架构成的

# 为何需要不同的后端框架

可能有些小伙伴会有疑问,既然某一种HTTP包(比如okhttp3)可以作为后端的底层HTTP框架,已提供了日常所有的HTTP请求访问功能,为何还再支持另一种不同的HTTP框架作为后端呢?

这是因为没有一种框架都是完美的,都有各自的优缺点以及差异,比如okhttp3接入相对简单、同步异步容易切换,但很难支持带请求体的GET请求这种非标准的畸形请求(但往往业务中需要这种类型请求); 而httpclient(5.0版本以下)性能较好,支持各种标准和非标准请求,但接入较为麻烦,还需要依赖很多的jar包,且不支持HTTP/2协议

Forest在某种程度上可以被理解为是一个屏蔽层,尽可能地屏蔽不同后端底层HTTP框架之间的差异,比如有统一的接口调用方式、统一的配置等等,但还是有些底层的特性差异是Forest无能为力的,比如让okhttp3的GET请求携带Body这件事就难以做到

对于这样的问题,Forest给出的解决方案就是组合使用不同的后端框架,换句话说就是在需要的地方使用相应的后端框架

# 全局后端框架

Forest有一个全局唯一的后端,并以此为HTTP请求的默认后端,默认情况下为okhttp3

    # 设置全局后端框架
    # 目前版本有两种选择:okhttp3 和 httpclient
    # 不填的默认请求为 okhttp3
    
    forest:
        backend: httpclient # 设置全局后端为 httpclient
    
    1
    2
    3
    4
    5
    6
    # 设置全局后端框架
    # 目前版本有两种选择:okhttp3 和 httpclient
    # 不填的默认请求为 okhttp3
    
    forest:
        backend: okhttp3 # 设置全局后端为 okhttp3
    
    1
    2
    3
    4
    5
    6
    # 设置全局后端框架
    # 目前版本有两种选择:okhttp3 和 httpclient
    # 不填的默认请求为 okhttp3
    
    # 设置全局后端为 httpclient
    forest.backend=httpclient
    
    1
    2
    3
    4
    5
    6
    # 设置全局后端框架
    # 目前版本有两种选择:okhttp3 和 httpclient
    # 不填的默认请求为 okhttp3
    
    # 设置全局后端为 okhttp3
    forest.backend=okhttp3
    
    1
    2
    3
    4
    5
    6
    <!-- backend 后端HTTP API: httpclient -->
    <forest:configuration
        ... ...
        backend="httpclient">
    ... ...
    </forest:configuration>
    
    1
    2
    3
    4
    5
    6
    <!-- backend 后端HTTP API: okhttp3 -->
    <forest:configuration
        ... ...
        backend="okhttp3">
    ... ...
    </forest:configuration>
    
    1
    2
    3
    4
    5
    6
    // 目前版本有两种选择:okhttp3 和 httpclient
    // 不填的默认请求为 okhttp3
    
    // 获取全局默认配置对象
    ForestConfiguration configuration = Forest.config();
    // 设置全局后端为 httpclient
    configuration.setBackend(new HttpclientBackend());
    
    1
    2
    3
    4
    5
    6
    7
    // 目前版本有两种选择:okhttp3 和 httpclient
    // 不填的默认请求为 okhttp3
    
    // 获取Forest全局配置对象
    ForestConfiguration configuration = Forest.config();
    // 设置全局后端框架为 okhttp3
    configuration.setBackend(new OkHttp3Backend());
    
    1
    2
    3
    4
    5
    6
    7
    // Make sure to add code blocks to your code group

    如果要通过代码方式设置后端框架,建议将后端对象作为静态常量常驻于内存,而不是经常重复实例化同样的后端对象

    public class MyBackend {
        // httpclient 后端对象
        public final static HttpclientBackend HTTPCLIENT = new HttpclientBackend();
        // okhttp3 后端对象
        public final static OkHttp3Backend OKHTTP3 = new OkHttp3Backend();
    }
    
    1
    2
    3
    4
    5
    6
    // 获取Forest全局配置对象
    ForestConfiguration configuration = Forest.config();
    // 设置全局后端框架为 httpclient
    configuration.setBackend(MyBackend.HTTPCLIENT);
    
    1
    2
    3
    4
    // 获取Forest全局配置对象
    ForestConfiguration configuration = Forest.config();
    // 设置全局后端框架为 okhttp3
    configuration.setBackend(MyBackend.OKHTTP3);
    
    1
    2
    3
    4

    # 接口/请求后端框架

    全局后端框架可以配置和切换,甚至可以进行动态切换,但很多时候需要同时使用不同的后端框架,比如两个不同的接口分别使用不同的后端

    自1.5.5版本后,Forest支持了接口/请求级别的后端框架配置,方便HTTP请求灵活设置后端

    # 后端快捷注解

    Forest提供了 @HttpClient 注解和 OkHttp3 注解,分别用于绑定请求的后端为 httpclient 和 okhttp3


     




     



    // 绑定请求的后端为 httpclient
    @HttpClient
    @Post("/data1")
    String send1(@Body MyUser user);
    
    // 绑定请求的后端为 okhttp3
    @OkHttp3
    @Post("/data2")
    String send2(@Body MyUser user);
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    如果此类注解也绑定到接口上,那么该接口下的所有方法的请求默认为该接口注解指定的后端框架


     








     





    // 设置该请求接口的后端框架默认为 httpclient
    @HttpClient
    public interface BackendClient2 {
    
        // 未设置请求的后端,则默认为接口指定的后端框架,即 httpclient
        @Post("/data1")
        String send1(@Body MyUser user);
    
        // 绑定某一方法请求的后端为 okhttp3
        // 会覆盖掉接口上绑定的后端
        @OkHttp3
        @Post("/data2")
        String send2(@Body MyUser user);
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    # @Backend 注解

    还有一种更为灵活和通用的注解 @Backend, 可以通过传入的字符串参数来确定具体要绑定的后端框架


     







     





    // 设置该请求接口的后端框架默认为 httpclient
    @Backend("httpclient")
    public interface BackendClient2 {
    
        // 未设置请求的后端,则默认为接口指定的后端框架,即 httpclient
        @Post("/data1")
        String send1(@Body MyUser user);
    
        // 绑定请求的后端为 okhttp3
        @Backend("okhttp3")
        @Post("/data2")
        String send2(@Body MyUser user);
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    该注解的参数也支持字符串模板,即可以通过全局变量和参数来动态传入

    @Backend("{0}")
    @Post("/data")
    String send(String backend, @Body MyUser user);
    
    1
    2
    3

    提示

    对于如何在非 spring/springboot 项目中通过代码设置后端框架,请参见《请求对象 - 后端框架》

    # 自定义后端 Client 对象

    Forest 在默认情况下会自动生成后端 Client 对象实例,并进行缓存。但如果您想进行更细致的操作时也可以自行生成和配置后端 Client 对象。

    # OkHttpClient

    自定义 OkHttp3 框架的 OkHttpClient 对象,只需实现OkHttpClientProvider接口

    public class MyOkHttpClientProvider implements OkHttpClientProvider {
    
        @Override
        public OkHttpClient getClient(ForestRequest request, LifeCycleHandler lifeCycleHandler) {
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(700, TimeUnit.SECONDS)
                    .readTimeout(700, TimeUnit.SECONDS)
                    .writeTimeout(700, TimeUnit.SECONDS)
                    .callTimeout(700, TimeUnit.SECONDS)
                    .followSslRedirects(false)
                    .retryOnConnectionFailure(false)
                    .followRedirects(false)
                    .build();
            return okHttpClient;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    绑定该自定义的 OkHttpClient 对象提供者


     


    @Get("/")
    @OkHttp3(client = MyOkHttpClientProvider.class)
    ForestResponse<String> sendData();
    
    1
    2
    3

    # HttpClient

    同理,自定义 Apache Httpclient 框架的 HttpClient 对象,也只需实现HttpClientProvider接口

    public class MyHttpClientProvider implements HttpClientProvider {
    
        @Override
        public HttpClient getClient(ForestRequest request, LifeCycleHandler lifeCycleHandler) {
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(700 * 1000)
                    .setSocketTimeout(700 * 1000)
                    .setConnectionRequestTimeout(700 * 1000)
                    .setRedirectsEnabled(false)
                    .build();
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(config)
                    .build();
            return httpClient;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    绑定该自定义的 HttpClient 对象提供者


     


    @Get("/")
    @HttpClient(client = MyHttpClientProvider.class)
    ForestResponse<String> sendData();
    
    1
    2
    3

    # 后端 Client 缓存

    为提高 Forest 请求的执行性能,默认情况下,每个请求所对应的后端客户端对象都会被缓存

    请求前,会先去缓存中寻找所需的后端 Client 对象实例,如若没有,则新创建一个并放入该请求所对应的缓存中

    接口的缓存开关设定如下:



     


    // 关闭后端 Client 缓存
    @Get("/")
    @BackendClient(cache = false)
    ForestRequest<String> sendData();
    
    1
    2
    3
    4
    帮助我们改善此文档 (opens new window)
    上次更新: 2023/03/13, 15:28:40
    👔 请求体
    🧁 接口注解

    ← 👔 请求体 🧁 接口注解→

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