You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java/Kotlin结合OkHttp实现OpenAI chat/completions流式响应?

使用OkHttp实现OpenAI Chat Completions流式响应

OpenAI的chat/completions API支持通过stream=true参数返回流式响应,以下是基于OkHttp客户端的Java和Kotlin实现示例:


Java 实现

1. 添加OkHttp依赖

如果使用Maven,在pom.xml中加入:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.11.0</version> <!-- 使用最新稳定版本 -->
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version> <!-- 用于JSON解析 -->
</dependency>

2. 完整代码示例

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import java.io.IOException;

public class OpenAIStreamExample {
    private static final String API_KEY = "YOUR_OPENAI_API_KEY";
    private static final String API_URL = "https://api.openai.com/v1/chat/completions";
    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient();

        // 构建请求体
        String requestBody = """
                {
                    "model": "gpt-3.5-turbo",
                    "messages": [{"role": "user", "content": "请介绍一下Java语言"}],
                    "stream": true
                }
                """;

        Request request = new Request.Builder()
                .url(API_URL)
                .header("Authorization", "Bearer " + API_KEY)
                .header("Content-Type", "application/json")
                .post(RequestBody.create(requestBody, MediaType.parse("application/json")))
                .build();

        // 异步发送请求并处理流式响应
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) {
                    System.err.println("请求失败: " + response.code() + " " + response.message());
                    return;
                }

                // 逐行读取响应流
                try (ResponseBody responseBody = response.body()) {
                    if (responseBody == null) {
                        return;
                    }
                    responseBody.source().readAllLines().forEach(line -> {
                        // 过滤空行和结束标记
                        if (line.isEmpty() || line.equals("data: [DONE]")) {
                            return;
                        }
                        // 提取data部分的JSON内容
                        String jsonStr = line.substring(6); // 去掉前缀"data: "
                        try {
                            JsonNode jsonNode = objectMapper.readTree(jsonStr);
                            JsonNode choices = jsonNode.get("choices");
                            if (choices != null && choices.size() > 0) {
                                JsonNode delta = choices.get(0).get("delta");
                                if (delta != null && delta.has("content")) {
                                    // 输出流式返回的内容(不换行,模拟ChatGPT的打字效果)
                                    System.out.print(delta.get("content").asText());
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });
                    // 最后换行
                    System.out.println();
                } finally {
                    response.close();
                }
            }
        });

        // 防止主线程提前退出(仅示例用,实际项目按需处理)
        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Kotlin 实现

1. 添加OkHttp依赖

Gradle项目在build.gradle.kts中加入:

dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.11.0")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2")
}

2. 完整代码示例(协程版)

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

data class StreamResponse(
    val choices: List<Choice>
)

data class Choice(
    val delta: Delta
)

data class Delta(
    val content: String? = null
)

fun main() {
    val apiKey = "YOUR_OPENAI_API_KEY"
    val apiUrl = "https://api.openai.com/v1/chat/completions"
    val objectMapper = jacksonObjectMapper()
    val client = OkHttpClient()

    val requestBody = """
        {
            "model": "gpt-3.5-turbo",
            "messages": [{"role": "user", "content": "请介绍一下Kotlin语言"}],
            "stream": true
        }
    """.trimIndent()

    val request = Request.Builder()
        .url(apiUrl)
        .header("Authorization", "Bearer $apiKey")
        .header("Content-Type", "application/json")
        .post(requestBody.toRequestBody("application/json".toMediaType()))
        .build()

    // 使用协程异步处理
    GlobalScope.launch(Dispatchers.IO) {
        try {
            client.newCall(request).execute().use { response ->
                if (!response.isSuccessful) {
                    println("请求失败: ${response.code} ${response.message}")
                    return@launch
                }

                response.body?.source()?.use { source ->
                    while (!source.exhausted()) {
                        val line = source.readUtf8Line() ?: continue
                        if (line.isEmpty() || line == "data: [DONE]") continue

                        val jsonStr = line.substring(6)
                        val streamResponse = objectMapper.readValue<StreamResponse>(jsonStr)
                        streamResponse.choices.firstOrNull()?.delta?.content?.let { content ->
                            // 流式输出内容
                            print(content)
                        }
                    }
                    println()
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    // 防止主线程退出
    Thread.sleep(60000)
}

关键注意事项

  • 替换代码中的YOUR_OPENAI_API_KEY为你的OpenAI API密钥
  • 请求必须设置stream=true参数,API才会返回流式响应
  • 响应流中的每行以data: 开头,最后一行是data: [DONE]表示响应结束
  • 处理响应时需要逐行读取,过滤空行和结束标记,再解析JSON提取content字段

内容的提问来源于stack exchange,提问作者Ziad Halabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:25:11