# forest
**Repository Path**: php_java/forest
## Basic Information
- **Project Name**: forest
- **Description**: 声明式HTTP客户端API框架,让Java发送HTTP/HTTPS请求不再难。它比OkHttp和HttpClient更高层,是封装调用第三方restful api client接口的好帮手,是retrofit和feign之外另一个选择。通过在接口上声明注解的方式配置HTTP请求接口
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: http://forest.dtflyx.com/
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 801
- **Created**: 2021-11-18
- **Last Updated**: 2021-11-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
Forest - 声明式HTTP客户端框架
项目介绍:
-------------------------------------
Forest是一个高层的、极简的声明式HTTP调用API框架。
相比于直接使用Httpclient您不再用写一大堆重复的代码了,而是像调用本地方法一样去发送HTTP请求。
文档和示例:
-------------------------------------
* [项目主页](http://forest.dtflyx.com/)
* [中文文档](http://forest.dtflyx.com/docs/)
* [JavaDoc](https://apidoc.gitee.com/dt_flys/forest/)
* [Demo工程](https://gitee.com/dt_flys/forest-example)
Forest有哪些特性?
-----
* 以Httpclient和OkHttp为后端框架
* 通过调用本地方法的方式去发送Http请求, 实现了业务逻辑与Http协议之间的解耦
* 因为针对第三方接口,所以不需要依赖Spring Cloud和任何注册中心
* 支持所有请求方法:GET, HEAD, OPTIONS, TRACE, POST, DELETE, PUT, PATCH
* 支持文件上传和下载
* 支持灵活的模板表达式
* 支持拦截器处理请求的各个生命周期
* 支持自定义注解
* 支持OAuth2验证
* 支持过滤器来过滤传入的数据
* 基于注解、配置化的方式定义Http请求
* 支持Spring和Springboot集成
* JSON格式数据序列化和反序列化
* XML格式数据序列化和反序列化
* Protobuf格式数据序列化和反序列化
* JSON、XML或其他类型转换器可以随意扩展和替换
* 支持JSON转换框架: Fastjson, Jackson, Gson
* 支持JAXB形式的XML转换
* 可以通过OnSuccess和OnError接口参数实现请求结果的回调
* 配置简单,一般只需要@Request一个注解就能完成绝大多数请求的定义
* 支持异步请求调用
极速开始
-------------------------------------
以下例子基于Spring Boot
### 第一步:添加Maven依赖
直接添加以下maven依赖即可
```xml
com.dtflys.forest
forest-spring-boot-starter
1.5.13
```
### 第二步:创建一个`interface`
就以高德地图API为栗子吧
```java
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`属性里填上远程接口的所在的包名
```java
@SpringBootApplication
@Configuration
@ForestScan(basePackages = "com.yoursite.client")
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
```
### 第四步:调用接口
OK,我们可以愉快地调用接口了
```java
// 注入接口实例
@Autowired
private AmapClient amapClient;
...
// 调用接口
Map result = amapClient.getLocation("121.475078", "31.223577");
System.out.println(result);
```
## 发送JSON数据
```java
/**
* 将对象参数解析为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数据
```java
/**
* 将一个通过JAXB注解修饰过的类型对象解析为XML字符串
* 并放在请求的Body进行传输
*/
@Post("/message")
String sendXmlMessage(@XMLBody MyMessage message);
/**
* 直接传入一个XML字符串,并放在请求的Body进行传输
*/
@Post("/test/xml")
String postXmlBodyString(@XMLBody String xml);
```
## 发送Protobuf数据
```java
/**
* ProtobufProto.MyMessage 为 Protobuf 生成的数据类
* 将 Protobuf 生成的数据对象转换为 Protobuf 格式的字节流
* 并放在请求的Body进行传输
*
* 注: 需要引入 google protobuf 依赖
*/
@Post(url = "/message", contentType = "application/octet-stream")
String sendProtobufMessage(@ProtobufBody ProtobufProto.MyMessage message);
```
## 文件上传
```java
/**
* 用@DataFile注解修饰要上传的参数对象
* OnProgress参数为监听上传进度的回调函数
*/
@Post("/upload")
Map upload(@DataFile("file") String filePath, OnProgress onProgress);
```
可以用一个方法加Lambda同时解决文件上传和上传的进度监听
```java
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! --------");
}
});
```
## 多文件批量上传
```java
/**
* 上传Map包装的文件列表,其中 {_key} 代表Map中每一次迭代中的键值
*/
@Post("/upload")
ForestRequest