Java
Maven 依赖(pom.xml 中添加)
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-sse</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
</dependencies>如果你已使用 Spring Boot 3,可直接用 Spring 自带的 RestTemplate / WebClient,无需额外引入 OkHttp。
1) 非流式聊天 - UmengAiClient.java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class UmengAiClient {
private static final String BASE_URL = "https://ai.umeng.com";
private static final String API_KEY = "YOUR_API_KEY";
// OkHttp 默认 readTimeout 仅 10 秒,大模型响应普遍超过 10 秒,必须显式调大
private final OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.build();
private final ObjectMapper mapper = new ObjectMapper();
public String chat(String prompt) throws Exception {
Map<String, Object> body = Map.of(
"model", "auto",
"enableThinking", false,
"messages", List.of(Map.of("role", "user", "content", prompt))
);
Request req = new Request.Builder()
.url(BASE_URL + "/api/llm/chat")
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.post(RequestBody.create(
mapper.writeValueAsBytes(body),
MediaType.get("application/json")))
.build();
try (Response resp = client.newCall(req).execute()) {
JsonNode json = mapper.readTree(resp.body().byteStream());
if (!json.path("success").asBoolean()) {
throw new RuntimeException("接口返回失败: " + json.path("msg").asText());
}
JsonNode data = json.path("data");
System.out.printf("路由模型=%s, 算力点=%d%n",
data.path("meta").path("actual_model").asText(),
data.path("usage").path("cost_credits").asInt());
return data.path("content").asText();
}
}
public static void main(String[] args) throws Exception {
System.out.println("回答: " + new UmengAiClient().chat("用一句话介绍牛顿第一定律"));
}
}2) 流式聊天(SSE) - 逐字接收
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class UmengAiStreamClient {
private static final String BASE_URL = "https://ai.umeng.com";
private static final String API_KEY = "YOUR_API_KEY";
public static void main(String[] args) throws Exception {
// SSE 长连接必须调大 readTimeout
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(300, TimeUnit.SECONDS)
.build();
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> body = Map.of(
"model", "auto",
"enableThinking", false,
"messages", List.of(Map.of("role", "user", "content", "请用 Python 写一个 LRU 缓存"))
);
Request req = new Request.Builder()
.url(BASE_URL + "/api/llm/chat/stream")
.header("Authorization", "Bearer " + API_KEY)
.header("Accept", "text/event-stream")
.post(RequestBody.create(
mapper.writeValueAsBytes(body),
MediaType.get("application/json")))
.build();
CountDownLatch latch = new CountDownLatch(1);
EventSources.createFactory(client).newEventSource(req, new EventSourceListener() {
@Override public void onEvent(EventSource es, String id, String type, String data) {
try {
JsonNode node = mapper.readTree(data);
if ("delta".equals(type)) {
System.out.print(node.path("delta").asText());
} else if ("done".equals(type)) {
System.out.printf("%n[完成] tokens=%d%n", node.path("total_tokens").asInt());
latch.countDown();
}
} catch (Exception e) { e.printStackTrace(); }
}
@Override public void onFailure(EventSource es, Throwable t, Response r) {
t.printStackTrace();
latch.countDown();
}
});
latch.await();
}
}3) 图像生成
// readTimeout 调至 180 秒(图像生成需 20~60 秒)
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(180, TimeUnit.SECONDS)
.build();
Map<String, Object> body = Map.of(
"model", "doubao-seedream-5-0-pro-260628",
"messages", List.of(Map.of("role", "user", "content", "一只在滑雪的柴犬")),
"imageParams", Map.of("size", "1024x1024", "quality", "low", "n", 1)
);
// 返回 content 为 Markdown 图片链接
JsonNode json = mapper.readTree(resp.body().byteStream());
String markdown = json.path("data").path("content").asText();
String imageUrl = markdown.substring(markdown.indexOf("(") + 1, markdown.lastIndexOf(")"));
System.out.println("图片地址: " + imageUrl);4) 视频生成(两步:提交 + 轮询)
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
ObjectMapper mapper = new ObjectMapper();
MediaType JSON = MediaType.parse("application/json");
// ① 提交任务
Map<String, Object> body = Map.of(
"model", "wan2.5-t2v-preview",
"messages", List.of(Map.of("role", "user", "content", "一只橘猫在窗台上晒太阳")),
"videoParams", Map.of("resolution", "480P", "ratio", "16:9", "duration", 5)
);
Request submit = new Request.Builder()
.url(BASE_URL + "/api/llm/chat")
.addHeader("Authorization", "Bearer " + API_KEY)
.post(RequestBody.create(mapper.writeValueAsString(body), JSON))
.build();
String requestId;
try (Response resp = client.newCall(submit).execute()) {
JsonNode data = mapper.readTree(resp.body().string()).path("data");
requestId = data.path("request_id").asText();
System.out.println("任务已提交: " + requestId);
}
// ② 轮询结果
for (int i = 1; i <= 40; i++) {
Request query = new Request.Builder()
.url(BASE_URL + "/api/llm/chat/video/result")
.addHeader("Authorization", "Bearer " + API_KEY)
.post(RequestBody.create("{\"requestId\":\"" + requestId + "\"}", JSON))
.build();
JsonNode data;
try (Response resp = client.newCall(query).execute()) {
data = mapper.readTree(resp.body().string()).path("data");
}
String status = data.path("status").asText();
System.out.println("第 " + i + " 次轮询,状态: " + status);
if ("SUCCEEDED".equals(status)) {
System.out.println("视频地址: " + data.path("video_url").asText());
System.out.println("扣费: " + data.path("credits").asDouble() + " 算力点");
break;
}
if ("FAILED".equals(status)) break;
TimeUnit.SECONDS.sleep(15);
}