完整的 Java 示例代码,演示如何使用 Tokenra API。
- Java 11 或更高版本
- Maven 3.6 或更高版本
cd java
mvn clean installexport API_KEY="your_api_key_here"直接在代码中修改 API_KEY 常量。
演示最基本的 API 调用:
mvn exec:java -Dexec.mainClass="com.example.BasicRequest"功能:
- 发送简单的聊天请求
- 正确设置请求头和请求体
- 解析响应和 Token 使用统计
演示如何处理 Server-Sent Events (SSE) 流式响应:
mvn exec:java -Dexec.mainClass="com.example.StreamingRequest"功能:
- 启用流式输出 (
stream: true) - 逐块接收和显示响应
- 处理 SSE 格式数据
- 检测流结束标记
[DONE]
演示完整的错误处理和重试机制:
mvn exec:java -Dexec.mainClass="com.example.ErrorHandling"功能:
- HTTP 状态码检查
- 自定义异常类
- 指数退避重试策略
- 区分可重试和不可重试错误
- 超时处理
演示如何跟踪 Token 使用量并估算成本:
mvn exec:java -Dexec.mainClass="com.example.TokenUsage"功能:
- 提取使用统计 (
usage字段) - 成本计算
- 多轮对话 Token 累计
max_tokens参数影响分析- 提示词优化建议
- 月度成本估算
Request request = new Request.Builder()
.url(ENDPOINT)
.addHeader("Authorization", "Bearer " + API_KEY)
.post(body)
.build();JsonObject payload = new JsonObject();
payload.addProperty("model", "kimi-k3.1-pro");
payload.addProperty("max_tokens", 1024);
payload.addProperty("stream", false);
JsonArray messages = new JsonArray();
JsonObject message = new JsonObject();
message.addProperty("role", "user");
message.addProperty("content", "你的问题");
messages.add(message);
payload.add("messages", messages);OkHttpClient client = new OkHttpClient();
Gson gson = new Gson();
RequestBody body = RequestBody.create(
gson.toJson(payload),
MediaType.get("application/json; charset=utf-8")
);
Request request = new Request.Builder()
.url(ENDPOINT)
.addHeader("Authorization", "Bearer " + API_KEY)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("HTTP " + response.code());
}
JsonObject result = gson.fromJson(response.body().string(), JsonObject.class);
// 处理结果
}自动关闭资源,避免内存泄漏:
try (Response response = client.newCall(request).execute()) {
// 处理响应
}检查响应状态并抛出异常:
if (!response.isSuccessful()) {
String errorBody = response.body().string();
throw new IOException("HTTP " + response.code() + ": " + errorBody);
}使用 BufferedReader 读取 SSE 流:
InputStream inputStream = response.body().byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("data: ")) {
String dataStr = line.substring(6);
// 处理数据
}
}配置连接和读取超时:
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();实现指数退避重试:
for (int attempt = 0; attempt <= maxRetries; attempt++) {
try {
// 发送请求
return response;
} catch (IOException e) {
if (attempt < maxRetries) {
int delay = initialDelay * (int) Math.pow(2, attempt);
Thread.sleep(delay);
} else {
throw e;
}
}
}高效的 HTTP 客户端:
- 连接池和复用
- GZIP 压缩
- 响应缓存
- 超时配置
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>Google 的 JSON 库:
- 简洁的 API
- 类型安全
- 对象序列化/反序列化
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>如果你正在使用类似 OpenAI 的 Java SDK,迁移步骤:
- 更换 Base URL:
// 原来
OpenAiService service = new OpenAiService("your_openai_key");
// 现在 - 使用 OkHttp 直接调用
OkHttpClient client = new OkHttpClient();
String endpoint = "https://tokenra.io/v1/chat/completions";- 调整请求构造:
// 使用相同的请求格式
JsonObject payload = new JsonObject();
payload.addProperty("model", "kimi-k3.1-pro");
// ... 其余参数相同A: 使用 try-catch 捕获 JsonSyntaxException:
try {
JsonObject result = gson.fromJson(responseBody, JsonObject.class);
} catch (JsonSyntaxException e) {
System.err.println("JSON 解析失败: " + e.getMessage());
}A: 配置 OkHttpClient 的代理:
Proxy proxy = new Proxy(
Proxy.Type.HTTP,
new InetSocketAddress("proxy.example.com", 8080)
);
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy)
.build();A: 确保使用 UTF-8 编码:
MediaType JSON = MediaType.get("application/json; charset=utf-8");
RequestBody body = RequestBody.create(json, JSON);
// 读取响应时也要指定编码
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream, StandardCharsets.UTF_8)
);A: 使用 ExecutorService:
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<JsonObject>> futures = new ArrayList<>();
for (String message : messages) {
Future<JsonObject> future = executor.submit(() -> sendRequest(message));
futures.add(future);
}
// 获取结果
for (Future<JsonObject> future : futures) {
JsonObject result = future.get();
}
executor.shutdown();OkHttp 默认使用连接池,无需额外配置。
OkHttp 自动处理 GZIP 压缩。
创建一个全局的 OkHttpClient 实例,避免重复创建:
public class ApiClient {
private static final OkHttpClient CLIENT = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
public static OkHttpClient getClient() {
return CLIENT;
}
}使用 OkHttp 的异步 API:
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
// 处理响应
}
@Override
public void onFailure(Call call, IOException e) {
// 处理错误
}
});定义请求和响应的 Java 类:
public class ChatRequest {
private String model;
private List<Message> messages;
private int max_tokens;
private boolean stream;
// getters and setters
}
public class Message {
private String role;
private String content;
// getters and setters
}
public class ChatResponse {
private String id;
private List<Choice> choices;
private Usage usage;
// getters and setters
}
// 使用
ChatRequest request = new ChatRequest();
request.setModel("kimi-k3.1-pro");
// ...
String json = gson.toJson(request);
ChatResponse response = gson.fromJson(responseBody, ChatResponse.class);mvn package
java -jar target/api-tutorial-java-1.0.0.jar使用 Maven Shade Plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>添加 JUnit 依赖:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>编写测试:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class BasicRequestTest {
@Test
void testSendRequest() throws IOException {
BasicRequest client = new BasicRequest();
JsonObject result = client.sendBasicRequest();
assertNotNull(result);
assertTrue(result.has("choices"));
}
}