Skip to content

最佳实践

零依赖使用

有时候希望零依赖进行HTTP调用,下面是一个发送钉钉机器人的消息的一个例子:

java
private static final String URL = "https://oapi.dingtalk.com/robot/send?access_token=${YOUR_ACCESS_TOKEN}";

String content = "{\"msgtype\":\"text\",\"text\":{\"content\":\"hello, world\"}}";
SolpicTemplate solpicTemplate = Solpic.newSolpicTemplate();
HttpResponse<String> response = solpicTemplate.post(URL, content, String.class);
System.out.println(response.getStatusCode());
System.out.println(response.getPayload());

如果调用成功的话,会输出如下结果:

shell
OK
{"errcode":0,"errmsg":"ok"}

零依赖使用在JDK[8,10]会选用HttpURLConnection进行真正的HTTP调用,而在JDK[11会选用java.net.http.HttpClient进行真正的HTTP调用。HttpURLConnection不支持连接池配置,java.net.http.HttpClient本身没有显式的连接池管理API,但其内部实现了连接池并且默认启用。

TIP

java.net.http.HttpClient提供了系统变量用于配置连接池的属性:

  • jdk.httpclient.connectionPoolSize:用于配置连接池的容量,默认是0,也就是无限制
  • jdk.httpclient.keepalive.timeout:连接保活过期时间,默认是1200(单位是秒,也就是20分钟)

Solpic初始化底层客户端为java.net.http.HttpClient的时候会尝试捕获这两个值并且尝试基于配置值改变这两个系统变量,但是不确保会生效。

第三方客户端

使用Apache HTTP Client5,需要引入以下依赖:

xml
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version>
</dependency>
properties
implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1'

构建HttpClient实例的时候需要指定类型为APACHE_HTTPCLIENT_V5(ahc5)

java
HttpClient httpClient = Solpic.newHttpClientBuilder()
        .type(HttpClientType.APACHE_HTTPCLIENT_V5)
        .build();
System.out.println(httpClient.id());

使用Apache HTTP Client,需要引入以下依赖:

xml
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>
properties
implementation 'org.apache.httpcomponents:httpclient:4.5.14'

构建HttpClient实例的时候需要指定类型为APACHE_HTTPCLIENT_V4(ahc4)

java
HttpClient httpClient = Solpic.newHttpClientBuilder()
        .type(HttpClientType.APACHE_HTTPCLIENT_V4)
        .build();
System.out.println(httpClient.id());

使用OkHttp,需要引入以下依赖:

xml
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version>
</dependency>
properties
implementation 'com.squareup.okhttp3:okhttp:4.12.0'

构建HttpClient实例的时候需要指定类型为OKHTTP(okhttp)

java
HttpClient httpClient = Solpic.newHttpClientBuilder()
        .type(HttpClientType.OKHTTP)
        .build();
System.out.println(httpClient.id());

启用连接池

Solpic所支持的底层HTTP客户端实现之中只有HttpURLConnection不支持连接池配置,因此选用了其他底层客户端实现建议启用连接池特性。例如:

java
private static final String URL = "https://oapi.dingtalk.com/robot/send?access_token=${YOUR_ACCESS_TOKEN}";

String content = "{\"msgtype\":\"text\",\"text\":{\"content\":\"hello, world\"}}";
HttpClient httpClient = Solpic.newHttpClientBuilder()
        .type(HttpClientType.APACHE_HTTPCLIENT_V5)
        .option(HttpOptions.HTTP_CLIENT_ENABLE_CONNECTION_POOL, true)
        .option(HttpOptions.HTTP_CLIENT_CONNECTION_POOL_CAPACITY, 128)
        .option(HttpOptions.HTTP_CLIENT_CONNECTION_TTL, 1800000)
        .build();
SolpicTemplate solpicTemplate = Solpic.newSolpicTemplateBuilder()
        .httpClient(httpClient)
        .codec(Solpic.loadCodec())
        .build();
HttpResponse<String> response = solpicTemplate.post(URL, content, String.class);
System.out.println(response.getStatusCode());
System.out.println(response.getPayload());

启用虚拟线程

高级特性 - 启用虚拟线程小节。

声明式使用

现实中绝大部分的声明式使用场景都是同步调用,并且请求或者响应对象都是支持序列化和反序列化的简单对象,针对这个场景可以使用CodecConverterFactory基于编码解码器完成API的请求参数和响应结果转换。举个例子:

java
@Data
public class HttpBinResult {

    private Map<String, String> args;

    private Map<String, String> headers;

    private Map<String, Object> json;

    private String origin;

    private String url;
}

public interface SyncHttpBinApi {

    @Get(path = "/get")
    HttpBinResult get(@Query("foo") String fooVal);

    @Post(path = "/post")
    HttpBinResult post(@Payload Map<String, String> payload);
}

编写客户端API调用代码:

java
public static void main(String[] args) {
    SyncHttpBinApi api = ApiEnhancerBuilder.newBuilder()
            .httpClient(Solpic.newHttpClientBuilder().type(HttpClientType.JDK_HTTPCLIENT).build())
            .addConverterFactory(CodecConverterFactory.newInstance(Solpic.loadCodec("jackson")))
            .baseUrl("https://httpbin.org")
            .build()
            .enhance(SyncHttpBinApi.class);
    HttpBinResult r1 = api.get("bar");
    System.out.printf("get result => %s\n", r1);
    HttpBinResult r2 = api.post(Collections.singletonMap("hello", "world"));
    System.out.printf("post result => %s\n", r2);
}

某次执行结果如下:

shell
get result => HttpBinResult(args={foo=bar}, headers={Host=httpbin.org, User-Agent=Java-http-client/22,
X-Amzn-Trace-Id=Root=1-66e262a8-6c9166a234faa02e2e442389}, json=null, origin=183.6.24.203, url=https://httpbin.org/get?foo=bar)
post result => HttpBinResult(args={}, headers={Host=httpbin.org, Transfer-Encoding=chunked, User-Agent=Java-http-client/22,
X-Amzn-Trace-Id=Root=1-66e262a9-475323555361295a0891c9f1}, json={hello=world}, origin=183.6.24.203, url=https://httpbin.org/post)

贡献者

页面历史

Released under the MIT License.