常用的http请求方式(第三方HTTP接口请求利器)
推荐一款非常不错的 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")
@SpringBootApplication
public 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);
}
然后就可以直接调用接口了,不需要写实现。
@SpringBootTest
class 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/
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com