123456823 发表于 2022-8-19 10:41:37

第三方HTTP接口请求利器:forest

推荐一款非常不错的 HTTP 请求发包工具: forest。
介绍

Java 日常开发中,肯定会经常遇到 HTTP 远程调用的情况,微服务场景下,有 feign/open-feign 这样的非常简洁的第三方方案。
但是在调用第三方服务的情况下,一般会选择 Apache 的 HttpClient、OkHttp 这样的第三方库 或者 JDK11 提供的 java.net.http.HttpClient;但是这些库都需要写不少代码,使用比较繁琐。
今天要推荐的 forest 用起来和 feign 非常类似, 最直观的感受如下:

[*]简单: 只需要写接口,不需要写实现(forest 替你自动生成了繁琐的实现)。
[*]扩展性强: 底层的实现可以由你自己指定是使用 OkHttp 还是其他的实现。
[*]模板变量
[*]异步请求
[*]拦截器
[*]自定义转换器
架构

forest 的架构图如下(图片来自官网):



forest架构图
可以将 forest 和 JDBC 类比:

[*]JDBC 定义了标准,用户只需要针对 JDBC 的 API 接口编程,底层实现可以自由切换
[*]forest 也定义了自己的 HTTP 请求,用户只需要针对 forest 接口编程,底层实现可以自由切换(虽然目前的选择就OkHttp和ApacheHttpClient两种)
声明式接口简单示例

这里就以 spring-boot 项目为例来简单演示 forest 的用法。

[*]依赖
<dependency>    <groupId>com.dtflys.forest</groupId>    <artifactId>forest-spring-boot-starter</artifactId>    <version>1.5.25</version></dependency>

[*]包扫描配置
// 1.5.1以后版本可以跳过此步,不需要 @ForestScan 注解来指定扫描的包范围@ForestScan(basePackages = "com.example.demo.forestdemo.client")@SpringBootApplicationpublic class ForestDemoApplication {    public static void main(String[] args) {      SpringApplication.run(ForestDemoApplication.class, args);    }}

[*]定义接口
public interface HttpCallService {    @Get("https://github.com/dromara/forest")    String helloForest();    @Get("https://ditu.amap.com/service/regeo?longitude={0}&latitude={1}")    Map<String, Object> getLocation(String longitude, String latitude);}然后就可以直接调用接口了,不需要写实现。
@SpringBootTestclass HttpCallServiceTest {    @Autowired    private HttpCallService httpCallService;    @Test    void helloForest() {      final String response = httpCallService.helloForest();      System.out.println(response);    }    @Test    void getLocation() throws JsonProcessingException {      final Map<String, Object> location = this.httpCallService.getLocation("121.369", "31.258");      System.out.println(new ObjectMapper().writeValueAsString(location));    }}编程式接口简单示例

如果你不想定义接口,就想直接发 HTTP 请求,forest 也提供了快捷接口:
class HttpCallServiceTest {    @Test    void shortcutMethodTest() {      // get 请求 https://www.baidu.com      // 然后将响应结果转为字符串      final String response = Forest.get("https://www.baidu.com").executeAsString();      System.out.println(response);    }}说个题外话: 个人感觉,在快捷接口(编程式接口)方面,还是 JDK11 提供的 java.net.http.HttpClient 的功能更加丰富,下面是 JDK11 的 HttpClient 实现的和上面例子一样的功能的写法:
public class MainTest {    static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(16);    @Test    public void testGet() throws IOException, InterruptedException, URISyntaxException {      final HttpClient httpClient = HttpClient                .newBuilder()                .executor(EXECUTOR)                .build();      final HttpRequest httpRequest = HttpRequest.newBuilder()                .uri(new URI("https://www.baidu.com"))                .header("User-Agent", "jdk 9 http client")                .GET()                .build();      final HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());      System.out.println(httpResponse.statusCode());      System.out.println(httpResponse.body());    }    @Test    public void testAsyncGet() throws URISyntaxException {      final HttpClient httpClient = HttpClient                .newBuilder()                .executor(EXECUTOR)                .build();      final HttpRequest request = HttpRequest.newBuilder()                .uri(new URI("https://www.baidu.com"))                .GET()                .build();      final CompletableFuture<HttpResponse<String>> response = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString());      response.whenComplete((resp, t) -> {            if (t != null) {                t.printStackTrace();            } else {                System.out.println(resp.body());                System.out.println(resp.statusCode());            }      }).join();    }}个人感觉 forest 的声明式接口这点是非常简洁易用的。
其他各种特性建议直接看官方文档: https://forest.dtflyx.com/

冀苍鸾 发表于 2022-8-19 10:42:13

转发了
页: [1]
查看完整版本: 第三方HTTP接口请求利器:forest