1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/dromara-forest

11.03.2025 04:31
GitLife Service Account

Объявлен выпуск версии Forest v1.6.4! В этом выпуске были внесены изменения в интерфейсы обработки сообщений SSE.

Устройство сообщений SSE

Сообщения SSE обычно имеют стандартный многострочный формат name:value, где каждое сообщение разделено пустыми строками. Пример:

id:1
event:json
data:{"name":"a"}
text:xxx

id:2
event:json
data:{"name":"b"}
text:yyy

Для этого стандарта можно использовать режим с многими строками (MULTI_LINES) или автоматический режим (AUTO).

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 автоматически распознает необходимый режим строк
sse.listen(); // по умолчанию режим строки AUTO

Кроме того, существуют различные нестандартные форматы сообщений SSE, такие как каждый JSON-объект на отдельной строке, представляющий собой отдельное сообщение.

{"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)`
- feat: Поддержка указания режима строк сообщений SSE, включая одиночный, множественный и автоматический режим

#### Исправленные проблемы

- fix: Проблема с непредвиденным шифрованием данных body из-за наличия пробелов в части `; charset=utf8` заголовка Content-Type
- fix: Проблема совместимости с предыдущими версиями Forest, связанная с отсутствием сигнатур методов get(url), post(url) и других в новой версии класса Forest, что приводило к ошибкам
Последнее сообщение коммита: add: ForestSSE.asyncListen(SSELinesMode linesMode, ExecutorService ...
11.03.2025 04:31
GitLife Service Account

Новые возможности

  • Добавлен метод EventSource.value(Class<T>)
  • Добавлен метод EventSource.value(TypeReference<T>)

Неразрывные изменения

  • Переработан метод SSEInterceptor.onSSEClose(EventSource) с параметром EventSource
  • Переработан метод ForestSSE.setOnClose(Consumer<EventSource>) с параметром EventSource
  • Переименован метод EventSource.getValue() в EventSource.value()
  • Переименован метод EventSource.getName() в EventSource.name()
  • Переименован метод EventSource.getRawData() в EventSource.rawData()

Другие изменения

  • Обновлены зависимости версий
Последнее сообщение коммита: update: version 1.6.3
11.03.2025 04:31
GitLife Service Account

Версия Forest v1.6.2 выпущена! В этом выпуске были исправлены проблемы, связанные с JsonPath и SSE, а также добавлены новые методы для управления SSE.

Новые возможности

  • feat: Добавлен метод ForestSSE.close() для закрытия слушателя
  • feat: Добавлен метод ForestSSE.await() для блокирующего ожидания завершения асинхронного прослушивания

Исправленные ошибки

  • fix: Проблема с некорректным закрытием SSE через EventSource.close()
  • fix: Ошибка при получении простых типов данных через JsonPath
Последнее сообщение коммита: fix: 通过JsonPath获取基本类型字段错误
11.03.2025 04:30
GitLife Service Account

Релиз версии Forest v1.6.1! В этом выпуске были исправлены проблемы, связанные с SSE, а также добавлен SSE-интерцептор.

SSE-интерцептор

Контроллер ForestSSE и пользовательский контроллер SSE являются независимыми объектами, которые не являются одиночками, поэтому они не могут быть внедрены в контексте Spring и использоваться для доступа к ресурсам контекста.

Интерфейс SSE-интерцептора SSEInterceptor, который расширяется от интерцептора Interceptor, может быть внедрен в контексте Spring и использовать бины этого контекста, но как и обычные интерцепторы, он является одиночкой и не может использовать поля класса для передачи данных между вызовами.

@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
    }
}

Способ привязки аналогичен способу привязки обычного интерцептора:

@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
11.03.2025 04:30
GitLife Service Account

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 аннотация используется для указания значения события
    }

    @SSEEventMessage(valueRegex = "\\{.*name.*\\}")
    public void onEvent(@SSEValue Contact contact) {
        // Отслеживает событие с названием "event"
        // И сообщение должно удовлетворять регулярному выражению "\\{.*name.*\\}"
    }
}

Вызов интерфейса:

// Вызов интерфейса с ForestSSE в качестве типа возвращаемого значения
sseClient.testSSE().listen();

// Вызов интерфейса с кастомным SSE контроллером в качестве типа возвращаемого значения
sseClient.testSSE2().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(); // Начало прослушивания

Поддержка цепочного условия

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", 100))       // [Если 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();```java
@Test
public void testGetListOfUserAges() {
    @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 — это уже открытый объект InputStream
            // здесь нет необходимости вручную открывать и закрывать поток
        });

Потоковая обработка больших 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);
        });

Новые возможности

  • feat: Поддержка SSE
  • feat: Цепочное условие
  • feat: Поддержка JsonPath
  • feat: Теперь строки шаблонов могут использовать {} вместо {число} в качестве местоположителей аргументов
  • feat: Добавлен уровень класса @BindingVar аннотация
  • feat: Адаптация логгирования для Android среды
  • feat: Добавлена новая функция обратного вызова жизненного цикла onResponse
  • feat: Поддержка Optional как типа возвращаемого значения интерфейсов
  • feat: Поддержка CompletableFuture как типа возвращаемого значения интерфейсов
  • feat: Возможность использования пользовательского LogHandler, внедренного через Spring Beans
- feat: добавление нового интерфейса для безопасной обработки потока ответов#### Исправление проблем
- fix: исправлено проблему с кодировкой процентных символов с помощью URLEncode
- fix: исправлено невозможность переопределения свойства аннотации `@Address`
- fix: исправлено невозможность вызова фильтрационных функций
- fix: исправлено возможную ошибку при закрытии пула соединений
- fix: исправлено ошибку вывода content-type как multipart/form-data, когда body имеет другой тип
- fix: исправлено недействие метода setReturnType в onMethodInitialized (#I8PJ9R)
- fix: исправлено выход за границы стека из-за отсутствия восстановления parentScope (#I9TP9Z)

#### Изменение кода
- update: заменено кэширование Hutool LRU кэшем
- update: обновлен плагин forest-solon-plugin до версии Solon 3.0.1 (совместимость с 2.5.9+)
- update: обновлены зависимости до последней стабильной версии
- refactor: добавлена возможность вывода информации о статусе при ошибке Response: [Network Error]
- opt: добавлена thread-safe поддержка запросов
- reflector: рефакторинг интерфейса ForestAuthenticator
- refactor: рефакторинг логики обработки потока ответов
- add: добавлен метод openStream в ResultGetter
- refactor: изменён формат сообщений об ошибках выражений

#### Вкладчики
- @wittplus (witt)
- @Kiroe (Kiro)
- @noear_admin (Запад)
Последнее сообщение коммита: test: 安全响应流处理接口
11.03.2025 04:29
GitLife Service Account

Forest v1.5.36 версия выпущена! В этом выпуске основное внимание уделено поддержке Fastjson2 и обновлению версий Solon.

Новые возможности

  • feat: Поддержка Fastjson2

Исправленные проблемы

  • fix: В backend okhttp response.getContentLength() возвращает пустое значение (#I90MUX)
  • fix: Ошибка при конвертации Lazy Map в конвертере Jackson

Изменения в коде

  • Update: Обновление Solon до версии v2.6.5
  • refactor: Отказ от использования методов из пакета okio при генерации строки разделителя multipart
Последнее сообщение коммита: test: jackson兼容问题
11.03.2025 04:28
GitLife Service Account

v1.5.35 версия выпущена! В этой версии были реализованы возможности конфигурирования размера и времени жизни кеша клиентских объектов в бэкенд.

Настройка кеша клиента бэкэнда

Настройте максимальный размер кеша и время его истечения.

forest:
  backend-client-cache-max-size: 512      # Максимальный размер кеша клиента бэкэнда (в единицах экземпляров; значение по умолчанию — 128)
  backend-client-cache-expire-time: 3h    # Время истечения кеша клиента бэкэнда (в единицах времени; значение по умолчанию — 6 часов)

Новые возможности:

  • feat: возможность конфигурирования размера и времени жизни кеша клиентских объектов в бэкенд.
Последнее сообщение коммита: update: new version 1.5.35
11.03.2025 04:28
GitLife Service Account

версия v1.5.34 выпущена! В этом выпуске исправлена проблема увеличивающегося потребления памяти при множественных запросах к различным доменам, используя кэширование Caffeine как бэкенд для клиентского кэша.

Исправленные проблемы

  • fix: При множественных запросах к различным доменам увеличивалось потребление памяти (#I8J5PN)
  • fix: В условиях высокой конкуренции отслеживание значения runningPoolSize привело к появлению отрицательных значений и ситуации, когда все запросы завершены, но значение не возвращается к нулю (#I8JNBU)
  • fix: Улучшение юнит-тестов для исправления объявленного интерфейса @BaseRequest или @BaseURL, где полное URL-адрес метода без указания порта заменяется портом базового адреса вместо использования порта по умолчанию 80
  • fix: Исправление ошибки, когда baseUrl и url в @Get() не могут корректно склеиться, независимо от того, используется ли @Address или @BaseRequest (#I7CAYS)
  • fix: Обработка ошибки, возникающей при наличии / в конце basePath аннотации @Addrees и отсутствие / в начале URL метода, что приводит к двум последовательным слешам в итоговом адресе
  • fix: Конфликт класса MultipartRequestBody (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
11.03.2025 04:28
GitLife Service Account

Forest v1.5.33 выпущена. В этом выпуске основное внимание уделено поддержке прокси SOCKS и переопределению свойств объединённых аннотаций.

Новые возможности:

  • feat: Поддержка прокси SOCKS (#I6MLMD)
  • feat: Объединённые аннотации поддерживают переопределение свойств

Исправленные проблемы:

  • fix: Аннотация @Body с массивом параметров некорректно парсится в JSON-массив (#I7UPBR)
  • fix: При Content-Type application/xml отправка байтового массива данных ошибочна (#I7F3F0)
  • fix: Аннотация @JSONBody, коллекция 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
  • Устранение проблемы #I7QLTS выполнено @Angle94

Как использовать новые возможности:

Последнее сообщение коммита: test: 1.5.33
11.03.2025 04:27
GitLife Service Account

в версии v1.5.32 были внесены исправления! Основной акцент сделан на устранение некоторых ошибок.

Исправленные проблемы:

  • fix: Ошибка при передаче ленивой лямбды в параметре @Header (#I7EIAB)
  • fix: URLEncoder не может закодировать символ процента (%) (134)

Изменения в коде:

opt: Оптимизация параллелизма при инициализации асинхронного пула потоков

Последнее сообщение коммита: update: version 1.5.32
11.03.2025 04:27
GitLife Service Account

Forest v1.5.31 выпущена! Этот выпуск является небольшим обновлением, в котором были исправлены некоторые ошибки.

Новые возможности

  • feat: Все запросы Forest теперь по умолчанию содержат заголовок User-Agent: forest/{версия}

Исправленные проблемы

  • fix: Управление версий JDK для различных модулей Maven
  • fix: Возможность загрязнения параметров при создании клиентских экземпляров с использованием разных объектов ForestConfiguration
  • fix: Ошибка при установке свойства schema атрибута @Address как https (#I6Y6E2)
  • fix: Небезопасное использование метода ReflectUtils.getFields (#I6W9TF)

Изменения в коде

  • opt: Инициализация ForestMethod теперь происходит ленивой загрузкой
  • refactor: Использование ревизий для управления версиями нескольких модулей
  • refactor: Атрибут interceptor аннотации запроса принимает только классы, реализующие интерфейс Interceptor
  • add: Добавлено поле Forest.VERSION, которое позволяет динамически получать номер версии Forest
Последнее сообщение коммита: feat: 所有 Forest 请求默认带上 User-Agent: forest/version 的请求头
11.03.2025 04:27
GitLife Service Account

версия v1.5.30 была выпущена с существенными изменениями. Теперь она поддерживает и адаптирована к Spring Boot 3 и Solon. В новой версии XML-модуль был вынесен в отдельный модуль, а также были добавлены возможности задержки параметров.

Адаптация к Spring Boot 3

В проекте добавлен модуль forest-spring-boot3-starter, при интеграции которого следует использовать следующие зависимости:

<!-- Модуль Forest для Spring Boot 3 -->
<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>

Для старых версий Spring Boot зависимость остаётся практически такой же, но XML-модуль теперь требует дополнительной зависимости:

<!-- Модуль Forest для Spring Boot 1 или 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. При интеграции этого модуля следует использовать следующую зависимость:

<!-- Модуль Forest для Solon -->
<dependency>
    <groupId>com.dtflys.forest</groupId>
    <artifactId>forest-solon-plugin</artifactId>
    <version>1.5.30</version>
</dependency>
```<!-- Одним из JSON-фреймворков может быть Fastjson, Jackson или Gson -->
<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](https://gitee.com/dromara/forest/tree/master/forest-examples).

#### Об XML-модуле
В этой версии функции сериализации и десериализации XML были перемещены из основного модуля `forest-core` в отдельные модули Forest XML. Выбор конкретного модуля зависит от специфики вашего проекта. Если проект является обычным проектом, не использующим Spring Boot 3 (например, Spring, Spring Boot 1 или 2) с версией JDK ниже 17, то следует использовать зависимость `forest-jaxb`.

```xml
<!-- Поддержка модулей Forest JAXB -->
<dependency>
    <groupId>com.dtflys.forest</groupId>
    <artifactId>forest-jaxb</artifactId>
    <version>1.5.30</version>
</dependency>

Если ваш проект использует Spring Boot 3 или имеет версию JDK 17 или выше, выберите зависимость forest-jakarta-xml.

<!-- Поддержка модулей Jakarta XML в Forest -->
<dependency>
    <groupId>com.dtflys.forest</groupId>
    <artifactId>forest-jakarta-xml</artifactId>
    <version>1.5.30</version>
</dependency>
```#### Опоздание параметров (Параметры lambda)
Существуют ситуации, когда значения параметров заголовков, запросов или тела могут быть получены только непосредственно перед отправкой запроса. Примером может служить ситуация с цифровой подписью (добавление параметра `token` в заголовок, значение которого является результатом шифрования всего тела).- Опоздание параметров заголовка
```java
Forest.post("/test")
        .addHeader("Content-Type", "application/json; charset=UTF-8")
        // Здесь передается лямбда-выражение, которое будет выполнено за доли секунды до отправки запроса
        // Это вычисляет значение, сериализуя весь тело запроса и применяя базовый шифр Base64, затем передает его в заголовок Authorization
        .addHeader("Authorization", req -> Base64.encode("Token=" + req.body().encodeToString()))
        .addBody("id", "1972664191")
        .addBody("name", "XieYu20011008")
        .execute();
  • Опоздание параметров тела
Forest.post("/test")
        .addHeader("Content-Type", "application/json; charset=UTF-8")
        .addHeader("_id", "20011008")
        .addBody("id", "1972664191")
        // Здесь также передается лямбда-выражение, которое будет выполнено за доли секунды до отправки запроса
        // Процесс выполнения и принцип работы аналогичны тому, что был описан выше
        .addBody("name", req -> "Foo" + req.headerValue("_id"))
        .addBody("token", req -> Base64.encode(req.body().encode()))
        .execute();

Здесь процесс сериализации тела запроса, вызываемый в лямбда-выражении req.body().encode(), автоматически исключает само это лямбда-выражение, поэтому нет необходимости беспокоиться о возникновении бесконечной рекурсии.#### Новые возможности

  • feat: Поддержка Spring Boot 3
  • feat: Поддержка Solon
  • feat: Добавлена поддержка отложенного вычисления параметров с задержкой (Lambda параметры) для параметров запроса, заголовков и тела запроса.
  • feat: Введен выборочный подход к определению стратегий отказа для пула асинхронных запросов.
  • feat: Реализован интерфейс сериализации тела запроса, ForestRequest.body.encode() и ForestRequest.body.encodeToString().

Исправление проблем

  • fix: #I63WWN Проблема с добавлением заголовков в ForestProxy.
  • fix: Неправильный порядок жизненного цикла при кодировании тела запроса.
  • fix: Проблема использования одного общего пула асинхронных потоков различными объектами ForestConfiguration.
  • fix: Невозможность парсинга URL типа localhost:8080 без явной указания протокола http://.

Другие изменения

  • reflector: Разделение модуля XML парсера на два подмодуля forest-jaxb и forest-jakarta-xml, требуется в случае самостоятельного импорта.
  • reflector: Кодировщик тела запроса.
  • refactor: Клонирование тела запроса в Forest.
  • refactor: Улучшение процесса сборки строки запроса.
  • add: Добавлено свойство headers аннотации HTTPProxy.
  • add: Пример проекта для Forest.

Благодарности

Отдельная благодарность автору Solon (@noear_admin) за поддержку проекта Forest в адаптации к Solon.

Последнее сообщение коммита: fix: 无法解析 localhost 这类省略 http:// 的 url
11.03.2025 04:26
GitLife Service Account

версия v1.5.28 выпущена. Это небольшой выпуск, в котором были исправлены некоторые ошибки и добавлена функция обратного вызова onBodyEncode для промежуточных модулей.

Новые возможности

  • feat: Добавлена функция обратного вызова onBodyEncode для промежуточных модулей (#I4WF5Q)
  • feat: В запросах с BasicAuth авторизацией теперь происходит неявное преобразование (#I62BTW)
  • feat: Объявленные интерфейсы могут вернуть тип ForestFuture<T>

Исправленные проблемы

  • fix: При скачивании файла возникали проблемы с двойными кавычками в имени файла, полученном из URL (#I61NPK)
  • fix: При отсутствии параметров возникала ошибка NullPointerException (110)
  • fix: Проблема с аннотациями @HttpClient и @OkHttp3, которая была недействительна в версии 1.5.27
  • fix: Ошибка при старте проекта Spring Boot из-за отсутствия аргументов в конструкторе SpringSSLKeyStore
  • fix: Ошибка NullPointerException при указании #RetryWhen (#I5WEBC)
  • fix: Аннотация @BaseRequest не работала для connectTimeout и readTimeout (#I5WC6U)
  • fix: При использовании полной URL-страницы в аннотации @Address, метод request.basePath() давал неверный результат

Отдельное спасибо

  • @idevmo
Последнее сообщение коммита: update: new version -> 1.5.28
11.03.2025 04:25
GitLife Service Account

версия v1.5.27 была выпущена. В этой версии были исправлены некоторые ошибки, а также добавлена поддержка корутин Kotlin, усилены API асинхронных запросов и получения ответных данных.

Новые возможности

  • feat: Усиление асинхронных API, теперь поддерживаются Async/Await стили (#I60IAL)
  • feat: Усиление API ответов, теперь есть возможность преобразования выходных данных (#I60IDO)
  • feat: Поддержка корутин Kotlin
  • feat: Возможность прерывания выполнения запроса (#I60I90)

Исправленные проблемы

  • fix: При использовании ForestHeaderMap.addCookie может возникнуть проблема с отсутствием заголовков (100)
  • fix: При отправке запроса multipart/form-data, если параметр @Body пустой, будет выдано сообщение об ошибке (#I5Y7WJ)
  • fix: При вызове ForestRequest.getQueryString(), если не установлен charset, будет выдано сообщение об ошибке (#I5RGX4)
  • fix: ForestRequest.getBasePath() не может получить basePath, определённый в AddressSource (#I5RGOY)
  • fix: Для запросов в формате x-www-form-urlencoded при URL-кодировании игнорируется символ #
  • fix: При повторной попытке запроса не происходит закрытие предыдущего ответа

Отдельное спасибо

Последнее сообщение коммита: comment: 修改注释以符合Javadoc规范
11.03.2025 04:25
GitLife Service Account

Forest v1.5.26 версия выпущена! В этом выпуске были внесены исправления нескольких ошибок.

Новые возможности

  • feat: Разрешено использование нерасшифрованных фигурных скобок в параметрах запроса при использовании бэкэнда OkHttp3 (#I5ITW9)
  • feat: Обход ошибки пустого Multipart при использовании OkHttp3 (#I5I1AC)

Исправленные проблемы

  • fix: По умолчанию автоматически отключается проверка SSL-сертификата
  • fix: При указании типа возвращаемых данных как String (или других типов CharSequence) возникали проблемы с пользовательским конвертером (#I5L2P6)
  • fix: Бэкенд Okhttp автоматически преобразует charset=UTF-8 в нижний регистр (#I5L4AS)
  • fix: Автоматическое добавление пути "/ " к параметрам доменного имени URL приводит к ошибкам (#I5I62P)
  • fix: Символ $ в пути URL будет экранироваться
  • fix: Атрибут ssl ForestURL запроса не наследуется из @BaseRequest класса (#I5HXHX)

Другие изменения

  • update: Обновлено до версии Spring 5.3.19
  • update: Обновлено до версии Spring Boot 2.6.7
Последнее сообщение коммита: update: new version 1.5.26
11.03.2025 04:25
GitLife Service Account

Лес v1.5.25 версия выпущена!

Исправленные проблемы

  • fix: Валидация безопасной cookie при сравнении
  • fix: Недостаточная передача cookie в запросах (#I5F8IY)
  • fix: Проблема утечки соединений в OKHTTP (#I5E613)
  • fix: Лес не может запуститься с Spring Boot 1.5.14.release (#I5FDBG)
  • fix: При передаче параметров с символом "+", он преобразуется в пробелы на стороне сервера (#I5EG9L)

Другие изменения

  • add: OkHttp3Cookie
  • add: HttpClientCookie
  • update: Обновление версии Jackson до 2.13.3
  • update: Обновление версии Jackson-databind до 2.13.3
  • update: Обновление версии Jackson-annotations до 2.13.3
  • update: Обновление версии Gson до 2.8.9
  • update: Обновление версии FastJson до 1.2.83
Последнее сообщение коммита: update: 更新jackson版本到2.13.3
11.03.2025 04:25
GitLife Service Account

Forest v1.5.24 версия выпущена! В этом выпуске были исправлены некоторые ошибки.

Исправление ошибок

  • fix: Исправлена проблема с утечкой соединений в OKHTTP (#I5E613)
  • fix: При встрече непарсимого cookie отображается NullPointerException (#I5E27R)
Последнее сообщение коммита: update: new version 1.5.24
11.03.2025 04:25
GitLife Service Account

Релиз версии Forest v1.5.23! В этом выпуске была проведена глобальная оптимизация производительности выполнения запросов!

Увеличение пропускной способности запросов (QPS) для backend-клиента OkHttp3 более чем в три раза!

Увеличение пропускной способности запросов (QPS) для backend-клиента HttpClient более чем в два раза!

Оптимизации

  1. Введено понятие маршрута ForestRoute, где каждое уникальное сочетание Host + Port соответствует отдельному маршруту.
  2. Backend-клиенты OkHttpClient и HttpClient объединены и закэшированы в различных маршрутах.
  3. Возможность внедрения пользовательских объектов backend-клиента извне.
  4. Кэширование backend-клиента интерфейса является опциональным и может быть настроено с помощью аннотации @BackendClient.

Новые возможности

  • feat: Поддержка быстрого скачивания файлов через интерфейсы
  • feat: Настройка внедрения объектов OkHttpClient и HttpClient (#I5CWAL)
  • feat: Настройка кэширования backend-клиента интерфейсов (#I5D818)

Исправленные ошибки- fix: Неудачная инициализация конвертера бинарных данных при использовании конфигурации Spring Boot (#I5D07S)

  • fix: Появление NullPointerException при вызове метода ForestResponse.statusIs(xxx) (#I5CWQL)

  • fix: Утрата действительности базового пути basePath при использовании аннотации @Address (#I5CR15)

  • fix: Исключение java.lang.IllegalArgumentException: Socket может не быть null при использовании аннотации @HTTPProxy для установки HTTP-прокси для HTTPS-запросов

  • fix: Невозможность отправки запросов без указания ContentType и BodyType (#I5CML4)

  • fix: Выполнение метода ForestRequest.addBody(List) один раз вместо каждого цикла#### Изменения кода

  • refactor: Переработка Cookie (#I5C26U)

  • refactor: Переработка OkHttpClient

  • add: Добавление метода ForestRequest#addInterceptor(Class<? extends Interceptor>) для добавления interceptors к запросам

  • add: Добавление HttpClientFactory

  • add: Добавление OkHttpClientFactory

Отдельное спасибо

  • @CHMing
  • @tanglinyan
Последнее сообщение коммита: update: 去掉不用的import
11.03.2025 04:24
GitLife Service Account

Версия 1.5.22 выпущена! В этом выпуске были исправлены проблемы с унифицированным пулом соединений, а также начата поддержка Kotlin, совместимость с версиями Spring 4.x и ниже.

Основные изменения

Унифицированный пул соединений

Ранее версии конфигурационные свойства max-connections и max-route-connections были настроены для пулов соединений бэкенд-фреймворков OkHttp3 и HttpClient. Это приводило к тому, что запросы от разных бэкендов находились в различных пулах соединений, которые были изолированы друг от друга, и невозможно было установить единое ограничение максимального количества соединений.

Кроме того, ограничение на количество запросов в OkHttp3 находится внутри компонента Dispatcher, который привязывается непосредственно к объекту OkHttpClient, поэтому его сложно настраивать и управлять. Таким образом, свойства max-connections и max-route-connections фактически не действуют для OkHttp3.

Новый унифицированный пул соединений позволяет через свойства max-connections и max-route-connections управлять максимальным количеством запросов и максимальным количеством запросов на маршрут для всех бэкендов OkHttp и HttpClient, включая асинхронные запросы.##### Определение типа возвращаемого значения
Добавлена аннотация @Return, которая используется для указания параметра как возвращаемого значения.

/**
 * Использует тип Class для определения типа возвращаемого значения
 *
 * @param clazz Тип возвращаемого значения
 * @return экземпляр типа, указанного параметром clazz
 * @param <T> неопределённый параметр типа, конкретизируется передачей параметра clazz
 */
@Get("/")
<T> T getGenericClass(@Return Class<T> clazz);
```/**
 * Использует тип Type для определения типа возвращаемого значения
 *
 * @param type Тип возвращаемого значения
 * @return Экземпляр типа, указанного параметром type
 * @param <T> Непредопределённый параметр типа, конкретизируется передачей параметра type
 */
@Get("/")
<T> T getGenericType(@Return Type type);

/**
 * Использует тип TypeReference для определения типа возвращаемого значения
 *
 * @param typeReference Тип возвращаемого значения
 * @return Экземпляр типа, указанного параметром typeReference
 * @param <T> Непредопределённый параметр типа, конкретизируется передачей параметра typeReference
 */
@Get("/")
<T> T getGenericTypeReference(@Return TypeReference<T> typeReference);

Новые возможности

  • feat: Унифицированный пул соединений (#I5APJA)
  • feat: Настройка размера очереди пула потоков для асинхронных запросов (#I5B78X)
  • feat: Поддержка определения типа возвращаемого значения через параметры (#I5ANZL)#### Исправленные ошибки
  • fix: Проблемы с Spring 5.1 В нижеуказанных более ранних версиях произошел сбой при запуске
    • исправление: запрос, адрес которого содержит символ #, будет экранироваться, что приведёт к невозможности найти ресурс (#I59O7M)
    • исправление: после конфигурирования свойства baseURL в BaseRequest полный путь запроса с дефолтным портом будет перезаписан, что вызывает ошибку запроса (#I4YBDV)
    • исправление: решена проблема передачи атрибутов типа char и Character объектами, помеченными аннотацией @Body, от клиента до сервера
    • исправление: возникающие при старте проекта на Kotlin исключения (#I50PDZ)
    • исправление: условие повторной попытки RetryWhen выполняется дважды после последней попытки повтора (#I599BT)#### Другие изменения
  • обновление: удаление зависимости log4j2 из тестовых случаев (#I5ANZR)

Отдельное спасибо

Участникам, внесшим свой вклад в этот выпуск

  • @fangzhengjin
  • @xiao4852
Последнее сообщение коммита: feat: #I5APJA 统一连接池
11.03.2025 04:23
GitLife Service Account

версия v1.5.21 выпущена!

Основные изменения в этой версии направлены на исправление ошибок при парсинге URL в некоторых случаях, а также добавлена поддержка ручной URLEncode для шаблонов строк.

Новые возможности

  • feat: поддержка ручной URLEncode для шаблонов строк (#I58D1C)

Исправленные баги

  • fix: исправление ошибок парсинга URL в некоторых сценариях (#I56XDM)
Последнее сообщение коммита: fix: query url encode
1
https://api.gitlife.ru/oschina-mirror/dromara-forest.git
git@api.gitlife.ru:oschina-mirror/dromara-forest.git
oschina-mirror
dromara-forest
dromara-forest