Skip to content
LangChain4j 文档版本 1.22.0 源快照 1ea65b5f 更新于 2026-10-14

可定制的 HTTP 客户端

某些 LangChain4j 模块(目前是 OpenAI 与 Ollama)支持定制用于调用 LLM 提供者 API 的 HTTP 客户端。

langchain4j-http-client 模块实现了一个 HttpClient SPI,这些模块用它来调用 LLM 提供者的 REST API。 这意味着底层 HTTP 客户端可被定制,而任何其它 HTTP 客户端都可以通过实现 HttpClient SPI 来接入。

目前有以下开箱即用的实现:

  • 来自 langchain4j-http-client-jdk 模块的 JdkHttpClient。 当使用受支持的模块(例如 langchain4j-open-ai)时,它被默认使用。
  • 来自 langchain4j-http-client-spring-boot4-restclient/langchain4j-http-client-spring-restclient 模块的 SpringRestClient。 当使用受支持模块的 Spring Boot starter(例如 langchain4j-open-ai-spring-boot4-starter/langchain4j-open-ai-spring-boot-starter)时,它被默认使用。
  • 来自 langchain4j-http-client-apache 模块的 ApacheHttpClient。
  • 来自 langchain4j-http-client-okhttp 模块的 OkHttpClient。

定制 JDK 的 HttpClient

java
HttpClient.Builder httpClientBuilder = HttpClient.newBuilder()
        .sslContext(...);

JdkHttpClientBuilder jdkHttpClientBuilder = JdkHttpClient.builder()
        .httpClientBuilder(httpClientBuilder);

OpenAiChatModel model = OpenAiChatModel.builder()
        .httpClientBuilder(jdkHttpClientBuilder)
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .modelName("gpt-4o-mini")
        .build();

HTTP 版本

默认情况下,JdkHttpClient 对 https:// URL 使用 HTTP/2(当服务器支持时),对纯 http:// URL 使用 HTTP/1.1。在纯 HTTP 上使用 HTTP/2 需要一个 Upgrade: h2c 请求,而许多服务器无法正确处理它。例如,运行在带 httptools 解析器的 uvicorn 上的 Python 服务器(如 vLLM 或 Xinference)会忽略请求体,而在 Tomcat 或 Reactor Netty 上启用了 HTTP/2 的 Java 服务器会拒绝较大的请求或停止响应。典型症状包括提示请求体缺失的服务器错误(例如 Field required)、Unsupported upgrade request、413 Request Entity Too Large,或请求一直挂起到超时。

NOTE

在 1.23.0 之前,JdkHttpClient 对纯 http:// URL 也使用 HTTP/2。 如果你使用更早版本并看到上述症状,请提供一个带 .version(HttpClient.Version.HTTP_1_1) 的 HttpClient.Builder,如下所示。

当你提供自己的 HttpClient.Builder(例如为了配置代理或 SSLContext)时,其上配置的 HTTP 版本会被用于所有 URL。如果你不在其上设置版本,JDK 默认是 HTTP/2,因此纯 http:// 请求又会发送 Upgrade: h2c 请求。 要在那种情况下使用 HTTP/1.1,请显式设置版本:

java
HttpClient.Builder httpClientBuilder = HttpClient.newBuilder()
        .proxy(...)
        .version(HttpClient.Version.HTTP_1_1);

JdkHttpClientBuilder jdkHttpClientBuilder = JdkHttpClient.builder()
        .httpClientBuilder(httpClientBuilder);

反之,如果你的纯 HTTP 服务器支持 Upgrade: h2c 请求,且你希望对它使用 HTTP/2,请提供一个带 .version(HttpClient.Version.HTTP_2) 的 builder。

NOTE

HttpClient 的实现也可以提供非阻塞对应方法:用于单个响应的 executeAsync(...),以及用于已解析服务端事件冷 Flow.Publisher 的 stream(...)。内置的 JDK、OkHttp 与 Apache 客户端都实现了二者,当 classpath 上有 spring-webflux 时 SpringRestClient 也是。参见非阻塞与响应式。

定制 Spring 的 RestClient

java
RestClient.Builder restClientBuilder = RestClient.builder()
        .requestFactory(new HttpComponentsClientHttpRequestFactory());

SpringRestClientBuilder springRestClientBuilder = SpringRestClient.builder()
        .restClientBuilder(restClientBuilder)
        .streamingRequestExecutor(new VirtualThreadTaskExecutor());

OpenAiChatModel model = OpenAiChatModel.builder()
        .httpClientBuilder(springRestClientBuilder)
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .modelName("gpt-4o-mini")
        .build();

SpringRestClient 用 RestClient 发送阻塞请求,用 WebClient 发送非阻塞请求(executeAsync(...) 与 stream(...)),后者需要 classpath 上有 spring-webflux。由于 spring-webflux 是可选的,WebClient.Builder 会被包在一个 WebClientBuilderHolder 中传入:

java
SpringRestClientBuilder springRestClientBuilder = SpringRestClient.builder()
        .restClientBuilder(RestClient.builder())
        .webClientBuilder(WebClientBuilderHolder.of(WebClient.builder()))
        .clientHttpConnectorBuilder(ClientHttpConnectorBuilder.reactor()); // optional: pins the connector

使用 JDK 客户端时的 HTTP 版本

当 Spring 选择 JDK 的 HttpClient(classpath 上没有 Apache HttpComponents、Jetty 或 Reactor Netty)时,SpringRestClient 表现得像 JdkHttpClient:纯 http:// 请求走 HTTP/1.1,https:// 请求在服务器支持时使用 HTTP/2。这对阻塞与非阻塞请求都适用。关于纯 HTTP 为何不使用 HTTP/2,参见 HTTP 版本。

你用 clientHttpRequestFactoryBuilder(...) 或 clientHttpConnectorBuilder(...) 设置的 builder 会被原样使用。 JDK 客户端默认为 HTTP/2,因此要对它使用 HTTP/1.1,请显式设置版本:

java
SpringRestClientBuilder springRestClientBuilder = SpringRestClient.builder()
        .clientHttpRequestFactoryBuilder(ClientHttpRequestFactoryBuilder.jdk()
                .withHttpClientCustomizer(builder -> builder.version(HttpClient.Version.HTTP_1_1)))
        .clientHttpConnectorBuilder(ClientHttpConnectorBuilder.jdk() // only needed for non-blocking requests
                .withHttpClientCustomizer(builder -> builder.version(HttpClient.Version.HTTP_1_1)));

NOTE

在 1.23.0-beta33 之前,SpringRestClient 对纯 http:// URL 也使用 HTTP/2。 如果你使用更早版本并看到 HTTP 版本 中描述的症状,请按上文所示设置 clientHttpRequestFactoryBuilder(...)。

定制 Apache 的 HttpClient

java
org.apache.hc.client5.http.impl.classic.HttpClientBuilder httpClientBuilder = org.apache.hc.client5.http.impl.classic.HttpClientBuilder.create();

ApacheHttpClientBuilder apacheHttpClientBuilder = ApacheHttpClient.builder()
        .httpClientBuilder(httpClientBuilder);

OpenAiChatModel model = OpenAiChatModel.builder()
        .httpClientBuilder(apacheHttpClientBuilder)
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .modelName("gpt-4o-mini")
        .build();

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。