|
|
|
@ -0,0 +1,248 @@
|
|
|
|
|
package com.dsideal.aiSupport.Test;
|
|
|
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
import com.dsideal.aiSupport.Plugin.YamlProp;
|
|
|
|
|
import com.google.common.io.ByteStreams;
|
|
|
|
|
import com.jfinal.kit.Prop;
|
|
|
|
|
import org.apache.commons.codec.binary.Hex;
|
|
|
|
|
|
|
|
|
|
import javax.crypto.Mac;
|
|
|
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
import java.io.OutputStream;
|
|
|
|
|
import java.net.HttpURLConnection;
|
|
|
|
|
import java.net.URL;
|
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
|
import java.nio.charset.Charset;
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
import java.security.MessageDigest;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
public class Sign {
|
|
|
|
|
static {
|
|
|
|
|
//加载配置文件
|
|
|
|
|
String configFile = "application_{?}.yaml".replace("{?}", getEnvPrefix());
|
|
|
|
|
PropKit = new YamlProp(configFile);
|
|
|
|
|
System.out.println("当前环境: " + getEnvPrefix());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:获取是否为开发环境
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getEnvPrefix() {
|
|
|
|
|
String myEnvVar = System.getenv("WORKING_ENV");
|
|
|
|
|
if (myEnvVar == null) {
|
|
|
|
|
myEnvVar = "dev";
|
|
|
|
|
}
|
|
|
|
|
return myEnvVar;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Prop PropKit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final BitSet URLENCODER = new BitSet(256);
|
|
|
|
|
private static final String CONST_ENCODE = "0123456789ABCDEF";
|
|
|
|
|
public static final Charset UTF_8 = StandardCharsets.UTF_8;
|
|
|
|
|
private final String region;
|
|
|
|
|
private final String service;
|
|
|
|
|
private final String schema;
|
|
|
|
|
private final String host;
|
|
|
|
|
private final String path;
|
|
|
|
|
private final String ak;
|
|
|
|
|
private final String sk;
|
|
|
|
|
|
|
|
|
|
static {
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 97; i <= 122; ++i) {
|
|
|
|
|
URLENCODER.set(i);
|
|
|
|
|
}
|
|
|
|
|
for (i = 65; i <= 90; ++i) {
|
|
|
|
|
URLENCODER.set(i);
|
|
|
|
|
}
|
|
|
|
|
for (i = 48; i <= 57; ++i) {
|
|
|
|
|
URLENCODER.set(i);
|
|
|
|
|
}
|
|
|
|
|
URLENCODER.set('-');
|
|
|
|
|
URLENCODER.set('_');
|
|
|
|
|
URLENCODER.set('.');
|
|
|
|
|
URLENCODER.set('~');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Sign(String region, String service, String schema, String host, String path, String ak, String sk) {
|
|
|
|
|
this.region = region;
|
|
|
|
|
this.service = service;
|
|
|
|
|
this.host = host;
|
|
|
|
|
this.schema = schema;
|
|
|
|
|
this.path = path;
|
|
|
|
|
this.ak = ak;
|
|
|
|
|
this.sk = sk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void doRequest(String method, Map<String, String> queryList, byte[] body,
|
|
|
|
|
Date date, String action, String version) throws Exception {
|
|
|
|
|
if (body == null) {
|
|
|
|
|
body = new byte[0];
|
|
|
|
|
}
|
|
|
|
|
String xContentSha256 = hashSHA256(body);
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
|
|
|
|
|
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
|
|
|
String xDate = sdf.format(date);
|
|
|
|
|
String shortXDate = xDate.substring(0, 8);
|
|
|
|
|
String contentType = "application/json";
|
|
|
|
|
String signHeader = "host;x-date;x-content-sha256;content-type";
|
|
|
|
|
|
|
|
|
|
SortedMap<String, String> realQueryList = new TreeMap<>(queryList);
|
|
|
|
|
realQueryList.put("Action", action);
|
|
|
|
|
realQueryList.put("Version", version);
|
|
|
|
|
StringBuilder querySB = new StringBuilder();
|
|
|
|
|
for (String key : realQueryList.keySet()) {
|
|
|
|
|
querySB.append(signStringEncoder(key)).append("=").append(signStringEncoder(realQueryList.get(key))).append("&");
|
|
|
|
|
}
|
|
|
|
|
querySB.deleteCharAt(querySB.length() - 1);
|
|
|
|
|
|
|
|
|
|
String canonicalStringBuilder = method + "\n" + path + "\n" + querySB + "\n" +
|
|
|
|
|
"host:" + host + "\n" +
|
|
|
|
|
"x-date:" + xDate + "\n" +
|
|
|
|
|
"x-content-sha256:" + xContentSha256 + "\n" +
|
|
|
|
|
"content-type:" + contentType + "\n" +
|
|
|
|
|
"\n" +
|
|
|
|
|
signHeader + "\n" +
|
|
|
|
|
xContentSha256;
|
|
|
|
|
String hashcanonicalString = hashSHA256(canonicalStringBuilder.getBytes());
|
|
|
|
|
String credentialScope = shortXDate + "/" + region + "/" + service + "/request";
|
|
|
|
|
String signString = "HMAC-SHA256" + "\n" + xDate + "\n" + credentialScope + "\n" + hashcanonicalString;
|
|
|
|
|
|
|
|
|
|
byte[] signKey = genSigningSecretKeyV4(sk, shortXDate, region, service);
|
|
|
|
|
String signature = HexFormat.of().formatHex(hmacSHA256(signKey, signString));
|
|
|
|
|
URL url = new URL(schema + "://" + host + path + "?" + querySB);
|
|
|
|
|
|
|
|
|
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
|
|
|
conn.setRequestMethod(method);
|
|
|
|
|
conn.setRequestProperty("Host", host);
|
|
|
|
|
conn.setRequestProperty("X-Date", xDate);
|
|
|
|
|
conn.setRequestProperty("X-Content-Sha256", xContentSha256);
|
|
|
|
|
conn.setRequestProperty("Content-Type", contentType);
|
|
|
|
|
conn.setRequestProperty("Authorization", "HMAC-SHA256" +
|
|
|
|
|
" Credential=" + ak + "/" + credentialScope +
|
|
|
|
|
", SignedHeaders=" + signHeader +
|
|
|
|
|
", Signature=" + signature);
|
|
|
|
|
if (!Objects.equals(conn.getRequestMethod(), "GET")) {
|
|
|
|
|
conn.setDoOutput(true);
|
|
|
|
|
OutputStream os = conn.getOutputStream();
|
|
|
|
|
os.write(body);
|
|
|
|
|
os.flush();
|
|
|
|
|
os.close();
|
|
|
|
|
}
|
|
|
|
|
conn.connect();
|
|
|
|
|
|
|
|
|
|
int responseCode = conn.getResponseCode();
|
|
|
|
|
|
|
|
|
|
InputStream is;
|
|
|
|
|
if (responseCode == 200) {
|
|
|
|
|
is = conn.getInputStream();
|
|
|
|
|
} else {
|
|
|
|
|
is = conn.getErrorStream();
|
|
|
|
|
}
|
|
|
|
|
String responseBody = new String(ByteStreams.toByteArray(is));
|
|
|
|
|
is.close();
|
|
|
|
|
|
|
|
|
|
System.out.println(responseCode);
|
|
|
|
|
System.out.println(responseBody);
|
|
|
|
|
|
|
|
|
|
JSONObject jo = JSON.parseObject(responseBody);
|
|
|
|
|
String imgBase64 = jo.getJSONObject("data").getString("binary_data_base64");
|
|
|
|
|
|
|
|
|
|
System.out.println(imgBase64);
|
|
|
|
|
String filePath = "D:/temp/result.jpg"; // 目标文件路径,可以自行设置合适的路径和文件名
|
|
|
|
|
|
|
|
|
|
// 对 Base64 字符串进行解码
|
|
|
|
|
Base64.Decoder decoder = Base64.getDecoder();
|
|
|
|
|
byte[] bytes = decoder.decode(imgBase64);
|
|
|
|
|
|
|
|
|
|
try (OutputStream os = new FileOutputStream(filePath)) { // 使用-with try-resources 自动关闭资源
|
|
|
|
|
os.write(bytes);
|
|
|
|
|
os.flush(); // 刷新缓冲区,确保数据写入文件
|
|
|
|
|
System.out.println("文件保存成功!");
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String signStringEncoder(String source) {
|
|
|
|
|
if (source == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
StringBuilder buf = new StringBuilder(source.length());
|
|
|
|
|
ByteBuffer bb = UTF_8.encode(source);
|
|
|
|
|
while (bb.hasRemaining()) {
|
|
|
|
|
int b = bb.get() & 255;
|
|
|
|
|
if (URLENCODER.get(b)) {
|
|
|
|
|
buf.append((char) b);
|
|
|
|
|
} else if (b == 32) {
|
|
|
|
|
buf.append("%20");
|
|
|
|
|
} else {
|
|
|
|
|
buf.append("%");
|
|
|
|
|
char hex1 = CONST_ENCODE.charAt(b >> 4);
|
|
|
|
|
char hex2 = CONST_ENCODE.charAt(b & 15);
|
|
|
|
|
buf.append(hex1);
|
|
|
|
|
buf.append(hex2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buf.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String hashSHA256(byte[] content) throws Exception {
|
|
|
|
|
try {
|
|
|
|
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
|
|
|
|
return Hex.encodeHexString(md.digest(content));
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new Exception("Unable to compute hash while signing request: " + e.getMessage(), e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static byte[] hmacSHA256(byte[] key, String content) throws Exception {
|
|
|
|
|
try {
|
|
|
|
|
Mac mac = Mac.getInstance("HmacSHA256");
|
|
|
|
|
mac.init(new SecretKeySpec(key, "HmacSHA256"));
|
|
|
|
|
return mac.doFinal(content.getBytes());
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new Exception("Unable to calculate a request signature: " + e.getMessage(), e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private byte[] genSigningSecretKeyV4(String secretKey, String date, String region, String service) throws Exception {
|
|
|
|
|
byte[] kDate = hmacSHA256((secretKey).getBytes(), date);
|
|
|
|
|
byte[] kRegion = hmacSHA256(kDate, region);
|
|
|
|
|
byte[] kService = hmacSHA256(kRegion, service);
|
|
|
|
|
return hmacSHA256(kService, "request");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
|
|
// 火山官网密钥信息, 注意sk结尾有==
|
|
|
|
|
String AccessKeyID = PropKit.get("JiMeng.ak");
|
|
|
|
|
String SecretAccessKey = PropKit.get("JiMeng.sk");
|
|
|
|
|
|
|
|
|
|
// 请求域名
|
|
|
|
|
String endpoint = "visual.volcengineapi.com";
|
|
|
|
|
String path = "/"; // 路径,不包含 Query// 请求接口信息
|
|
|
|
|
String service = "cv";
|
|
|
|
|
String region = "cn-north-1";
|
|
|
|
|
String schema = "https";
|
|
|
|
|
Sign sign = new Sign(region, service, schema, endpoint, path, AccessKeyID, SecretAccessKey);
|
|
|
|
|
// 参考接口文档Query参数
|
|
|
|
|
String action = "CVProcess";
|
|
|
|
|
String version = "2022-08-31";
|
|
|
|
|
Date date = new Date();
|
|
|
|
|
// 参考接口文档Body参数
|
|
|
|
|
JSONObject req = new JSONObject();
|
|
|
|
|
req.put("req_key", "jimeng_high_aes_general_v21_L");
|
|
|
|
|
req.put("prompt", "制作一张vlog视频封面。马卡龙配色,美女旅游照片+色块的拼贴画风格,主文案是“威海旅游vlog”,副文案是“特种兵一日游 被低估的旅游城市”,海报主体是一个穿着短裙、梳双马尾的少女,人物白色描边");
|
|
|
|
|
sign.doRequest("POST", new HashMap<>(), req.toString().getBytes(), date, action, version);
|
|
|
|
|
}
|
|
|
|
|
}
|