艾思科蓝开放平台

多语言签名示例

以下示例口径完全一致:submit 提交(JSON + 文件 base64)→ query 查询 → report 取报告地址。把 APP_ID 与 APP_SECRET 替换为您的值即可运行。

Java
// 开放 API 签名与调用示例(Java 17+)。
// JSON 序列化用 Jackson(主流三方库);HMAC/HTTP 用 JDK 自带。
// 依赖:com.fasterxml.jackson.core:jackson-databind(Maven 引入后编译运行)。
// <dependency>
// <groupId>com.fasterxml.jackson.core</groupId>
// <artifactId>jackson-databind</artifactId>
// <version>2.17.0</version>
// </dependency>
// 用法:APP_ID=oa... APP_SECRET=... java -cp .:jackson-*.jar SignAndSubmit submit ./paper.pdf 2 OT001 "标题"
// APP_ID=oa... APP_SECRET=... java ... SignAndSubmit query <taskNo> | online <taskNo>
//
// 签名:以 appSecret(Base64 解码为 32 字节)为密钥对待签内容做 HMAC-SHA256,结果 Base64。
// bodyHash = SHA-256(原始 JSON body 字节) 的十六进制小写;GET 用空串。
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.HexFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class SignAndSubmit {
static final String BASE_URL = envOr("BASE_URL", "https://open.ais.cn");
static final String APP_ID = System.getenv("APP_ID");
static final String APP_SECRET = System.getenv("APP_SECRET"); // 平台下发的 Base64 共享密钥
static final ObjectMapper MAPPER = new ObjectMapper();
public static void main(String[] args) throws Exception {
switch (args[0]) {
case "submit" -> submit(Path.of(args[1]), args[2], args[3], args.length > 4 ? args[4] : null);
case "query" -> get("/api/open/v1/tasks/query/" + args[1]);
case "online" -> get("/api/open/v1/tasks/online/" + args[1]);
default -> System.err.println("usage: submit <file> <checkType> <outTradeNo> <title> | query <taskNo> | online <taskNo>");
}
}
static void submit(Path file, String checkType, String outTradeNo, String title) throws Exception {
String path = "/api/open/v1/tasks/submit";
String fileBase64 = Base64.getEncoder().encodeToString(Files.readAllBytes(file));
// 用 Jackson 组 JSON body(LinkedHashMap 保序);序列化结果即实际发送的字节,用于 bodyHash
// 公共字段在顶层;类型专属参数(文件/引文等)收在 payload 子对象
Map<String, Object> payload = new LinkedHashMap<>();
payload.put("fileName", file.getFileName().toString());
payload.put("fileBase64", fileBase64);
Map<String, Object> reqBody = new LinkedHashMap<>();
reqBody.put("outTradeNo", outTradeNo);
reqBody.put("checkType", Integer.parseInt(checkType)); // 数字码:1=AI率 2=相似度 3=参考文献
reqBody.put("title", title);
reqBody.put("payload", payload);
byte[] bodyBytes = MAPPER.writeValueAsBytes(reqBody);
Map<String, String> headers = authHeaders("POST", path, sha256Hex(bodyBytes));
HttpRequest.Builder rb = HttpRequest.newBuilder(URI.create(BASE_URL + path))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofByteArray(bodyBytes));
headers.forEach(rb::header);
System.out.println(HttpClient.newHttpClient().send(rb.build(), HttpResponse.BodyHandlers.ofString()).body());
}
static void get(String path) throws Exception {
Map<String, String> headers = authHeaders("GET", path, sha256Hex(new byte[0]));
HttpRequest.Builder rb = HttpRequest.newBuilder(URI.create(BASE_URL + path)).GET();
headers.forEach(rb::header);
System.out.println(HttpClient.newHttpClient().send(rb.build(), HttpResponse.BodyHandlers.ofString()).body());
}
static Map<String, String> authHeaders(String method, String path, String bodyHash) throws Exception {
String ts = String.valueOf(System.currentTimeMillis());
byte[] nb = new byte[16];
new SecureRandom().nextBytes(nb);
String nonce = HexFormat.of().formatHex(nb);
String content = method + "\n" + path + "\n" + ts + "\n" + nonce + "\n" + bodyHash;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(Base64.getDecoder().decode(APP_SECRET), "HmacSHA256"));
String sign = Base64.getEncoder().encodeToString(mac.doFinal(content.getBytes(StandardCharsets.UTF_8)));
Map<String, String> h = new LinkedHashMap<>();
h.put("X-App-Id", APP_ID);
h.put("X-Timestamp", ts);
h.put("X-Nonce", nonce);
h.put("X-Signature", sign);
return h;
}
static String sha256Hex(byte[] data) throws Exception {
return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(data));
}
static String envOr(String k, String d) {
String v = System.getenv(k);
return v == null || v.isBlank() ? d : v;
}
}