MyGit

v1.6.0

dromara/forest

版本发布时间: 2024-12-18 20:58:34

dromara/forest最新发布版本:v1.6.0(2024-12-18 20:58:34)

Forest v1.6.0 版本发布了!此次版本更新功能较多,新增了包括 SSE、Jsonpath、链式条件函数等新特性。

支持 SSE

此次最大的更新,主要是支持了 SSE,并且支持声名式编程式两种 SSE 接口

声明式 SSE 接口:

接口定义:

public interface SSEClient {
    // Forest SSE 控制器类作为 SSE 接口返回类型
    @Get("/sse")
    ForestSSE testSSE();
    
    // 自定义 SSE 控制器类作为 SSE 接口返回类型
    @Get("/sse")
    MySSEHandler testSSE2();

}

自定义 SSE 控制器类:

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.*\\}" 的要求
    }
}

接口调用:

// ForestSSE 作为返回值的接口调用
sseClient.testSSE().listen();
// 自定义 SSE 控制器作为返回值的接口调用
sseClient.testSSE().listen();
编程式 SSE 接口:
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(); // 开始监听

支持链式条件函数

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 注解

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 接口

TestUser user = Forest.get("http://localhost:{}/test/user", server.getPort())
        .executeAsResponse()
        .getByPath("$.data", TestUser.class);

安全流处理接口

Forest.get("http://localhost:{}/download/test-img.jpg", server.getPort())
        .executeAsStream((in, req, res) -> {
            // in 为已经打开的 InpuStream 流对象
            // 在这里不需要手动打开和关闭流
        });

大JSON数据的流式处理

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)
        });

新增特性

修复问题

代码改动

贡献者

相关地址:原始地址 下载(tar) 下载(zip)

查看:2024-12-18发行的版本