A high-level and lightweight HTTP client framework for Java. it makes sending HTTP requests in Java easier.

Related tags

forest
Overview

logo

Gitee Stars JDK Codecov License Documentation Author

Forest - 轻量级HTTP客户端框架

项目介绍:

Forest是一个高层的、极简的轻量级HTTP调用API框架。
相比于直接使用Httpclient您不再用写一大堆重复的代码了,而是像调用本地方法一样去发送HTTP请求。

文档和示例:

Forest有哪些特性?

  • 以Httpclient和OkHttp为后端框架
  • 通过调用本地方法的方式去发送Http请求, 实现了业务逻辑与Http协议之间的解耦
  • 因为针对第三方接口,所以不需要依赖Spring Cloud和任何注册中心
  • 支持所有请求方法:GET, HEAD, OPTIONS, TRACE, POST, DELETE, PUT, PATCH
  • 支持文件上传和下载
  • 支持灵活的模板表达式
  • 支持拦截器处理请求的各个生命周期
  • 支持自定义注解
  • 支持OAuth2验证
  • 支持过滤器来过滤传入的数据
  • 基于注解、配置化的方式定义Http请求
  • 支持Spring和Springboot集成
  • JSON字符串到Java对象的自动化解析
  • XML文本到Java对象的自动化解析
  • JSON、XML或其他类型转换器可以随意扩展和替换
  • 支持JSON转换框架: Fastjson, Jackson, Gson
  • 支持JAXB形式的XML转换
  • 可以通过OnSuccess和OnError接口参数实现请求结果的回调
  • 配置简单,一般只需要@Request一个注解就能完成绝大多数请求的定义
  • 支持异步请求调用

极速开始

以下例子基于Spring Boot

第一步:添加Maven依赖

直接添加以下maven依赖即可

<dependency>
    <groupId>com.dtflys.forestgroupId>
    <artifactId>forest-spring-boot-starterartifactId>
    <version>1.5.0-RC6version>
dependency>

第二步:创建一个interface

就以高德地图API为栗子吧

package com.yoursite.client;

import com.dtflys.forest.annotation.Request;
import com.dtflys.forest.annotation.DataParam;

public interface AmapClient {

    /**
     * 聪明的你一定看出来了@Get注解代表该方法专做GET请求
     * 在url中的${0}代表引用第一个参数,${1}引用第二个参数
     */
    @Get("http://ditu.amap.com/service/regeo?longitude=${0}&latitude=${1}")
    Map getLocation(String longitude, String latitude);
}

第三步:扫描接口

在Spring Boot的配置类或者启动类上加上@ForestScan注解,并在basePackages属性里填上远程接口的所在的包名

@SpringBootApplication
@Configuration
@ForestScan(basePackages = "com.yoursite.client")
public class MyApplication {
  public static void main(String[] args) {
      SpringApplication.run(MyApplication.class, args);
   }
}

第四步:调用接口

OK,我们可以愉快地调用接口了

// 注入接口实例
@Autowired
private AmapClient amapClient;
...
// 调用接口
Map result = amapClient.getLocation("121.475078", "31.223577");
System.out.println(result);

发送JSON数据

/**
 * 将对象参数解析为JSON字符串,并放在请求的Body进行传输
 */
@Post("/register")
String registerUser(@JSONBody MyUser user);

/**
 * 将Map类型参数解析为JSON字符串,并放在请求的Body进行传输
 */
@Post("/test/json")
String postJsonMap(@JSONBody Map mapObj);

/**
 * 直接传入一个JSON字符串,并放在请求的Body进行传输
 */
@Post("/test/json")
String postJsonText(@JSONBody String jsonText);

发送XML数据

/**
 * 将一个通过JAXB注解修饰过的类型对象解析为XML字符串
 * 并放在请求的Body进行传输
 */
@Post("/message")
String sendXmlMessage(@XMLBody MyMessage message);

/**
 * 直接传入一个XML字符串,并放在请求的Body进行传输
 */
@Post("/test/xml")
String postXmlBodyString(@XMLBody String xml);

文件上传

/**
 * 用@DataFile注解修饰要上传的参数对象
 * OnProgress参数为监听上传进度的回调函数
 */
@Post("/upload")
Map upload(@DataFile("file") String filePath, OnProgress onProgress);

可以用一个方法加Lambda同时解决文件上传和上传的进度监听

Map result = myClient.upload("D:\\TestUpload\\xxx.jpg", progress -> {
    System.out.println("progress: " + Math.round(progress.getRate() * 100) + "%");  // 已上传百分比
    if (progress.isDone()) {   // 是否上传完成
        System.out.println("--------   Upload Completed!   --------");
    }
});

多文件批量上传

/**
 * 上传Map包装的文件列表,其中 ${_key} 代表Map中每一次迭代中的键值
 */
@Post("/upload")
ForestRequest<Map> uploadByteArrayMap(@DataFile(value = "file", fileName = "${_key}") Map<String, byte[]> byteArrayMap);

/**
 * 上传List包装的文件列表,其中 ${_index} 代表每次迭代List的循环计数(从零开始计)
 */
@Post("/upload")
ForestRequest<Map> uploadByteArrayList(@DataFile(value = "file", fileName = "test-img-${_index}.jpg") List byteArrayList);

文件下载

下载文件也是同样的简单

/**
 * 在方法上加上@DownloadFile注解
 * dir属性表示文件下载到哪个目录
 * OnProgress参数为监听上传进度的回调函数
 * ${0}代表引用第一个参数
 */
@Get("http://localhost:8080/images/xxx.jpg")
@DownloadFile(dir = "${0}")
File downloadFile(String dir, OnProgress onProgress);

调用下载接口以及监听下载进度的代码如下:

File file = myClient.downloadFile("D:\\TestDownload", progress -> {
    System.out.println("progress: " + Math.round(progress.getRate() * 100) + "%");  // 已下载百分比
    if (progress.isDone()) {   // 是否下载完成
        System.out.println("--------   Download Completed!   --------");
    }
});

基本签名验证

@Post("/hello/user?username=${username}")
@BasicAuth(username = "${username}", password = "bar")
String send(@DataVariable("username") String username);

OAuth 2.0

@OAuth2(
        tokenUri = "/auth/oauth/token",
        clientId = "password",
        clientSecret = "xxxxx-yyyyy-zzzzz",
        grantType = OAuth2.GrantType.PASSWORD,
        scope = "any",
        username = "root",
        password = "xxxxxx"
)
@Get("/test/data")
String getData();

自定义注解

Forest允许您根据需要自行定义注解,不但让您可以简单优雅得解决各种需求,而且极大得扩展了Forest的能力。

定义一个注解

/**
 * 用Forest自定义注解实现一个自定义的签名加密注解
 * 凡用此接口修饰的方法或接口,其对应的所有请求都会执行自定义的签名加密过程
 * 而自定义的签名加密过程,由这里的@MethodLifeCycle注解指定的生命周期类进行处理
 * 可以将此注解用在接口类和方法上
 */
@Documented
/** 重点: @MethodLifeCycle注解指定该注解的生命周期类*/
@MethodLifeCycle(MyAuthLifeCycle.class)
@RequestAttributes
@Retention(RetentionPolicy.RUNTIME)
/** 指定该注解可用于类上或方法上 */
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAuth {

    /** 
     * 自定义注解的属性:用户名
     * 所有自定注解的属性可以在生命周期类中被获取到
     */
    String username();

    /** 
     * 自定义注解的属性:密码
     * 所有自定注解的属性可以在生命周期类中被获取到
     */
    String password();
}

定义注解生命周期类

/**
 *  MyAuthLifeCycle 为自定义的 @MyAuth 注解的生命周期类
 * 因为 @MyAuth 是针对每个请求方法的,所以它实现自 MethodAnnotationLifeCycle 接口
 * MethodAnnotationLifeCycle 接口带有泛型参数
 * 第一个泛型参数是该生命周期类绑定的注解类型
 * 第二个泛型参数为请求方法返回的数据类型,为了尽可能适应多的不同方法的返回类型,这里使用 Object
 */
public class MyAuthLifeCycle implements MethodAnnotationLifeCycle<MyAuth, Object> {

 
    /**
     * 当方法调用时调用此方法,此时还没有执行请求发送
     * 次方法可以获得请求对应的方法调用信息,以及动态传入的方法调用参数列表
     */
    @Override
    public void onInvokeMethod(ForestRequest request, ForestMethod method, Object[] args) {
        System.out.println("Invoke Method '" + method.getMethodName() + "' Arguments: " + args);
    }

    /**
     * 发送请求前执行此方法,同拦截器中的一样
     */
    @Override
    public boolean beforeExecute(ForestRequest request) {
        // 通过getAttribute方法获取自定义注解中的属性值
        // getAttribute第一个参数为request对象,第二个参数为自定义注解中的属性名
        String username = (String) getAttribute(request, "username");
        String password = (String) getAttribute(request, "password");
        // 使用Base64进行加密
        String basic = "MyAuth " + Base64Utils.encode("{" + username + ":" + password + "}");
        // 调用addHeader方法将加密结构加到请求头MyAuthorization中
        request.addHeader("MyAuthorization", basic);
        return true;
    }

    /**
     * 此方法在请求方法初始化的时候被调用
     */
    @Override
    public void onMethodInitialized(ForestMethod method, BasicAuth annotation) {
        System.out.println("Method '" + method.getMethodName() + "' Initialized, Arguments: " + args);
    }
}

使用自定义的注解

/**
 * 在请求接口上加上自定义的 @MyAuth 注解
 * 注解的参数可以是字符串模板,通过方法调用的时候动态传入
 * 也可以是写死的字符串
 */
@Get("/hello/user?username=${username}")
@MyAuth(username = "${username}", password = "bar")
String send(@DataVariable("username") String username);

详细文档请看:http://forest.dtflyx.com/

贡献者列表

Giteye chart 正因为有他们的贡献,Forest才得以走下去

联系作者

亲,进群前记得先star一下哦~

扫描二维码关注公众号,点击菜单中的 进群 按钮即可进群

avatar

Gitee上的Star趋势图

Giteye chart

参与贡献

  1. 进群讨论,可以在群里抛出您遇到的问题,或许已经有人解决了您的问题。
  2. 提issue,如果在gitee的issue中已经有您想解决的问题,可以直接将该issue分配给您自己。如若没有,可以自己在gitee上创建一个issue。
  3. Fork 本项目的仓库
  4. 新建分支,如果是加新特性,分支名格式为feat_${issue的ID号},如果是修改bug,则命名为fix_${issue的ID号}
  5. 本地自测,提交前请通过所有的已经单元测试,以及为您要解决的问题新增单元测试。
  6. 提交代码
  7. 新建 Pull Request
  8. 我会对您的PR进行验证和测试,如通过测试,我会合到dev分支上随新版本发布时再合到master分支上。

欢迎小伙伴们多提issue和PR,被接纳PR的小伙伴我会列在README上的贡献者列表中:)

项目协议

The MIT License (MIT)

Copyright (c) 2016 Jun Gong

Issues
  • @OAuth2 注解可配置化

    @OAuth2 注解可配置化

    场景

    项目是spring boot,@OAuth2 中的的配置信息需要做到配置化,如果再代码中硬编码灵活性太差。于是想通过forest变量来解决,如下

    @OAuth2(
        tokenUri = "${testaouth2.tokenUri}",
        clientId = "${testaouth2.clientId}",
        clientSecret = "${testaouth2.clientSecret}",
        grantType = OAuth2.GrantType.PASSWORD,
        scope = "${testaouth2.scope}",
        username = "${testaouth2.username}"
        password = "${testaouth2.password}"
    )
    

    问题

    grantType 是一个枚举,如何做到外部传参呢?

    opened by John-Chan 5
  • 使用httpclient作为实现时,是否可配置httpclient原生的HttpRequestInterceptor

    使用httpclient作为实现时,是否可配置httpclient原生的HttpRequestInterceptor

    如题,希望可支持配置httpclient原生的HttpRequestInterceptor

    opened by qiangbro 2
  • 文件上传接收json格式返回数据 默认的okhttp3可以接收并解析,httpclient接收的数据为content中的数据。

    文件上传接收json格式返回数据 默认的okhttp3可以接收并解析,httpclient接收的数据为content中的数据。

    1. 在使用文件上传的时候发现指定了backend:httpclient时,文件上传接口返还的json数据为 forestResponse中的content内容,而forestResponse中result没有数据导致json解析失败。

    2. 默认的okhttp3来实现上传请求没有问题。

    opened by jtc1998 2
  • 请问header怎么设置 参数

    请问header怎么设置 参数

    很抱歉在文档中没有看到

    opened by lianbitangjin 1
  • 响应头中的Transfer-Encoding为chunked,不能得到body内容

    响应头中的Transfer-Encoding为chunked,不能得到body内容

    调用spring boot actuator接口,响应头中的Transfer-Encoding为chunked,解析内容错误

    opened by ZhaoRd 1
  • build(deps-dev): bump junit from 4.12 to 4.13.1

    build(deps-dev): bump junit from 4.12 to 4.13.1

    Bumps junit from 4.12 to 4.13.1.

    Release notes

    Sourced from junit's releases.

    JUnit 4.13.1

    Please refer to the release notes for details.

    JUnit 4.13

    Please refer to the release notes for details.

    JUnit 4.13 RC 2

    Please refer to the release notes for details.

    JUnit 4.13 RC 1

    Please refer to the release notes for details.

    JUnit 4.13 Beta 3

    Please refer to the release notes for details.

    JUnit 4.13 Beta 2

    Please refer to the release notes for details.

    JUnit 4.13 Beta 1

    Please refer to the release notes for details.

    Commits
    • 1b683f4 [maven-release-plugin] prepare release r4.13.1
    • ce6ce3a Draft 4.13.1 release notes
    • c29dd82 Change version to 4.13.1-SNAPSHOT
    • 1d17486 Add a link to assertThrows in exception testing
    • 543905d Use separate line for annotation in Javadoc
    • 510e906 Add sub headlines to class Javadoc
    • 610155b Merge pull request from GHSA-269g-pwp5-87pp
    • b6cfd1e Explicitly wrap float parameter for consistency (#1671)
    • a5d205c Fix GitHub link in FAQ (#1672)
    • 3a5c6b4 Deprecated since jdk9 replacing constructor instance of Double and Float (#1660)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • build(deps): bump jackson-databind from 2.9.10 to 2.9.10.7 in /forest-core

    build(deps): bump jackson-databind from 2.9.10 to 2.9.10.7 in /forest-core

    Bumps jackson-databind from 2.9.10 to 2.9.10.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • fix #13 修复一些特殊的URL请求参数丢失的问题

    fix #13 修复一些特殊的URL请求参数丢失的问题

    URL查询参数在有些特殊的网站无法生效,并且会有查询参数丢失的问题。

    具体表现如下: /template/file/?${name} 会导致 ${name} 参数值丢失,实际只请求了 /template/file/ 地址,导致请求结果不正确。

    一般情况下请求参数通常是K-V键值对,但是有些请求参数只有Key,无Value值,并且不能有等于号(=),示例网站URL:http://www.mca.gov.cn/article/sj/xzqh/2019/?2 修改之后用户使用时必须明确指定查询参数值,当查询参数值为null时就只有Key,如果需要"Key="这样的空值,则需要把Value设置为一个长度为0的字符串(而不是null)

    opened by houkunlin 1
  • build(deps): bump spring.version from 5.0.2.RELEASE to 5.2.8.RELEASE in /forest-spring

    build(deps): bump spring.version from 5.0.2.RELEASE to 5.2.8.RELEASE in /forest-spring

    Bumps spring.version from 5.0.2.RELEASE to 5.2.8.RELEASE. Updates spring-core from 5.0.2.RELEASE to 5.2.8.RELEASE

    Release notes

    Sourced from spring-core's releases.

    v5.2.8.RELEASE

    :star: New Features

    • Defer creating logger in StandardWebSocketHandlerAdapter #25427
    • MutablePropertySources will not find or remove proxied sources #25369
    • Profiles should be comparable when created via Profiles.of() #25340
    • Avoid re-creating RSocketRequester instance per subscriber #25330
    • Hoist Class.getName() from String concatenation to dodge an issue related to profile pollution #25324
    • Improve Random seed in SocketUtils #25321
    • Support fragments in UriComponentsBuilder.fromHttpUrl() #25300
    • Support for custom cache registration in CaffeineCacheManager #25230
    • Don't get ContentCachingResponseWrapper in ShallowEtagHeaderFilter so that users can extend this wrapper #24976
    • Unnecessarily alarming stack trace logged during scheduler resolution #23268
    • Expose a setExceptionListener method in DefaultJmsListenerContainerFactory [SPR-17570] #22102

    :beetle: Bug fixes

    • UriComponentsBuilder.cloneBuilder() cause sharing query parameters between builders #25423
    • SimpleJdbcCall does not find stored function with PostgreSQL driver 42.2.11 #25399
    • MappingJackson2HttpMessageConverter might be too specific in its Charset support #25322
    • ReactorNetty websocket issue for multiple clients with different protocols #25315
    • Mutating a ServerHttpRequest breaks the existing context path #25279
    • ServerHttpRequest.getSslInfo() always returns null for reactor-netty HTTP/2 requests #25278
    • NoRollbackFor rule causes TransactionAspectSupport to log unwarranted "exception overridden" error on WebSphere #25253
    • AbstractJackson2HttpMessageConverter - Check for encoding breaks JSON to POJO de-serialization experience #25247
    • The AbstractTemplateViewResolver class is not abstract #25240
    • WebClient: NPE and leak in case connection is reset by server. #25216
    • Oracle LOB segments holding TEMP space after executing SP using SimpleJdbcCall with SqlParameterSource #22972
    • IllegalReferenceCountException happens when the operation was canceled #22594
    • DefaultListableBeanFactory.getBean(Class) may throw NoSuchBeanDefinitionException when removeBeanDefinition is being called simultaneously to remove an unrelated bean #22263

    :notebook_with_decorative_cover: Documentation

    • Clarify enforceInitMethod/enforceDestroyMethod default values in AbstractBeanDefinition #25402
    • Improve JavaDoc for ConfigurableApplicationContext.refresh() #25380
    • Fix interface and class names in examples in core-aop doc #25351
    • Wording changes #25314
    • Fix typo in Java example for handler class #25302
    • Improve Javadoc for @Value regarding supported expressions #25284
    • Fix syntax in validation examples #25251
    • Document exception handling limitations in TaskDecorator implementations (specifically for ThreadPoolTaskExecutor#submit) #25231

    :hammer: Dependency upgrades

    • Upgrade to Reactor Dysprosium-SR10 #25376
    • Upgrade to nohttp 0.0.5 #25266

    :heart: Contributors

    We’d like to thank all the contributors who worked on our current release!

    Commits
    • c23b1bd Release version 5.2.8.RELEASE
    • 1c83b3f Wording changes
    • 913eca9 ReactorNettyRequestUpgradeStrategy uses unique builder per request
    • 6c7f18e Upgrade to Jetty Reactive HttpClient 1.1.4
    • 64f4703 Defer creating logger in StandardWebSocketHandlerAdapter to instantiation time
    • eb032a5 Upgrade to Reactor Dysprosium-SR10
    • 65e6010 Copy queryParams MultiValueMap through addAll (for independent List entries)
    • f1345aa Defensively access existing beanDefinitionMap entries
    • 43e315f Unwrap SqlParameterValue for disposable value detection in cleanupParameters
    • 30bc5e0 Defensively catch NoSuchBeanDefinitionException on beanDefinitionNames traversal
    • Additional commits viewable in compare view

    Updates spring-beans from 5.0.2.RELEASE to 5.2.8.RELEASE

    Release notes

    Sourced from spring-beans's releases.

    v5.2.8.RELEASE

    :star: New Features

    • Defer creating logger in StandardWebSocketHandlerAdapter #25427
    • MutablePropertySources will not find or remove proxied sources #25369
    • Profiles should be comparable when created via Profiles.of() #25340
    • Avoid re-creating RSocketRequester instance per subscriber #25330
    • Hoist Class.getName() from String concatenation to dodge an issue related to profile pollution #25324
    • Improve Random seed in SocketUtils #25321
    • Support fragments in UriComponentsBuilder.fromHttpUrl() #25300
    • Support for custom cache registration in CaffeineCacheManager #25230
    • Don't get ContentCachingResponseWrapper in ShallowEtagHeaderFilter so that users can extend this wrapper #24976
    • Unnecessarily alarming stack trace logged during scheduler resolution #23268
    • Expose a setExceptionListener method in DefaultJmsListenerContainerFactory [SPR-17570] #22102

    :beetle: Bug fixes

    • UriComponentsBuilder.cloneBuilder() cause sharing query parameters between builders #25423
    • SimpleJdbcCall does not find stored function with PostgreSQL driver 42.2.11 #25399
    • MappingJackson2HttpMessageConverter might be too specific in its Charset support #25322
    • ReactorNetty websocket issue for multiple clients with different protocols #25315
    • Mutating a ServerHttpRequest breaks the existing context path #25279
    • ServerHttpRequest.getSslInfo() always returns null for reactor-netty HTTP/2 requests #25278
    • NoRollbackFor rule causes TransactionAspectSupport to log unwarranted "exception overridden" error on WebSphere #25253
    • AbstractJackson2HttpMessageConverter - Check for encoding breaks JSON to POJO de-serialization experience #25247
    • The AbstractTemplateViewResolver class is not abstract #25240
    • WebClient: NPE and leak in case connection is reset by server. #25216
    • Oracle LOB segments holding TEMP space after executing SP using SimpleJdbcCall with SqlParameterSource #22972
    • IllegalReferenceCountException happens when the operation was canceled #22594
    • DefaultListableBeanFactory.getBean(Class) may throw NoSuchBeanDefinitionException when removeBeanDefinition is being called simultaneously to remove an unrelated bean #22263

    :notebook_with_decorative_cover: Documentation

    • Clarify enforceInitMethod/enforceDestroyMethod default values in AbstractBeanDefinition #25402
    • Improve JavaDoc for ConfigurableApplicationContext.refresh() #25380
    • Fix interface and class names in examples in core-aop doc #25351
    • Wording changes #25314
    • Fix typo in Java example for handler class #25302
    • Improve Javadoc for @Value regarding supported expressions #25284
    • Fix syntax in validation examples #25251
    • Document exception handling limitations in TaskDecorator implementations (specifically for ThreadPoolTaskExecutor#submit) #25231

    :hammer: Dependency upgrades

    • Upgrade to Reactor Dysprosium-SR10 #25376
    • Upgrade to nohttp 0.0.5 #25266

    :heart: Contributors

    We’d like to thank all the contributors who worked on our current release!

    Commits
    • c23b1bd Release version 5.2.8.RELEASE
    • 1c83b3f Wording changes
    • 913eca9 ReactorNettyRequestUpgradeStrategy uses unique builder per request
    • 6c7f18e Upgrade to Jetty Reactive HttpClient 1.1.4
    • 64f4703 Defer creating logger in StandardWebSocketHandlerAdapter to instantiation time
    • eb032a5 Upgrade to Reactor Dysprosium-SR10
    • 65e6010 Copy queryParams MultiValueMap through addAll (for independent List entries)
    • f1345aa Defensively access existing beanDefinitionMap entries
    • 43e315f Unwrap SqlParameterValue for disposable value detection in cleanupParameters
    • 30bc5e0 Defensively catch NoSuchBeanDefinitionException on beanDefinitionNames traversal
    • Additional commits viewable in compare view

    Updates spring-context from 5.0.2.RELEASE to 5.2.8.RELEASE

    Release notes

    Sourced from spring-context's releases.

    v5.2.8.RELEASE

    :star: New Features

    • Defer creating logger in StandardWebSocketHandlerAdapter #25427
    • MutablePropertySources will not find or remove proxied sources #25369
    • Profiles should be comparable when created via Profiles.of() #25340
    • Avoid re-creating RSocketRequester instance per subscriber #25330
    • Hoist Class.getName() from String concatenation to dodge an issue related to profile pollution #25324
    • Improve Random seed in SocketUtils #25321
    • Support fragments in UriComponentsBuilder.fromHttpUrl() #25300
    • Support for custom cache registration in CaffeineCacheManager #25230
    • Don't get ContentCachingResponseWrapper in ShallowEtagHeaderFilter so that users can extend this wrapper #24976
    • Unnecessarily alarming stack trace logged during scheduler resolution #23268
    • Expose a setExceptionListener method in DefaultJmsListenerContainerFactory [SPR-17570] #22102

    :beetle: Bug fixes

    • UriComponentsBuilder.cloneBuilder() cause sharing query parameters between builders #25423
    • SimpleJdbcCall does not find stored function with PostgreSQL driver 42.2.11 #25399
    • MappingJackson2HttpMessageConverter might be too specific in its Charset support #25322
    • ReactorNetty websocket issue for multiple clients with different protocols #25315
    • Mutating a ServerHttpRequest breaks the existing context path #25279
    • ServerHttpRequest.getSslInfo() always returns null for reactor-netty HTTP/2 requests #25278
    • NoRollbackFor rule causes TransactionAspectSupport to log unwarranted "exception overridden" error on WebSphere #25253
    • AbstractJackson2HttpMessageConverter - Check for encoding breaks JSON to POJO de-serialization experience #25247
    • The AbstractTemplateViewResolver class is not abstract #25240
    • WebClient: NPE and leak in case connection is reset by server. #25216
    • Oracle LOB segments holding TEMP space after executing SP using SimpleJdbcCall with SqlParameterSource #22972
    • IllegalReferenceCountException happens when the operation was canceled #22594
    • DefaultListableBeanFactory.getBean(Class) may throw NoSuchBeanDefinitionException when removeBeanDefinition is being called simultaneously to remove an unrelated bean #22263

    :notebook_with_decorative_cover: Documentation

    • Clarify enforceInitMethod/enforceDestroyMethod default values in AbstractBeanDefinition #25402
    • Improve JavaDoc for ConfigurableApplicationContext.refresh() #25380
    • Fix interface and class names in examples in core-aop doc #25351
    • Wording changes #25314
    • Fix typo in Java example for handler class #25302
    • Improve Javadoc for @Value regarding supported expressions #25284
    • Fix syntax in validation examples #25251
    • Document exception handling limitations in TaskDecorator implementations (specifically for ThreadPoolTaskExecutor#submit) #25231

    :hammer: Dependency upgrades

    • Upgrade to Reactor Dysprosium-SR10 #25376
    • Upgrade to nohttp 0.0.5 #25266

    :heart: Contributors

    We’d like to thank all the contributors who worked on our current release!

    Commits
    • c23b1bd Release version 5.2.8.RELEASE
    • 1c83b3f Wording changes
    • 913eca9 ReactorNettyRequestUpgradeStrategy uses unique builder per request
    • 6c7f18e Upgrade to Jetty Reactive HttpClient 1.1.4
    • 64f4703 Defer creating logger in StandardWebSocketHandlerAdapter to instantiation time
    • eb032a5 Upgrade to Reactor Dysprosium-SR10
    • 65e6010 Copy queryParams MultiValueMap through addAll (for independent List entries)
    • f1345aa Defensively access existing beanDefinitionMap entries
    • 43e315f Unwrap SqlParameterValue for disposable value detection in cleanupParameters
    • 30bc5e0 Defensively catch NoSuchBeanDefinitionException on beanDefinitionNames traversal
    • Additional commits viewable in compare view

    Updates spring-webmvc from 5.0.2.RELEASE to 5.2.8.RELEASE

    Release notes

    Sourced from spring-webmvc's releases.

    v5.2.8.RELEASE

    :star: New Features

    • Defer creating logger in StandardWebSocketHandlerAdapter #25427
    • MutablePropertySources will not find or remove proxied sources #25369
    • Profiles should be comparable when created via Profiles.of() #25340
    • Avoid re-creating RSocketRequester instance per subscriber #25330
    • Hoist Class.getName() from String concatenation to dodge an issue related to profile pollution #25324
    • Improve Random seed in SocketUtils #25321
    • Support fragments in UriComponentsBuilder.fromHttpUrl() #25300
    • Support for custom cache registration in CaffeineCacheManager #25230
    • Don't get ContentCachingResponseWrapper in ShallowEtagHeaderFilter so that users can extend this wrapper #24976
    • Unnecessarily alarming stack trace logged during scheduler resolution #23268
    • Expose a setExceptionListener method in DefaultJmsListenerContainerFactory [SPR-17570] #22102

    :beetle: Bug fixes

    • UriComponentsBuilder.cloneBuilder() cause sharing query parameters between builders #25423
    • SimpleJdbcCall does not find stored function with PostgreSQL driver 42.2.11 #25399
    • MappingJackson2HttpMessageConverter might be too specific in its Charset support #25322
    • ReactorNetty websocket issue for multiple clients with different protocols #25315
    • Mutating a ServerHttpRequest breaks the existing context path #25279
    • ServerHttpRequest.getSslInfo() always returns null for reactor-netty HTTP/2 requests #25278
    • NoRollbackFor rule causes TransactionAspectSupport to log unwarranted "exception overridden" error on WebSphere #25253
    • AbstractJackson2HttpMessageConverter - Check for encoding breaks JSON to POJO de-serialization experience #25247
    • The AbstractTemplateViewResolver class is not abstract #25240
    • WebClient: NPE and leak in case connection is reset by server. #25216
    • Oracle LOB segments holding TEMP space after executing SP using SimpleJdbcCall with SqlParameterSource #22972
    • IllegalReferenceCountException happens when the operation was canceled #22594
    • DefaultListableBeanFactory.getBean(Class) may throw NoSuchBeanDefinitionException when removeBeanDefinition is being called simultaneously to remove an unrelated bean #22263

    :notebook_with_decorative_cover: Documentation

    • Clarify enforceInitMethod/enforceDestroyMethod default values in AbstractBeanDefinition #25402
    • Improve JavaDoc for ConfigurableApplicationContext.refresh() #25380
    • Fix interface and class names in examples in core-aop doc #25351
    • Wording changes #25314
    • Fix typo in Java example for handler class #25302
    • Improve Javadoc for @Value regarding supported expressions #25284
    • Fix syntax in validation examples #25251
    • Document exception handling limitations in TaskDecorator implementations (specifically for ThreadPoolTaskExecutor#submit) #25231

    :hammer: Dependency upgrades

    • Upgrade to Reactor Dysprosium-SR10 #25376
    • Upgrade to nohttp 0.0.5 #25266

    :heart: Contributors

    We’d like to thank all the contributors who worked on our current release!

    Commits
    • c23b1bd Release version 5.2.8.RELEASE
    • 1c83b3f Wording changes
    • 913eca9 ReactorNettyRequestUpgradeStrategy uses unique builder per request
    • 6c7f18e Upgrade to Jetty Reactive HttpClient 1.1.4
    • 64f4703 Defer creating logger in StandardWebSocketHandlerAdapter to instantiation time
    • eb032a5 Upgrade to Reactor Dysprosium-SR10
    • 65e6010 Copy queryParams MultiValueMap through addAll (for independent List entries)
    • f1345aa Defensively access existing beanDefinitionMap entries
    • 43e315f Unwrap SqlParameterValue for disposable value detection in cleanupParameters
    • 30bc5e0 Defensively catch NoSuchBeanDefinitionException on beanDefinitionNames traversal
    • Additional commits viewable in compare view

    Updates spring-test from 5.0.2.RELEASE to 5.2.8.RELEASE

    Release notes

    Sourced from spring-test's releases.

    v5.2.8.RELEASE

    :star: New Features

    • Defer creating logger in StandardWebSocketHandlerAdapter #25427
    • MutablePropertySources will not find or remove proxied sources #25369
    • Profiles should be comparable when created via Profiles.of() #25340
    • Avoid re-creating RSocketRequester instance per subscriber #25330
    • Hoist Class.getName() from String concatenation to dodge an issue related to profile pollution #25324
    • Improve Random seed in SocketUtils #25321
    • Support fragments in UriComponentsBuilder.fromHttpUrl() #25300
    • Support for custom cache registration in CaffeineCacheManager #25230
    • Don't get ContentCachingResponseWrapper in ShallowEtagHeaderFilter so that users can extend this wrapper #24976
    • Unnecessarily alarming stack trace logged during scheduler resolution #23268
    • Expose a setExceptionListener method in DefaultJmsListenerContainerFactory [SPR-17570] #22102

    :beetle: Bug fixes

    • UriComponentsBuilder.cloneBuilder() cause sharing query parameters between builders #25423
    • SimpleJdbcCall does not find stored function with PostgreSQL driver 42.2.11 #25399
    • MappingJackson2HttpMessageConverter might be too specific in its Charset support #25322
    • ReactorNetty websocket issue for multiple clients with different protocols #25315
    • Mutating a ServerHttpRequest breaks the existing context path #25279
    • ServerHttpRequest.getSslInfo() always returns null for reactor-netty HTTP/2 requests #25278
    • NoRollbackFor rule causes TransactionAspectSupport to log unwarranted "exception overridden" error on WebSphere #25253
    • AbstractJackson2HttpMessageConverter - Check for encoding breaks JSON to POJO de-serialization experience #25247
    • The AbstractTemplateViewResolver class is not abstract #25240
    • WebClient: NPE and leak in case connection is reset by server. #25216
    • Oracle LOB segments holding TEMP space after executing SP using SimpleJdbcCall with SqlParameterSource #22972
    • IllegalReferenceCountException happens when the operation was canceled #22594
    • DefaultListableBeanFactory.getBean(Class) may throw NoSuchBeanDefinitionException when removeBeanDefinition is being called simultaneously to remove an unrelated bean #22263

    :notebook_with_decorative_cover: Documentation

    • Clarify enforceInitMethod/enforceDestroyMethod default values in AbstractBeanDefinition #25402
    • Improve JavaDoc for ConfigurableApplicationContext.refresh() #25380
    • Fix interface and class names in examples in core-aop doc #25351
    • Wording changes #25314
    • Fix typo in Java example for handler class #25302
    • Improve Javadoc for @Value regarding supported expressions #25284
    • Fix syntax in validation examples #25251
    • Document exception handling limitations in TaskDecorator implementations (specifically for ThreadPoolTaskExecutor#submit) #25231

    :hammer: Dependency upgrades

    • Upgrade to Reactor Dysprosium-SR10 #25376
    • Upgrade to nohttp 0.0.5 #25266

    :heart: Contributors

    We’d like to thank all the contributors who worked on our current release!

    Commits
    • c23b1bd Release version 5.2.8.RELEASE
    • 1c83b3f Wording changes
    • 913eca9 ReactorNettyRequestUpgradeStrategy uses unique builder per request
    • 6c7f18e Upgrade to Jetty Reactive HttpClient 1.1.4
    • 64f4703 Defer creating logger in StandardWebSocketHandlerAdapter to instantiation time
    • eb032a5 Upgrade to Reactor Dysprosium-SR10
    • 65e6010 Copy queryParams MultiValueMap through addAll (for independent List entries)
    • f1345aa Defensively access existing beanDefinitionMap entries
    • 43e315f Unwrap SqlParameterValue for disposable value detection in cleanupParameters
    • 30bc5e0 Defensively catch NoSuchBeanDefinitionException on beanDefinitionNames traversal
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • 解析双层泛型对象的时候有bug

    解析双层泛型对象的时候有bug

    在解析双层泛型对象的时候 会报类转换异常

    opened by TomCcYuan 1
  • 不支持读取父接口的注解

    不支持读取父接口的注解

    forest-spring-boot-starter 1.5.0 版本, 接口调用上不能读取父接口上的注解信息. 比如@BaseRequest 注解

    opened by iszhangsc 0
  • 这框架支持在Android项目内使用吗?

    这框架支持在Android项目内使用吗?

    这框架支持在Android项目内使用吗?需要什么特别的配置吗?

    opened by spysoos 1
  • build(deps): bump commons-io from 2.4 to 2.7 in /forest-core

    build(deps): bump commons-io from 2.4 to 2.7 in /forest-core

    Bumps commons-io from 2.4 to 2.7.

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • 自定义注解优化建议

    自定义注解优化建议

    当使用自定义注解时,注解变量的值引用Forest全局变量进行赋值,当全局变量定义不存在时, 会报空指针异常。此处建议优化为,当全局变量的引用值为空时,使用自定义注解的对应字段的默认值, 没有默认值时再抛异常。 举例如下:

    public @interface ForestPorxy { String isProxy() default "false"; } @GetRequest(url = "https:.//www.baidu.com") @ForestPorxy(isProxy = "${proxy.baidui}") ForestResponse evtBaidu();

    如果proxy.baidui 在配置文件中不存在,现在的版本为直接抛出异常,且不会进入自定义注解的生命周期。

    opened by TravelEngineers 1
  • ForestJacksonConverter 可否支持一下自定义配置

    ForestJacksonConverter 可否支持一下自定义配置

    ForestJacksonConverter 可否支持一下自定义配置,比如 下划线 转驼峰支持 一些 api 接口 返回数据是 下划线格式的字段,需要自动映射为 驼峰格式,需要

     mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
    
    opened by imhuzi 1
  • 关于线程池配置

    关于线程池配置

    这里有关于线程池的相关配置么,默认线程池大小是多少

    opened by MaxSherry 2
  • forest-spring-boot-starter version:1.5.0 url param not encode.

    forest-spring-boot-starter version:1.5.0 url param not encode.

    使用forest-spring-boot-starter执行HTTP请求时,默认backend为okhttp3。 debug发现并未对Query参数进行URL Encode, 调用链路 com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor#execute(com.dtflys.forest.handler.LifeCycleHandler, int) com.dtflys.forest.backend.url.SimpleURLBuilder#buildUrl

    backend修改为httpclient调用的com.dtflys.forest.backend.url.QueryableURLBuilder则进行了正常URL Encode。 image image

    请修复

    opened by usami-muzugi 1
  • 文件下载时OnProgress没有执行

    文件下载时OnProgress没有执行

    image OnProgress的日志没有打印

    opened by ngchunhoCR7 9
  • springboot整合时,MultipartFile接收图片文件时contentType值不对

    springboot整合时,MultipartFile接收图片文件时contentType值不对

    文档(上传下载)给出:

    @PostRequest(url = "/upload")
    Map upload(@DataFile(value = "file") MultipartFile multipartFile, OnProgress onProgress);
    

    上传文件为图片时multipartFile的contentType= image/jpeg,upload给另外一个接口时,另外接口接收到的multipartFile的contentType= multipart/form-data

    opened by ShiTianming 1
  • 在普通项目中使用post请求会报错

    在普通项目中使用post请求会报错

    package com.example.request;
    
    import com.dtflys.forest.annotation.Body;
    import com.dtflys.forest.annotation.Get;
    import com.dtflys.forest.annotation.Post;
    
    
    public interface Client {
        @Post(url = "http://127.0.0.1:8090/api/admin/login/precheck", contentType = "application/json")
        public String login(@Body("username") String username, @Body("password") String password);
    }
    
    
    package com.example;
    
    import com.dtflys.forest.config.ForestConfiguration;
    import com.example.request.Client;
    
    public class main {
        public static void main(String[] args) {
            Client myClient = ForestConfiguration.configuration().createInstance(Client.class);
            myClient.login("[email protected]", "123456789");
        }
    }
    

    运行报错:

    [main] INFO com.dtflys.forest.config.ForestConfiguration - [Forest] Http Backend: okhttp3
    Exception in thread "main" java.lang.NullPointerException
    	at com.dtflys.forest.backend.body.AbstractBodyBuilder.buildBody(AbstractBodyBuilder.java:151)
    	at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.prepareBody(AbstractOkHttp3Executor.java:171)
    	at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.execute(AbstractOkHttp3Executor.java:181)
    	at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.execute(AbstractOkHttp3Executor.java:281)
    	at com.dtflys.forest.http.ForestRequest.execute(ForestRequest.java:1608)
    	at com.dtflys.forest.http.ForestRequest.execute(ForestRequest.java:1625)
    	at com.dtflys.forest.reflection.ForestMethod.invoke(ForestMethod.java:1143)
    	at com.dtflys.forest.proxy.InterfaceProxyHandler.invoke(InterfaceProxyHandler.java:121)
    	at com.sun.proxy.$Proxy9.login(Unknown Source)
    	at com.example.main.main(main.java:16)
    
    opened by testwangchao 2
Owner
dromara
The girl on the prairie
dromara
Feign makes writing java http clients easier

Feign makes writing java http clients easier Feign is a Java to HTTP client binder inspired by Retrofit, JAXRS-2.0, and WebSocket. Feign's first goal

null 6.8k Mar 13, 2021
Asynchronous Http and WebSocket Client library for Java

Async Http Client Follow @AsyncHttpClient on Twitter. The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and a

AsyncHttpClient 5.7k Mar 12, 2021
http-kit is a minimalist, event-driven, high-performance Clojure HTTP server/client library with WebSocket and asynchronous support

HTTP Kit A simple, high-performance event-driven HTTP client+server for Clojure CHANGELOG | API | current Break Version: [http-kit "2.5.3"] ; Publish

HTTP Client/Server for Clojure 2.2k Mar 12, 2021
⚗️ Lightweight HTTP extensions for Java 11

Methanol A lightweight library that complements java.net.http for a better HTTP experience. Overview Methanol provides useful lightweight HTTP extensi

Moataz Abdelnasser 89 Mar 3, 2021
Client-side response routing for Spring

Riptide: A next generation HTTP client Riptide noun, /ˈrɪp.taɪd/: strong flow of water away from the shore Riptide is a library that implements client

Zalando SE 167 Mar 11, 2021
Google HTTP Client Library for Java

Google HTTP Client Library for Java Description Written by Google, the Google HTTP Client Library for Java is a flexible, efficient, and powerful Java

Google APIs 1.1k Mar 12, 2021
Java HTTP Request Library

Http Request A simple convenience library for using a HttpURLConnection to make requests and access the response. This library is available under the

Kevin Sawicki 3.2k Apr 4, 2021
A high-level and lightweight HTTP client framework for Java. it makes sending HTTP requests in Java easier.

A high-level and lightweight HTTP client framework for Java. it makes sending HTTP requests in Java easier.

dromara 322 Apr 30, 2021
Square’s meticulous HTTP client for the JVM, Android, and GraalVM.

OkHttp See the project website for documentation and APIs. HTTP is the way modern applications network. It’s how we exchange data & media. Doing HTTP

Square 39.9k Apr 23, 2021
Tiny, easily embeddable HTTP server in Java.

NanoHTTPD – a tiny web server in Java NanoHTTPD is a light-weight HTTP server designed for embedding in other applications, released under a Modified

NanoHttpd 5.8k Mar 14, 2021
Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.

Ribbon Ribbon is a client side IPC library that is battle-tested in cloud. It provides the following features Load balancing Fault tolerance Multiple

Netflix, Inc. 3.9k Mar 11, 2021
ssh, scp and sftp for java

sshj - SSHv2 library for Java To get started, have a look at one of the examples. Hopefully you will find the API pleasant to work with :) Getting SSH

Jeroen van Erp 1.8k Mar 14, 2021
Unirest in Java: Simplified, lightweight HTTP client library.

Unirest for Java Install With Maven: <!-- Pull in as a traditional dependency --> <dependency> <groupId>com.konghq</groupId> <artifactId>unire

Kong 2.1k Mar 11, 2021
Unirest in Java: Simplified, lightweight HTTP client library.

Unirest for Java Install With Maven: <!-- Pull in as a traditional dependency --> <dependency> <groupId>com.konghq</groupId> <artifactId>unire

Kong 2.1k Apr 30, 2021