登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
轻量养虾,开箱即用!低 Token + 稳定算力,Gitee & 模力方舟联合出品的 PocketClaw 正式开售!点击了解详情
代码拉取完成,页面将自动刷新
开源项目
>
程序开发
>
网络开发包
&&
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
336
Star
3.9K
Fork
825
dromara
/
forest
代码
Issues
178
Pull Requests
0
Wiki
统计
流水线
服务
JavaDoc
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
开发画像分析
我知道了,不再自动展开
发行版
最新版
v1.8.0
8ef2e95
2025-10-10 17:36
对比
v1.8.0
公子骏
Forest v1.8.0 版本发布了,此次版本升级主要支持了响应式接口,声明式接口和编程式接口都能支持将 Flux 和 Mono 作为响应返回类型。 #### 支持响应式 在使用响应式特性钱,需要先新增以下 Maven 依赖 ```xml <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-reactor</artifactId> <version>1.8.0</version> </dependency> ``` 新版本 Forest 支持在声明式接口中,使用 Flux 或 Mono 作为响应数据的返回类型 ```java public interface ReactorClient { // 支持 Flux 作为返回类型 @Get("/flux") Flux<String> testFlux(); // 支持 Mono 作为返回类型 @Get("/mono") Mono<String> testMono(); } ``` #### 支持 SSE 转 Flux ```java Forest.get("/sse") .sse(ReactorSSE.class) // 使用 ReactorSSE 类 .setOnMessage((event, sink) -> { String data = event.value(String.class); sink.next("data: " + data); // 发布消息 }) .toFlux(String.class) // 转化为 Flux<String> 类型 .subscribe(name -> { // 订阅消息 System.out.println("value -> " + name); }); ``` #### 新增特性 - feat: 支持 Flux 作为响应返回类型 - feat: 支持 Mono 作为响应返回类型 - feat: 支持 SSE 转 Flux #### 修复问题 - fix: SSE 在 AUTO 模式下无法识别某些字符串格式的问题
最后提交信息为:
update: new version 1.8.0
v1.7.6
2412dcf
2025-09-27 23:25
对比
v1.7.6
公子骏
Forest v1.7.6 版本发布了,此次发布解决了一些Bug,并优化了一些性能。 #### 性能优化 将一些每次请求都要做的操作放到了初始化阶段一次做完,优化了一些性能。实测在 httpclient 作为后端的情况下,可以达到和 hutool HttpUtil 一样的性能,某些场景下(编程模式下手动关闭响应的请求)甚至有所超过。 #### 修复问题 - fix: 当 httpclient 做后端的时候,响应会拿不到带泛型的数据 (#243) - fix: x-www-form-urlencoded 格式的 body 字符串未按标准的形式进行转义 - fix: 后端为 okhttp3 时,并且 Content-Type 中`; charset=`部分带空格的话,实际发送的和设置的不一致 #### 优化内容 - opt: 优化请求性能
最后提交信息为:
update: new version 1.7.6
v1.7.5
89a50c4
2025-09-17 00:47
对比
v1.7.5
公子骏
Forest v1.7.5 版本发布了,此次发布主要解决了一些Bug。 #### 修复问题 - fix: 使用`@BaseRequest`的`baseURL`指定域名失效
最后提交信息为:
update: new version 1.7.5
v1.7.4
2ab28ea
2025-09-15 01:03
对比
v1.7.4
公子骏
Forest v1.7.4 版本发布了!此次版本发布主要支持了在编程式接口中使用和修改字符串模板变量 #### 编程式接口中的模板变量 可以在URL中使用模板变量 ```java Forest.get("{baseURL}/test/{myPath}"); ``` 可以在请求头中使用模板变量 ```java Forest.post("/test") .addHeader("Content-Type", "{myContentType}") .addHeader("name", "{myName}"); ``` 可以在字符串型请求体中使用模板变量 ```java Forest.post("/test") .contentTypeJson() .addBody("{myBody}"); ``` 可以在 K-V 型请求体中使用模板变量 ```java Forest.post("/test") .contentFormUrlEncoded() .addBody("a", "{a}") .addBody("b", "{b}"); ``` 其他可以使用模板变量的编程式接口 ```java Forest.get("/") .host("{myHost}") // host .port("{myPort}") // port .path("{myPath}") // path .charset("{myCharset}") // charset .connectTimeout("{myConnTimeout}") // connect timeout .readTimeout("{myReadTimeout}"); // read timeout ``` #### 新特性 - feat: 在编程式接口中,在`ForestRequest`对象中新增`var(name, value)`、`var(name)`、`varAs(name, class)`方法,用于修改和获取请求级别的变量 - feat: 在编程式接口中,`url`、`header`、Key-Value形式的`body`支持使用字符串模板 - feat: 在编程式接口中,`connectTimeout`方法和`readTimeout`方法支持接受字符串模板作为参数 - feat: 在编程式接口中,`charset`方法支持接受字符串模板作为参数 - feat: OAuth2 增加`OAuth2#forestInterceptor`属性,可以增加自定义拦截器来对获取 Token 的请求进行一些操作 #### 修复问题 - fix: 默认不对cookie的值进行编码和反编码(#ICVPUG)
最后提交信息为:
update: maven publish
v1.7.3
2b71ff1
2025-06-30 23:32
对比
v1.7.3
公子骏
Forest v1.7.3 版本发布了!任然是 Bug Fix,继续升级即可。 #### 修复错误 - feat: 新增 Forest 请求的 logRequestHeaders、logRequestBody 日志开关配置 - fix: 重复读取响应流时报错 - fix: 嵌套json字符串无法正常解析
最后提交信息为:
fix: 重复读取响应流时报错
v1.7.2
a554d9a
2025-06-30 14:21
对比
v1.7.2
公子骏
Forest v1.7.2 版本发布了!这个版本就是些 Bug Fix,没什么好说的,无脑升级即可。 #### 修复错误 - fix: 调用声名式接口的 hashCode() 方法会死循环 - fix: 以 ForestResponse<T> 为返回类型时,T 的子类匹配问题
最后提交信息为:
!76
update: new version -> 1.7.2
v1.7.1
dc16c9f
2025-06-23 13:47
对比
v1.7.1
公子骏
Forest v1.7.1 版本发布了!本次发布包含了很多重大更新内容,我们对字符串模板的语法进行了增强,支持了空安全语法和深度变量引用,并提供了更友好的报错信息;在Cookie方面也进行了增强,提供了Cookie自动保存和读取的机制,并添加了更完善的API接口;我们也对拦截器进行了优化改进,不再建议直接使用`Interceptor`接口和它的`onSuccess`方法,取而代之的是`ForestInterceptor`和`onResponse`方法,它们要比前者更安全,性能也更好;除此之外,此次更新对请求的性能进行了全面的优化,在默认使用编程式接口、不打印日志的情况下,可以达到和 hutool 的 HttpUtil 差不多的耗时。 #### 空安全语法 在原来版本,如果在字符串模板中引用一个没定义过的变量会支持报错。现在用空安全语法可以让它不再报错,而是直接返回 null 值。 ```java // 没定义过 testVar 变量,通过 ? 一样可以正常引用 Forest.get("/test/{testVar?}"); ``` 或者,引用了一个不存在或值为 null 的变量后,再用点`.`访问它的属性,这在老版本中自然是直接报错的。现在,可以通过`?.`符号自动判断是否为空。 ```java // 会先判断 testVar 是否为空,然后 testVar.a 是否为空,其中一个为空就会直接返回 null // 不会报错 Forest.get("/test/{testVar?.a?.name}"); ``` #### 深度引用 在原来版本中,字符串模板中的变量只能引用到第一层,如果该变量的值是引用其他的变量,字符串模板并不会进行解析。而现在,不管引用了多少层变量,都可以解析到底。 ```yaml forest: variables: var1: "{user.name}" var2: "{user.password}" user: name: foo password: bar ``` 在Java代码中直接引用 ```java // 最终 URL 为: /test/foo/bar Forest.get("/test/{var1}/{var2}"); ``` 如果不想进行深度引用,可以使用深度引用停止语法,即在变量后加上`!`符号,那么就只会引用一层该变量的值,至于该变量的值是否会包含其他字符串模板的内容,就不会再进行解析了。 ```java // 最终 URL 为: /test/{user.name}/{user.password} // 变量 var1 和 var2 的值直接返回字符串,而不会进行任何解析 Forest.get("/test/{var1!}/{var2!}"); ``` #### 更安全的拦截器 本次版本更新后,不再建议使用`Interceptor`(当然要用也可以用,不影响以前的老代码),同时引入了更安全的`ForestInterceptor`接口 ```java public class MyInterceptor implements ForestInterceptor { @Override public ResponseResult onResponse(ForestRequest request, ForestResponse response) { if (response.isError()) { // 返回错误标志 return error(response.getException()); } // 通过 response.getResult() 或 response.get(数据类型.class) 来获取响应数据 // 返回继续执行标志 return proceed(); } } ``` #### 请求级别日志开关 不再需要 new 一个 LogConfiguration 对象,直接在 ForestRequest 的链式调用中即可设置日志开关 ```java Forest.post("/test") .logEnabled(true) // 请求日志总开关 .logRequest(true) // 请求内容日志开关 .logResponseStatus(true) // 响应状态日志开关 .logResponseHeaders(true) // 响应头日志开关 .logResponseContent(false) // 响应体内容日志开关 .execute(); ``` #### 新增特性 * feat: 字符串模板支持空安全语法 * feat: 更友好的字符串模板错误消息 * feat: 字符串模板`{`、`${`等符号支持转义`\\{`、`\\${` * feat: 字符串模板支持深度变量引用 * feat: 字符串模板支持停止深度引用的语法 * feat: 支持嵌套字符串模板 * feat: 新增更安全的 Forest 拦截器接口 ForestInterceptor * feat: 通过配置自定义异步线程池拒绝策略 * feat: 支持Bear 认证器 * feat: 支持`@Var`作为方法和类的变量绑定注解 * feat: 新增 ForestRequest 级别的日志开关接口 * feat: 增强 Cookie 相关 API 接口 * feat: 后台自动清理过期 Cookie * feat: 支持 Cookie 自动化存取机制 #### 修复错误 * fix: 和老版本forest冲突时,新版本Forest类缺乏get(url)、post(url)等方法签名,造成错误 (#IC7LIH) * fix: body log在部分环境中文乱码 * fix: 修改接口中常量的命名,避免用户在其与只有大小写区别的方法之间产生混淆 #### 重构内容 * refactor: 重构URL解析过程 * refactor: 重构变量作用域 * refactor: 重构 Forest 变量体系 * refactor: ForestCookie 不再依赖 OkHttp * refactor: ForestCookie.parse() 接口 * refactor: 添加键值对类型请求体删除接口 ForestBody.removeNameValueBody #### 代码优化 * optimize: 优化请求性能 * optimize: 根据 Response 类型动态判断响应是否自动关闭 * optimize: 默认后端改为 httpclient * optimize: 拦截器优化
最后提交信息为:
!73
update: new version -> 1.7.1
v1.6.4
f6e8aac
2025-02-26 07:52
对比
v1.6.4
公子骏
Forest v1.6.4 版本发布了!此次版本更新主要调整了 SSE 消息处理方面的接口 #### SSE 消息行模式 SSE 的消息通常为标准的多行一组的`name:value`格式,每组消息用空白行隔开,具体如下: ```text id:1 event:json data:{"name":"a"} text:xxx id:2 event:json data:{"name":"b"} text:yyy ``` 对于这种标准的格式,可使用多行(MULTI_LINES),或自动(AUTO)模式 ```java Forest.get("/sse") .sse() .setOnMessage(event -> { event.id(); // 消息名为 id 的值,这里应得到 1, 2 event.event(); // json event.data(); // {"name": "a"}, ... event.value("text"); // 获取非标准名称的消息值,如: text,这里应得到 xxx, yyy }) .listen(SSELinesMode.MULTI_LINES); ``` 或者使用`AUTO`,`listen`方法不传参数的情况下,默认为`AUTO`,`AUTO`模式会自动识别需要采用的行模式 ```java // AUTO 模式会自动识别需要采用的行模式 sse.listen(); // 默认行模式为 AUTO ``` SSE 的消息除了有标准格式,还有很多非标准的格式,比如每行都是一条JSON字符串,每一行都是单独的消息 ```text {"name":"a"} {"name":"b"} {"name":"c"} ``` 对于这种类型的消息,就要使用单行模式(SINGLE_LINE) ```java Forest.get("/sse") .sse() .setOnMessage(event -> { String str = event.value(); // 获取字符串类型的消息值 MyUser user = event.value(MyUser.class); // 获取消息值并转换为自定义类型 }) .listen(SSELinesMode.SINGLE_LINE); ``` #### 新增特性 - feat: 添加根据类型获取body对象的接口,可通过`request.body().get(Class)`获得body中对应类型的对象 - feat: 支持指定 SSE 消息行模式,包括单行、多行、以及自动模式 #### 修复问题 - fix: 由Content-Type中`; charest=utf8`部分包含空格导致的body无故乱码的问题 - fix: 和老版本forest冲突时,新版本Forest类缺乏get(url)、post(url)等方法签名,造成错误
最后提交信息为:
add: ForestSSE.asyncListen(SSELinesMode linesMode, ExecutorService ...
v1.6.3
5b26edf
2024-12-29 19:11
对比
v1.6.3
公子骏
Forest v1.6.3 版本发布了!此次版本更新主要调整了 SSE 相关的API接口,以及更新了maven依赖 #### 新增特性 - add: EventSource.value(Class<T>) 方法 - add: EventSource.value(TypeReference<T>) 方法 #### 不兼容改动 - refactor: SSEInterceptor.onSSEClose(ForestRequest, ForestResponse) 方法参数改为 SSEInterceptor.onSSEClose(EventSource) - refactor: ForestSSE.setOnClose(BiConsumer<ForestRequest, ForestResponse>) 方法参数改为 ForestSSE.setOnClose(Consumer<EventSource>) - refactor: EventSource.getValue() 方法重命名为 EventSource.value() - refactor: EventSource.getName() 方法重命名为 EventSource.name() - refactor: EventSource.getRawData() 方法重命名为 EventSource.rawData() #### 其他改动 - update: 更新依赖版本
最后提交信息为:
update: version 1.6.3
v1.6.2
ef372f1
2024-12-24 14:14
对比
v1.6.2
公子骏
Forest v1.6.2 版本发布了!此次版本更新主要修复了 JsonPath 和 SSE 相关问题,并新增了 SSE 的监听关闭接口。 #### 新增特性 - feat: 新增 ForestSSE.close() 监听关闭接口 - feat: 新增 ForestSSE.await() 用于阻塞等待异步监听完成 #### 修复问题 - fix: EventSource.close() 无法正常关闭 SSE 监听 - fix: 通过JsonPath获取基本类型字段错误
最后提交信息为:
fix: 通过JsonPath获取基本类型字段错误
v1.6.1
2b27382
2024-12-21 05:46
对比
v1.6.1
公子骏
Forest v1.6.1 版本发布了!此次版本更新主要修复了 SSE 相关问题,并新增了 SSE 拦截器。 #### SSE 拦截器 `ForestSSE`控制器和自定义SSE控制器都是非单例的独立实例对象,所以无法直接注入和使用 spring 上下文中的资源。 而 SSE 拦截器接口 SSEIntercpetor 继承自 Interceptor,可以注入到 spring 上下文中并使用其中的 bean,但和普通拦截器一样是单例,不能使用类属性共享数据。 ```java @Component public class MySSEInterceptor implements SSEInterceptor { @Override public void onSuccess(InputStream data, ForestRequest request, ForestResponse response) { // 和普通拦截器 onSuccess 相同,data 是 SSE 的消息流,不建议在这里动它 } @Override public void afterExecute(ForestRequest request, ForestResponse response) { // 和普通拦截器 afterExecute 相同 } @Override public void onSSEOpen(EventSource eventSource) { // SSE 开始监听时调用 } @Override public void onSSEClose(ForestRequest request, ForestResponse response) { // SSE 结束监听时调用 } // 监听名称为 data 的消息 @SSEDataMessage public void onData(ForestRequest request, @SSEName String name, @SSEValue String value) { // 参数列表中的参数个数不做限制,可随意排列组合 ForestRequest、ForestResponse、EventSource 这几个类型参数 // name: @SSEName 注解修饰的参数可传递 SSE 消息的名称 // value: @SSEValue 注解修饰的参数可传递 SSE 消息的值 } // 监听名称为 event 的消息 @SSEEventMessage public void onEvent(EventSource eventSource, @SSEValue String value) { // 参数列表中的参数个数不做限制,可随意排列组合 ForestRequest、ForestResponse、EventSource 这几个类型参数 } // 通过 @SSEMessage 注解可以指定要监听何种名称的消息 @SSEMessage("id") public void onData(EventSource eventSource) { // 参数列表中的参数个数不做限制,可随意排列组合 ForestRequest、ForestResponse、EventSource 这几个类型参数 } } ``` 绑定方式和普通拦截器一样 ```java @Get(url = "/sse", interceptor = MySSEInterceptor.class) ForestSSE testSSE_withInterceptor(); ``` #### 新增特性 - feat: SSE 拦截器 #### 修复问题 - fix: @SSEName 注解参数取值错误 - fix: SSE 请求长连接超时 - fix: SSE 请求返回的控制器为单例的问题 #### 代码改动 - update: SSE 适配 spring-boot 和 solon
最后提交信息为:
update: SSE 适配 spring-boot 和 solon
v1.6.0
e0f8ec3
2024-12-18 18:43
对比
v1.6.0
公子骏
Forest v1.6.0 版本发布了!此次版本更新功能较多,新增了包括 SSE、Jsonpath、链式条件函数等新特性。 #### 支持 SSE 此次最大的更新,主要是支持了 SSE,并且支持<b>声名式</b>和<b>编程式</b>两种 SSE 接口 ##### 声明式 SSE 接口: 接口定义: ```java public interface SSEClient { // Forest SSE 控制器类作为 SSE 接口返回类型 @Get("/sse") ForestSSE testSSE(); // 自定义 SSE 控制器类作为 SSE 接口返回类型 @Get("/sse") MySSEHandler testSSE2(); } ``` 自定义 SSE 控制器类: ```java public class MySSEHandler extends ForestSSE { @Override protected void onOpen(EventSource eventSource) { // SSE 开始监听时执行 } @Override protected void onClose(ForestRequest request, ForestResponse response) { // SSE 结束监听时执行 } @SSEDataMessage public void onHello(@SSEValue String value) { // 监听名称为 data 的消息事件 // @SSEValue 注解修饰的 value 参数为消息的值 } @SSEEventMessage(valueRegex = "\\{.*name.*\\}") public void onEvent(@SSEValue Contact contact) { // 监听名称为 event 的消息事件 // 并且消息要满足匹配正则表达式 "\\{.*name.*\\}" 的要求 } } ``` 接口调用: ```java // ForestSSE 作为返回值的接口调用 sseClient.testSSE().listen(); // 自定义 SSE 控制器作为返回值的接口调用 sseClient.testSSE().listen(); ``` ##### 编程式 SSE 接口: ```java Forest.get("http://localhost:{}/", server.getPort()) .sse() // 指定请求为 SSE 请求 .setOnOpen(eventSource -> { // SSE 开始监听时执行 }) .setOnClose((req, res) -> { // SSE 结束监听时执行 }) .addOnData((eventSource, name, value) -> { // 监听到名称为 data 的消息事件时执行 }) .addOnEventMatchesPrefix("close", (eventSource, name, value) -> { // 监听到名称为 event 的消息事件,并且消息的值满足"close"前缀匹配要求时执行 eventSource.close(); // 手动关闭 SSE 监听 }) .listen(); // 开始监听 ``` #### 支持链式条件函数 ```java Forest.get("http://localhost:{}", server.getPort()) .addHeader("A", 0) .cond(b > 100, q -> q.addHeader("B", 100)) // [单分支] 如果 b > 100,则添加 Header B:100 .cond(c > 200, q -> q.addHeader("C", 200)) // [单分支] 如果 c > 200,则添加 Header C:100 .ifThen(a > 0, q -> q.addHeader("A", a + 1)) // [多分支] 如果 a > 0,则添加 Header A:a+1 .elseIfThen(a == 0, q -> q.addHeader("A", 0)) // [多分支] 但如果 a = 0,则添加 Header A:0 .elseIfThen(a == -1, q -> q.addHeader("A", -1)) // [多分支] 但如果 a = -1,则添加 Header A:-1 .elseIfThen(a == -2, q -> q.addHeader("A", -2)) // [多分支] 但如果 a = -2,则添加 Header A:-2 .elseThen(q -> q.addHeader("A", 10)) // [多分支] 否则添加 Header A:10 .execute(); ``` #### 支持 JsonPath 声名式 JsonPath 注解 ```java public interface TestJSONPathClient { @Get("/test/user") @JSONPathResult("$.data") TestUser getSingleUser(); @Get("/test/user") @JSONPathResult("$.data") List<TestUser> getListOfUsers(); @Get("/test/user") @JSONPathResult("$.data[*].age") List<Integer> getListOfUserAges(); @Get("/test/user") @JSONPathResult("$.data[?(@.age>{minAge})].age") List<Integer> getListOfUserAges(@Var("minAge") int minAge); } ``` 编程式 JsonPath 接口 ```java TestUser user = Forest.get("http://localhost:{}/test/user", server.getPort()) .executeAsResponse() .getByPath("$.data", TestUser.class); ``` #### 安全流处理接口 ```java Forest.get("http://localhost:{}/download/test-img.jpg", server.getPort()) .executeAsStream((in, req, res) -> { // in 为已经打开的 InpuStream 流对象 // 在这里不需要手动打开和关闭流 }); ``` 大JSON数据的流式处理 ```java List<MyUser> list = Forest.get("http://localhost:{}/user.json", server.getPort()) .executeAsStream((in, req, res) -> { // 在回调函数返回的数据会作为请求的最终返回值 return new Gson() .fromJson(new JsonReader(new InputStreamReader(in)), MyUser.class) }); ``` #### 新增特性 - feat: 支持SSE - feat: 链式条件接口 - feat: 支持Jsonpath - feat: 字符串模板可以用 {} 替代 {数字} 作为参数占位符 - feat: 类级别`@BindingVar`注解 - feat: 适配Android环境的Log - feat: 新增 onResponse 生命周期回调函数 - feat: 支持 Optional 作为接口返回结果类型 - feat: 支持 CompletableFuture 作为接口返回结果类型 - feat: 自定义 LogHandler 支持 Spring Bean 方式注入 - feat: 美化字符串表达式报错信息 - feat: 新增安全响应流处理接口 #### 修复问题 - fix: 百分号无法被 URLEncode 的问题 - fix: @Address 注解的属性无法重写的问题 - fix: 过滤器函数无法调用 - fix: 可能出现的 connection pool shut down 问题 - fix: 在后端为okhttp3情况下,打印content-type为multiparty/form-data,body为其他类型时报错的问题 - fix: 在拦截器的onMethodInitialized方法中调用setReturnType函数无效(#I8PJ9R) - fix: 修复未恢复parentScope导致的栈溢出(#I9TP9Z) #### 代码改动 - update: 缓存框架换成Hutool的LRU缓存 - update: forest-solon-plugin 升级 solon 为:3.0.1(兼容 2.5.9+) - update: 更新依赖最新稳定版本 - refactor: 在发生 Response: [Network Error] 错误时,可以打印 status 信息 - opt: query支持线程安全 - reflector: 重构 ForestAuthenticator 接口 - refactor: 重构响应的流处理逻辑 - add: ResultGetter.openStream 方法 - refactor: 修改表达式异常报错信息格式 #### 贡献者 - @wittplus (witt) - @Kiroe (Kiro) - @noear_admin (西东)
最后提交信息为:
test: 安全响应流处理接口
v1.5.36
8712765
2024-02-27 10:59
对比
v1.5.36
公子骏
Forest v1.5.36 版本发布了!此次改动主要支持了 Fastjson2,以及 solon 版本更新 #### 新增特性 - feat: 支持 Fastjson2 #### 修复问题 - fix: okhttp 后端`response.getContentLength()`取不到值 (#I90MUX) - fix: Jackson转换器中Lazy转换Map出错 #### 代码改动 - Update: solon 升级为`v2.6.5` - refactor: 不在生成 multipart boundary 字符串时使用 okio 包的方法
最后提交信息为:
test: jackson兼容问题
v1.5.35
d211512
2023-11-29 11:08
对比
v1.5.35
公子骏
`v1.5.35`版本发布了!此次版本更新主要实现了后端客户端缓存可配置空间大小以及过期时间 #### 配置后端客户端缓存 配置缓存大小和过期时间 ```yaml forest: backend-client-cache-max-size: 512 # 后端客户端缓存最大空间大小(单位为实例个数,默认为128) backend-client-cache-expire-time: 3h # 后端客户端缓存超时时间(单位为时间长度,默认为6小时) ``` #### 新增特性: - feat: 后端客户端实例缓存可配置大小以及过期时间
最后提交信息为:
update: new version 1.5.35
v1.5.34
12e280b
2023-11-28 11:49
对比
v1.5.34
公子骏
`v1.5.34`版本发布了!此次更新为解决请求不同的域名很多时,内存消耗越来越大的问题,使用 Caffeine 缓存框架作为后端客户端缓存的缓存 #### 修复问题 - fix: 当请求不同的域名很多时,内存消耗越来越大 (#I8J5PN) - fix: 高并发环境下,监控runningPoolSize值,出现负值情况&且有时候所有请求都结束了,但值没有 归零 (#I8JNBU ) - fix:完善单元测试之修复声明式接口,`@BaseRequest`或`@BaseURL`,在有baseURL属性下,如果方法的完整URL不写端口,就会被baseURL属性的端口覆盖,并不是默认的80端口的bug - fix: 修复不管是是用`@Address`还是`@BaseRequest`都无法将baseUrl和`@Get()`中的url拼接在一起的bug (#I7CAYS) - fix:处理`@Addrees`注解中basePath已`/`结尾,方法url不以`/`开头,最终地址会出现`//`的bug。 - fix: MultipartRequestBody 类冲突 ([154](https://github.com/dromara/forest/issues/154)) #### 代码改动 - refactor: 将gson改为单例 - refactor: 去掉`@DownloadFile`注解在下载文件时的进度日志 - refactor: 将 forest-spring-boot3 的相关测试用例移动到 forest-test 下 #### 贡献者 - @CHMing - @wittplus - @Moonsets - @noear_admin - https://github.com/zhfish - https://github.com/galaxy-sea
最后提交信息为:
update: new version 1.5.34
v1.5.33
57377b3
2023-08-29 13:38
对比
v1.5.33
公子骏
Forest v1.5.33 发布了,此次版本更新主要支持了 Socks 协议的代理,以及组合注解的属性重写 #### 新增特性: - feat: 支持socks代理 (#I6MLMD) - feat: 组合注解支持属性重写 #### 修复问题: - fix: `@Body`注解的数组参数无法正常解析为JSON数组 (#I7UPBR) - fix: Content-Type为application/xml的情况下,发送byte数组数据错误 (#I7F3F0) - fix: `@JSONBody` Collection<String> codes 报错 (#I7QLTS) #### 代码改动: - add: `@SocksProxy`注解 - add: `@OverrideAttribute`注解 - opt: 优化URL更新方式 - update: forest-solon-plugin 升级 solon 为:2.4.0 #### 鸣谢: - forest-solon-plugin 升级 solon 为:2.4.0 由 @noear_admin 贡献 - 解决issure:#I7QLTS 由 @Angle94 贡献 #### 新特性如何使用: - Socks 代理的使用方式请看 [声明式Socks代理文档](https://forest.dtflyx.com/pages/1.5.33/proxy/#socks%E4%BB%A3%E7%90%86) 以及 [编程式Socks代理文档](https://forest.dtflyx.com/pages/1.5.33/api_proxy/#socks-%E5%8D%8F%E8%AE%AE%E6%AD%A3%E5%90%91%E4%BB%A3%E7%90%86) - 组合注解的属性重写请看 [文档](https://forest.dtflyx.com/pages/1.5.33/makeup_annotation/#%E5%B1%9E%E6%80%A7%E9%87%8D%E5%86%99)
最后提交信息为:
test: 1.5.33
v1.5.32
09eea86
2023-06-19 19:06
对比
v1.5.32
公子骏
v1.5.32 版本发布了!此次版本更新主要修复一些BUG。 #### 修复问题: - fix: 在`@Header`参数中传入 Lazy Lambda 出错 (#I7EIAB) - fix: URLEncoder 无法编码百分号字符 (134) #### 代码改动: opt: 异步线程池初始化时并发优化
最后提交信息为:
update: version 1.5.32
v1.5.31
10661bc
2023-04-26 01:36
对比
v1.5.31
公子骏
Forest v1.5.31 发布了!该版本是一个小版本发布,主要修复了一些BUG #### 新增特性 - feat: 所有 Forest 请求默认带上`User-Agent: forest/{version}`的请求头 #### 修复问题 - fix: maven中各模块的JDK版本控制 - fix: 不同 ForestConfiguration 产生的 Client 实例存在参数污染的情况 - fix: 当`@Address`注解的 schema 属性设置为 https 时报错 (#I6Y6E2) - fix: ReflectUtils.getFields非线程安全 (#I6W9TF) #### 代码改动 - opt: ForestMethod 使用懒加载的方式初始化 - refactor: 使用 revision 进行多模块版本管理 - refactor: 请求注解的 interceptor 属性只接受继承自 Interceptor 接口的类 - add: `Forest.VERSION`字段,可动态获取 Forest 版本号
最后提交信息为:
feat: 所有 Forest 请求默认带上 User-Agent: forest/version 的请求头
v1.5.30
dbff4be
2023-03-08 16:21
对比
v1.5.30
公子骏
`v1.5.30`版本发布了,这次版本更新有了较大的改动,支持和适配了 SpringBoot3 和 Solon 框架,将XML模块拆分出了主模块,以及新增了延迟参数特性 #### 适配 SpringBoot3 项目中新增了`forest-spring-boot3-starter`模块,集成时需引入如下的依赖 ```xml <!-- Forest 的 SpringBoot3 适配模块 --> <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-spring-boot3-starter</artifactId> <version>1.5.30</version> </dependency> <!-- Forest 的 Jakarta XML 支持模块 --> <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-jakarta-xml</artifactId> <version>1.5.30</version> </dependency> ``` 如果是老版本 SpringBoot,依赖方式基本不变,但XML的模块需额外引入 ``` <!-- Forest 对 SpringBoot1或2 的适配模块 --> <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-spring-boot-starter</artifactId> <version>1.5.30</version> </dependency> <!-- Forest 的 JAXB 支持模块 --> <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-jaxb</artifactId> <version>1.5.30</version> </dependency> ``` 具体做法参考示例项目 https://gitee.com/dromara/forest/tree/master/forest-examples #### 适配 Solon 项目中新增了`forest-solon-plugin`模块,集成时需引入如下的依赖 ```xml <!-- Forest 的 Solon 适配模块 --> <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-solon-plugin</artifactId> <version>1.5.30</version> </dependency> <!-- Fastjson、Jackson、Gson 中任选一个JSON框架 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency> <!-- Forest 的 JAXB 支持模块 --> <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-jaxb</artifactId> <version>1.5.30</version> </dependency> ``` 具体做法参考示例项目 https://gitee.com/dromara/forest/tree/master/forest-examples #### 关于XML模块的说明 本次更新将XML序列化和反序列化相关功能移出了`forest-core`主模块,需根据不同的项目情况选择相应的 Forest XML 模块依赖。 如果项目,即普通非 SpringBoot3 项目(Spring、SpringBoot1或2)JDK版本也在17以下的项目,则用`forest-jaxb`依赖 ```xml <!-- Forest 的 JAXB 支持模块 --> <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-jaxb</artifactId> <version>1.5.30</version> </dependency> ``` 如果您的项目是 SpringBoot3,或是 JDK 17及以上版本的项目,这选择`forest-jakarta-xml`依赖 ```xml <!-- Forest 的 Jakarta XML 支持模块 --> <dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-jakarta-xml</artifactId> <version>1.5.30</version> </dependency> ``` #### 延迟参数 (Lambda参数) 有很多情况,Header、Query、Body的参数值不能马上得出,而是在请求发送前的那一刻(所有请求参数都到位时)才能得出,典型的例子就是加签验证的场景(在Header中添加一个参数token,而token的值是对整个body做加密的结果) - 请求头的延迟参数 ```java Forest.post("/test") .addHeader("Content-Type", "application/json; charset=UTF-8") // 这里传入的是一个 Lambda 表达式,它会在请求发送的前一刻才执行 // 将会通过对整个请求的Body做序列化后再进行Base64运算得出一个值,并给到Authorization请求头 .addHeader("Authorization", req -> Base64.encode("Token=" + req.body().encodeToString())) .addBody("id", "1972664191") .addBody("name", "XieYu20011008") .execute(); ``` - 请求体的延迟参数 ```java Forest.post("/test") .addHeader("Content-Type", "application/json; charset=UTF-8") .addHeader("_id", "20011008") .addBody("id", "1972664191") // 这里传入的是一个 Lambda 表达式,它会在请求发送的前一刻才执行 // 执行过程和原理同上 .addBody("name", req -> "Foo" + req.headerValue("_id")) .addBody("token", req -> Base64.encode(req.body().encode())) .execute(); ``` 这里在延迟参数Lambda表达式中调用的`req.body().encode()`执行的body序列化过程,会`自动排除`调用它的延迟参数本身,所以不必担心会发生死循环的情况 #### 新增特性 - feat: 适配 springboot3 - feat: 适配 solon - feat: 延迟参数 (Lambda参数),支持 Query, Header,Body 三种参数的延迟求值 - feat: 可自定义异步请求池拒绝策略 - feat: 请求体序列化接口,ForestRequest.body().encode() 和 ForestRequest.body().encodeToString() #### 修复问题 - fix: #I63WWN ForestProxy添加header没有效果 - fix: onBodyEncode 生命周期顺序问题 - fix: 不同 ForestConfiguration 对象共用同一个异步线程池的问题 - fix: 无法解析 `localhost:8080` 这类省略 http:// 的 url #### 其他改动 - reflector: 将xml解析模块拆分成了 forest-jaxb 和 forest-jakarta-xml 两个子模块,需要的情况要分别自行引入 - reflector: request body encoder - refactor: Forest Body clone - refactor: 构建 Query String 部分 - add: HTTPRoxy 注解的 headers 属性 - add: forest 示例工程 #### 特别鸣谢 特别感谢 Solon 作者 (@noear_admin) 对 Forest 项目在 Solon 适配上的支持
最后提交信息为:
fix: 无法解析 localhost 这类省略 http:// 的 url
v1.5.28
3ed96a2
2022-11-22 11:50
对比
v1.5.28
公子骏
v1.5.28版本发布了,此次版本发布是小版本更新,主要是修复一些BUG,并添加了`onBodyEncode`拦截器回调函数 #### 新增特性 - feat: 拦截器新增 onBodyEncode 回调函数 (#I4WF5Q) - feat: 隐式转换带 BasicAuth 认证信息的请求 (#I62BTW) - feat: 声明式接口可返回 `ForestFuture<T>` 类型 #### 修复问题 - fix: 下载文件,从URL中取得文件名时前后双引号的问题 (#I61NPK) - fix: 参数为空,导致空指针问题 ([110](https://github.com/dromara/forest/issues/110)) - fix: @HttpClient 和 @OkHttp3 注解在 1.5.27 失效的问题 - fix: SpringSSLKeyStore构造方法缺少参数导致SpringBoot项目启动失败 - fix: Null Pointer Error 当指定RetryWhen (#I5WEBC) - fix: @BaseRequest里的 connectTimeout和readTimeout没效果 (#I5WC6U) - fix: 接口上@Address注解的basePath设置为完整URL时,request.basePath() 结果不正确 #### 特别鸣谢 - @idevmo
最后提交信息为:
update: new version -> 1.5.28
下载
请输入验证码,防止盗链导致资源被占用
取消
下载
Java
1
https://gitee.com/dromara/forest.git
git@gitee.com:dromara/forest.git
dromara
forest
forest
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册