Http客户端框架Forest项目解读

项目介绍

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

Maven依赖

<dependency>
    <groupId>com.dtflys.forest</groupId>
    <artifactId>forest-spring-boot-starter</artifactId>
    <version>1.5.19</version>
</dependency>
复制代码

快速上手

简单请求

public interface MyClient {

    @Request("http://localhost:8080/hello")
    String simpleRequest();

}
复制代码

通过@Request注解,将上面的MyClient接口中的simpleRequest()方法绑定了一个 HTTP 请求, 其 URL 为http://localhost:8080/hello ,并默认使用GET方式,且将请求响应的数据以String的方式返回给调用者。

稍微复杂点的请求,需要在请求头设置信息

public interface MyClient {

    @Request(
            url = "http://localhost:8080/hello/user",
            headers = "Accept: text/plain"
    )
    String sendRequest(@Query("uname") String username);
}
复制代码

上面的sendRequest方法绑定的 HTTP 请求,定义了 URL 信息,以及把Accept:text/plain加到了请求头中, 方法的参数String username绑定了注解@Query("uname"),它的作用是将调用者传入入参 username 时,自动将username的值加入到 HTTP 的请求参数uname中。

这段实际产生的HTTP请求如下:

GET http://localhost:8080/hello/user?uname=foo
HEADER:
    Accept: text/plain
复制代码

请求方法,假设发起post请求,有3种写法:

public interface MyClient {

    /**
     * 使用 @Post 注解,可以去掉 type = "POST" 这行属性
     */
    @Post("http://localhost:8080/hello")
    String simplePost1();


    /**
     * 通过 @Request 注解的 type 参数指定 HTTP 请求的方式。
     */
    @Request(
            url = "http://localhost:8080/hello",
            type = "POST"
    )
    String simplePost2();

    /**
     * 使用 @PostRequest 注解,和上面效果等价
     */
    @PostRequest("http://localhost:8080/hello")
    String simplePost3();

}
复制代码

可以用@GetRequest@PostRequest等注解代替@Request注解,这样就可以省去写type属性的麻烦了。

请求体

POSTPUT等请求方法中,通常使用 HTTP 请求体进行传输数据。在 Forest 中有多种方式设置请求体数据。

表单格式

上面使用 @Body 注解的例子用的是普通的表单格式,也就是contentType属性为application/x-www-form-urlencoded的格式,即contentType不做配置时的默认值。

表单格式的请求体以字符串 key1=value1&key2=value2&...&key{n}=value{n} 的形式进行传输数据,其中value都是已经过 URL Encode 编码过的字符串。


/**
 * contentType属性设置为 application/x-www-form-urlencoded 即为表单格式,
 * 当然不设置的时候默认值也为 application/x-www-form-urlencoded, 也同样是表单格式。
 * 在 @Body 注解的 value 属性中设置的名称为表单项的 key 名,
 * 而注解所修饰的参数值即为表单项的值,它可以为任何类型,不过最终都会转换为字符串进行传输。
 */
@Post(
    url = "http://localhost:8080/user",
    contentType = "application/x-www-form-urlencoded",
    headers = {"Accept:text/plain"}
)
String sendPost(@Body("key1") String value1,  @Body("key2") Integer value2, @Body("key3") Long value3);
复制代码

调用后产生的结果可能如下:

POST http://localhost:8080/hello/user
HEADER:
    Content-Type: application/x-www-form-urlencoded
BODY:
    key1=xxx&key2=1000&key3=9999
复制代码

@Body注解修饰的参数为一个对象,并注解的value属性不设置任何名称的时候,会将注解所修饰参数值对象视为一整个表单,其对象中的所有属性将按 属性名1=属性值1&属性名2=属性值2&...&属性名{n}=属性值{n} 的形式通过请求体进行传输数据。

/**
 * contentType 属性不设置默认为 application/x-www-form-urlencoded
 * 要以对象作为表达传输项时,其 @Body 注解的 value 名称不能设置
 */
@Post(
    url = "http://localhost:8080/hello/user",
    headers = {"Accept:text/plain"}
)
String send(@Body User user);
复制代码

调用产生的结果如下:

POST http://localhost:8080/hello/user
HEADER:
    Content-Type: application/x-www-form-urlencoded
BODY:
    username=foo&password=bar
复制代码

JSON格式

@JSONBody注解修饰对象

发送JSON非常简单,只要用@JSONBody注解修饰相关参数就可以了,该注解自1.5.0-RC1版本起可以使用。 使用@JSONBody注解的同时就可以省略 contentType = "application/json"属性设置

/**
 * 被@JSONBody注解修饰的参数会根据其类型被自定解析为JSON字符串
 * 使用@JSONBody注解时可以省略 contentType = "application/json"属性设置
 */
@Post("http://localhost:8080/hello/user")
String helloUser(@JSONBody User user);
复制代码

调用后产生的结果如下:

POST http://localhost:8080/hello/user
HEADER:
    Content-Type: application/json
BODY:
    {"username": "foo", "password": "bar"}
复制代码

猜你喜欢

转载自juejin.im/post/7077742590505779207