main
HuangHai 2 months ago
parent 2b8c28b2f7
commit 6f61af1fff

@ -43,6 +43,16 @@
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.0</version>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>com.alibaba</groupId>

@ -0,0 +1,58 @@
package com.dsideal.aiSupport.Util.AiPpt;
import com.alibaba.fastjson.JSONObject;
import com.dsideal.aiSupport.Util.AiPpt.Kit.ApiKit;
import com.dsideal.aiSupport.Util.AiPpt.Kit.HttpUtils;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
/**
* PPT
*
* @author veasion
* @date 2024/7/12
*/
public class AiPptDemo1 extends ApiKit {
public static void main(String[] args) throws Exception {
// 第三方用户ID数据隔离
String uid = "test";
String subject = "AI未来的发展";
// 创建 api token (有效期2小时建议缓存到redis同一个 uid 创建时之前的 token 会在10秒内失效)
String apiToken = ApiKit.createApiToken(uid, null);
System.out.println("api token: " + apiToken);
// 生成大纲
System.out.println("\n\n========== 正在生成大纲 ==========");
String outline = ApiKit.generateOutline(apiToken, subject, null, null);
// 生成大纲内容
System.out.println("\n\n========== 正在生成大纲内容 ==========");
String markdown = ApiKit.generateContent(apiToken, outline, null, null);
// 随机一个模板
System.out.println("\n\n========== 随机选择模板 ==========");
String templateId = ApiKit.randomOneTemplateId(apiToken);
System.out.println(templateId);
// 生成PPT
System.out.println("\n\n========== 正在生成PPT ==========");
JSONObject pptInfo = ApiKit.generatePptx(apiToken, templateId, markdown, false);
String pptId = pptInfo.getString("id");
System.out.println("pptId: " + pptId);
System.out.println("ppt主题" + pptInfo.getString("subject"));
System.out.println("ppt封面" + pptInfo.getString("coverUrl") + "?token=" + apiToken);
// 下载PPT到桌面
System.out.println("\n\n========== 正在下载PPT ==========");
JSONObject result = ApiKit.downloadPptx(apiToken, pptId);
String url = result.getString("fileUrl");
System.out.println("ppt链接" + url);
String savePath = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + pptId + ".pptx";
HttpUtils.download(url, new File(savePath));
System.out.println("ppt下载完成保存路径" + savePath);
}
}

@ -0,0 +1,62 @@
package com.dsideal.aiSupport.Util.AiPpt;
import com.alibaba.fastjson.JSONObject;
import com.dsideal.aiSupport.Util.AiPpt.Kit.ApiKit;
import com.dsideal.aiSupport.Util.AiPpt.Kit.HttpUtils;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.util.Map;
/**
* PPT
*
* @author veasion
* @date 2024/7/12
*/
public class AiPptDemo2 extends ApiKit {
public static void main(String[] args) throws Exception {
// 第三方用户ID数据隔离
String uid = "test";
// 文档文件,支持 word/excel/ppt/md/txt/pdf 等类型
File file = new File("README.md");
// 创建 api token (有效期2小时建议缓存到redis同一个 uid 创建时之前的 token 会在10秒内失效)
String apiToken = ApiKit.createApiToken(uid, null);
System.out.println("apiToken: " + apiToken);
// 解析文件
String dataUrl = ApiKit.parseFileData(apiToken, file, null, null);
// 生成大纲
System.out.println("\n\n========== 正在生成大纲 ==========");
String outline = ApiKit.generateOutline(apiToken, null, dataUrl, null);
// 异步生成大纲内容
System.out.println("\n\n========== 正在异步生成大纲内容 ==========");
Map<String, String> pptInfo = ApiKit.asyncGenerateContent(apiToken, outline, dataUrl, null, null);
String pptId = pptInfo.get("id");
// 下载PPT到桌面
System.out.println("\n\n========== 正在下载PPT ==========");
System.out.println("pptId: " + pptId);
String url = null;
for (int i = 0; i < 30; i++) {
// 等待PPT文件可下载
JSONObject result = ApiKit.downloadPptx(apiToken, pptId);
if (result != null) {
url = result.getString("fileUrl");
if (url != null) {
break;
}
}
Thread.sleep(1000);
}
System.out.println("ppt链接" + url);
String savePath = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + pptId + ".pptx";
HttpUtils.download(url, new File(savePath));
System.out.println("ppt下载完成保存路径" + savePath);
}
}

@ -0,0 +1,45 @@
package com.dsideal.aiSupport.Util.AiPpt;
import com.alibaba.fastjson.JSONObject;
import com.dsideal.aiSupport.Util.AiPpt.Kit.ApiKit;
import com.dsideal.aiSupport.Util.AiPpt.Kit.HttpUtils;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
/**
* PPT
*
* @author veasion
* @date 2024/7/12
*/
public class AiPptDemo3 extends ApiKit {
public static void main(String[] args) throws Exception {
// 第三方用户ID数据隔离
String uid = "test";
String subject = "AI未来的发展";
// 创建 api token (有效期2小时建议缓存到redis同一个 uid 创建时之前的 token 会在10秒内失效)
String apiToken = ApiKit.createApiToken(uid, null);
System.out.println("apiToken: " + apiToken);
// 通过主题直接生成PPT
System.out.println("\n正在生成PPT...\n");
JSONObject pptInfo = ApiKit.directGeneratePptx(apiToken, true, null, subject, null, null, false);
String pptId = pptInfo.getString("id");
String fileUrl = pptInfo.getString("fileUrl");
System.out.println("\n\n===============");
System.out.println("pptId: " + pptId);
System.out.println("ppt主题" + pptInfo.getString("subject"));
System.out.println("ppt封面" + pptInfo.getString("coverUrl"));
System.out.println("ppt链接" + fileUrl);
// 下载PPT到桌面
String savePath = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + pptId + ".pptx";
HttpUtils.download(fileUrl, new File(savePath));
System.out.println("ppt下载完成保存路径" + savePath);
}
}

@ -0,0 +1,49 @@
package com.dsideal.aiSupport.Util.AiPpt;
import com.alibaba.fastjson.JSONObject;
import com.dsideal.aiSupport.Util.AiPpt.Kit.ApiKit;
import com.dsideal.aiSupport.Util.AiPpt.Kit.HttpUtils;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
/**
* PPT
*
* @author veasion
* @date 2024/7/12
*/
public class AiPptDemo4 {
public static void main(String[] args) throws Exception {
// 第三方用户ID数据隔离
String uid = "test";
// 文档文件,支持 word/excel/ppt/md/txt/pdf 等类型
File file = new File("README.md");
// 创建 api token (有效期2小时建议缓存到redis同一个 uid 创建时之前的 token 会在10秒内失效)
String apiToken = ApiKit.createApiToken( uid, null);
System.out.println("apiToken: " + apiToken);
// 解析文件
String dataUrl = ApiKit.parseFileData(apiToken, file, null, null);
// 通过文件直接生成PPT
System.out.println("\n正在生成PPT...\n");
JSONObject pptInfo = ApiKit.directGeneratePptx(apiToken, true, null, null, dataUrl, null, false);
String pptId = pptInfo.getString("id");
String fileUrl = pptInfo.getString("fileUrl");
System.out.println("\n\n===============");
System.out.println("pptId: " + pptId);
System.out.println("ppt主题" + pptInfo.getString("subject"));
System.out.println("ppt封面" + pptInfo.getString("coverUrl"));
System.out.println("ppt链接" + fileUrl);
// 下载PPT到桌面
String savePath = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath() + File.separator + pptId + ".pptx";
HttpUtils.download(fileUrl, new File(savePath));
System.out.println("ppt下载完成保存路径" + savePath);
}
}

@ -0,0 +1,304 @@
package com.dsideal.aiSupport.Util.AiPpt.Kit;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dsideal.aiSupport.Plugin.YamlProp;
import com.jfinal.kit.Prop;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static com.dsideal.aiSupport.AiSupportApplication.getEnvPrefix;
/**
* Api
*
* @author luozhuowei
* @date 2024/7/15
*/
public class ApiKit {
public static Prop PropKit; // 配置文件工具
protected static String BASE_URL;
protected static String apiKey; // 填写access key
static {
//加载配置文件
String configFile = "application_{?}.yaml".replace("{?}", getEnvPrefix());
PropKit = new YamlProp(configFile);
BASE_URL = PropKit.get("AIPPT.BASE_URL");
apiKey = PropKit.get("GPTNB.sk");
}
public static String createApiToken(String uid, Integer limit) {
String url = BASE_URL + "/api/user/createApiToken";
JSONObject body = new JSONObject();
body.put("uid", uid);
body.put("limit", limit);
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
httpRequest.setBody(body.toJSONString());
httpRequest.addHeaders("Api-Key", apiKey);
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
if (response.getStatus() != 200) {
throw new RuntimeException("创建apiToken失败httpStatus=" + response.getStatus());
}
JSONObject result = response.getResponseToJson();
if (result.getIntValue("code") != 0) {
throw new RuntimeException("创建apiToken异常" + result.getString("message"));
}
return result.getJSONObject("data").getString("token");
}
public static String parseFileData(String apiToken, File file, String content, String fileUrl) {
String url = BASE_URL + "/api/ppt/parseFileData";
HttpUtils.HttpRequest httpRequest = new HttpUtils.HttpRequest();
httpRequest.setUrl(url);
httpRequest.setMethod("POST");
httpRequest.addHeaders("token", apiToken);
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setCharset(StandardCharsets.UTF_8);
if (file != null) {
multipartEntity.addBinaryBody("file", file);
}
if (content != null) {
multipartEntity.addTextBody("content", content, ContentType.create("text/plain", StandardCharsets.UTF_8));
}
if (fileUrl != null) {
multipartEntity.addTextBody("fileUrl", fileUrl, ContentType.create("text/plain", StandardCharsets.UTF_8));
}
httpRequest.setBody(multipartEntity.build());
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
if (response.getStatus() != 200) {
throw new RuntimeException("解析文件或内容失败httpStatus=" + response.getStatus());
}
JSONObject result = response.getResponseToJson();
if (result.getIntValue("code") != 0) {
throw new RuntimeException("解析文件或内容异常," + result.getString("message"));
}
return result.getJSONObject("data").getString("dataUrl");
}
public static String generateOutline(String apiToken, String subject, String dataUrl, String prompt) {
String url = BASE_URL + "/api/ppt/generateOutline";
JSONObject body = new JSONObject();
body.put("subject", subject);
body.put("dataUrl", dataUrl);
body.put("prompt", prompt);
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
httpRequest.setBody(body.toJSONString());
httpRequest.addHeaders("token", apiToken);
StringBuilder sb = new StringBuilder();
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
if (data == null || data.isEmpty()) {
return;
}
JSONObject json = JSONObject.parseObject(data);
if (Objects.equals(json.getInteger("status"), -1)) {
throw new RuntimeException(json.getString("error"));
}
String text = json.getString("text");
sb.append(text);
// 打印输出
System.out.print(text);
});
if (response.getStatus() != 200) {
throw new RuntimeException("生成大纲失败httpStatus=" + response.getStatus());
}
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
JSONObject result = response.getResponseToJson();
throw new RuntimeException("生成大纲失败:" + result.getString("message"));
}
return sb.toString();
}
public static String generateContent(String apiToken, String outlineMarkdown, String dataUrl, String prompt) {
String url = BASE_URL + "/api/ppt/generateContent";
JSONObject body = new JSONObject();
body.put("outlineMarkdown", outlineMarkdown);
body.put("dataUrl", dataUrl);
body.put("prompt", prompt);
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
httpRequest.setBody(body.toJSONString());
httpRequest.addHeaders("token", apiToken);
StringBuilder sb = new StringBuilder();
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
if (data == null || data.isEmpty()) {
return;
}
JSONObject json = JSONObject.parseObject(data);
if (Objects.equals(json.getInteger("status"), -1)) {
throw new RuntimeException(json.getString("error"));
}
String text = json.getString("text");
sb.append(text);
// 打印输出
System.out.print(text);
});
if (response.getStatus() != 200) {
throw new RuntimeException("生成大纲内容失败httpStatus=" + response.getStatus());
}
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
JSONObject result = response.getResponseToJson();
throw new RuntimeException("生成大纲内容失败:" + result.getString("message"));
}
return sb.toString();
}
public static Map<String, String> asyncGenerateContent(String apiToken, String outlineMarkdown, String dataUrl, String templateId, String prompt) {
String url = BASE_URL + "/api/ppt/generateContent";
JSONObject body = new JSONObject();
body.put("asyncGenPptx", true);
body.put("templateId", templateId);
body.put("outlineMarkdown", outlineMarkdown);
body.put("dataUrl", dataUrl);
body.put("prompt", prompt);
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
httpRequest.setBody(body.toJSONString());
httpRequest.addHeaders("token", apiToken);
Map<String, String> pptInfo = new HashMap<>();
StringBuilder sb = new StringBuilder();
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
if (data == null || data.isEmpty()) {
return;
}
JSONObject json = JSONObject.parseObject(data);
if (Objects.equals(json.getInteger("status"), -1)) {
throw new RuntimeException(json.getString("error"));
}
if (json.getString("pptId") != null) {
pptInfo.put("id", json.getString("pptId"));
}
String text = json.getString("text");
sb.append(text);
// 打印输出
System.out.print(text);
});
if (response.getStatus() != 200) {
throw new RuntimeException("生成大纲内容失败httpStatus=" + response.getStatus());
}
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
JSONObject result = response.getResponseToJson();
throw new RuntimeException("生成大纲内容失败:" + result.getString("message"));
}
pptInfo.put("markdown", sb.toString());
return pptInfo;
}
public static String randomOneTemplateId(String apiToken) {
String url = BASE_URL + "/api/ppt/randomTemplates";
JSONObject body = new JSONObject();
body.put("size", 1);
JSONObject filters = new JSONObject();
filters.put("type", 1);
body.put("filters", filters);
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
httpRequest.setBody(body.toJSONString());
httpRequest.addHeaders("token", apiToken);
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
if (response.getStatus() != 200) {
throw new RuntimeException("获取模板失败httpStatus=" + response.getStatus());
}
JSONObject result = response.getResponseToJson();
if (result.getIntValue("code") != 0) {
throw new RuntimeException("获取模板异常," + result.getString("message"));
}
JSONArray data = result.getJSONArray("data");
JSONObject template = data.getJSONObject(0);
return template.getString("id");
}
public static JSONObject generatePptx(String apiToken, String templateId, String markdown, boolean pptxProperty) {
String url = BASE_URL + "/api/ppt/generatePptx";
JSONObject body = new JSONObject();
body.put("templateId", templateId);
body.put("outlineContentMarkdown", markdown);
body.put("pptxProperty", pptxProperty);
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
httpRequest.setBody(body.toJSONString());
httpRequest.addHeaders("token", apiToken);
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
if (response.getStatus() != 200) {
throw new RuntimeException("生成PPT失败httpStatus=" + response.getStatus());
}
JSONObject result = response.getResponseToJson();
if (result.getIntValue("code") != 0) {
throw new RuntimeException("生成PPT异常" + result.getString("message"));
}
return result.getJSONObject("data").getJSONObject("pptInfo");
}
public static JSONObject downloadPptx(String apiToken, String id) {
String url = BASE_URL + "/api/ppt/downloadPptx";
JSONObject body = new JSONObject();
body.put("id", id);
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
httpRequest.setBody(body.toJSONString());
httpRequest.addHeaders("token", apiToken);
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
if (response.getStatus() != 200) {
throw new RuntimeException("下载PPT失败httpStatus=" + response.getStatus());
}
JSONObject result = response.getResponseToJson();
if (result.getIntValue("code") != 0) {
throw new RuntimeException("下载PPT异常" + result.getString("message"));
}
return result.getJSONObject("data");
}
public static JSONObject directGeneratePptx(String apiToken, boolean stream, String templateId, String subject, String dataUrl, String prompt, boolean pptxProperty) {
String url = BASE_URL + "/api/ppt/directGeneratePptx";
JSONObject body = new JSONObject();
body.put("stream", stream);
body.put("templateId", templateId);
body.put("subject", subject);
body.put("dataUrl", dataUrl);
body.put("prompt", prompt);
body.put("pptxProperty", pptxProperty);
HttpUtils.HttpRequest httpRequest = HttpUtils.HttpRequest.postJson(url);
httpRequest.setBody(body.toJSONString());
httpRequest.addHeaders("token", apiToken);
if (stream) {
// 流式生成
JSONObject[] pptInfo = new JSONObject[1];
HttpUtils.HttpResponse response = HttpUtils.requestWithEventStream(httpRequest, data -> {
if (data == null || data.isEmpty()) {
return;
}
JSONObject json = JSONObject.parseObject(data);
if (Objects.equals(json.getInteger("status"), -1)) {
throw new RuntimeException(json.getString("error"));
}
if (Objects.equals(json.getInteger("status"), 4) && json.containsKey("result")) {
pptInfo[0] = json.getJSONObject("result");
}
String text = json.getString("text");
// 打印输出
System.out.print(text);
});
if (response.getStatus() != 200) {
throw new RuntimeException("生成PPT失败httpStatus=" + response.getStatus());
}
if (response.getHeaders().getOrDefault("Content-Type", response.getHeaders().get("content-type")).contains("application/json")) {
JSONObject result = response.getResponseToJson();
throw new RuntimeException("生成PPT失败" + result.getString("message"));
}
return pptInfo[0];
} else {
// 非流式生成
HttpUtils.HttpResponse response = HttpUtils.request(httpRequest);
if (response.getStatus() != 200) {
throw new RuntimeException("生成PPT失败httpStatus=" + response.getStatus());
}
JSONObject result = response.getResponseToJson();
if (result.getIntValue("code") != 0) {
throw new RuntimeException("生成PPT异常" + result.getString("message"));
}
return result.getJSONObject("data").getJSONObject("pptInfo");
}
}
}

@ -0,0 +1,665 @@
package com.dsideal.aiSupport.Util.AiPpt.Kit;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.SocketException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* HttpUtils
*
* @author veasion
* @date 2021/9/13
*/
public class HttpUtils {
public static final String CHARSET_DEFAULT = "UTF-8";
public static final String CONTENT_TYPE = "Content-Type";
public static final String CONTENT_TYPE_JSON = "application/json";
public static final String CONTENT_TYPE_FORM_DATA = "application/x-www-form-urlencoded";
private static final PoolingHttpClientConnectionManager CONNECTION_MANAGER;
private static final int MAX_CONNECT_TIMEOUT = 8000;
private static final int MAX_SOCKET_TIMEOUT = 90000;
static {
CONNECTION_MANAGER = new PoolingHttpClientConnectionManager(getDefaultRegistry());
CONNECTION_MANAGER.setMaxTotal(500);
CONNECTION_MANAGER.setDefaultMaxPerRoute(50);
CONNECTION_MANAGER.setValidateAfterInactivity(2000);
}
public static HttpResponse get(String url) {
return get(url, null);
}
public static HttpResponse get(String url, Map<String, Object> params) {
String urlLinks = getUrlLinks(params);
if (urlLinks != null) {
if (url.contains("?")) {
url = url + "&" + urlLinks;
} else {
url = url + "?" + urlLinks;
}
}
return request(HttpRequest.build(url, "GET"));
}
public static void download(String url, File destFile) throws Exception {
HttpRequest request = HttpRequest.build(url, "GET");
request.setResponseHandler(entity -> {
try {
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
try (FileOutputStream fs = new FileOutputStream(destFile)) {
entity.writeTo(fs);
}
return destFile;
} catch (Exception e) {
return e;
}
});
HttpResponse response = request(request);
if (response.getResponse() instanceof Exception) {
throw (Exception) response.getResponse();
}
}
public static HttpResponse postJson(String url, String bodyJson) {
HttpRequest request = HttpRequest.build(url, "POST").setBody(bodyJson);
if (request.getHeaders() == null) {
request.setHeaders(Collections.singletonMap(CONTENT_TYPE, CONTENT_TYPE_JSON));
} else {
request.getHeaders().put(CONTENT_TYPE, CONTENT_TYPE_JSON);
}
return request(request);
}
public static HttpResponse postForm(String url, Map<String, Object> params) {
String urlLinks = getUrlLinks(params);
HttpRequest request = HttpRequest.build(url, "POST").setBody(urlLinks != null ? urlLinks : "");
if (request.getHeaders() == null) {
request.setHeaders(Collections.singletonMap(CONTENT_TYPE, CONTENT_TYPE_FORM_DATA));
} else {
request.getHeaders().put(CONTENT_TYPE, CONTENT_TYPE_FORM_DATA);
}
return request(request);
}
public static HttpResponse requestWithEventStream(ExecutorService executorService, long firstReadTimeout, HttpRequest request, Consumer<String> dataConsumer) throws ExecutionException, InterruptedException, TimeoutException {
return requestWithEventStream(executorService, firstReadTimeout, request, dataConsumer, null);
}
public static HttpResponse requestWithEventStream(ExecutorService executorService, long firstReadTimeout, HttpRequest request, Consumer<String> dataConsumer, Consumer<Future<?>> futureConsumer) throws ExecutionException, InterruptedException, TimeoutException {
// status: 0 start 1 run 2 timeout
AtomicInteger status = new AtomicInteger(0);
Future<HttpResponse> submit = executorService.submit(() -> {
if (request.getMaxSocketTimeout() == null) {
request.setMaxSocketTimeout(30_000);
}
request.setResponseHandler(entity -> {
StringBuilder sb = new StringBuilder();
try {
try (InputStream is = entity.getContent()) {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
if (status.get() == 2) {
throw new TimeoutException();
}
status.set(1);
sb.append(line).append("\n");
if (line.startsWith("data:")) {
dataConsumer.accept(line.substring(line.startsWith("data: ") ? 6 : 5));
}
}
}
}
} catch (Exception e) {
throw new RuntimeException("eventStream 请求异常", e);
}
return sb.toString();
});
return request(request);
});
if (futureConsumer != null) {
futureConsumer.accept(submit);
}
try {
HttpResponse httpResponse = submit.get(firstReadTimeout, TimeUnit.MILLISECONDS);
if (httpResponse != null) {
return httpResponse;
}
} catch (TimeoutException e) {
if (status.get() == 0) {
status.set(2);
submit.cancel(true);
throw e;
}
}
return submit.get();
}
public static HttpResponse requestWithEventStream(HttpRequest request, Consumer<String> dataConsumer) {
if (request.getMaxSocketTimeout() == null) {
request.setMaxSocketTimeout(30_000);
}
request.setResponseHandler(entity -> {
StringBuilder sb = new StringBuilder();
try {
try (InputStream is = entity.getContent()) {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line).append("\n");
if (line.startsWith("data:")) {
dataConsumer.accept(line.substring(line.startsWith("data: ") ? 6 : 5));
}
}
}
}
} catch (Exception e) {
throw new RuntimeException("eventStream 请求异常", e);
}
return sb.toString();
});
return request(request);
}
public static int getUrlHttpStatus(String _url) {
HttpURLConnection urlConnection = null;
try {
URL url = new URL(_url);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
return urlConnection.getResponseCode();
} catch (Exception ignored) {
return -1;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
public static String getUrlLinks(Map<String, Object> params) {
if (params == null || params.isEmpty()) {
return null;
}
StringBuilder sb = new StringBuilder();
try {
String[] sortedKeys = params.keySet().toArray(new String[0]);
Arrays.sort(sortedKeys);
for (String key : sortedKeys) {
if (key == null || key.isEmpty()) {
continue;
}
Object value = params.get(key);
sb.append(key).append("=");
if (value != null) {
sb.append(URLEncoder.encode(value.toString(), "UTF-8"));
}
sb.append("&");
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
return sb.toString();
}
@SuppressWarnings("unchecked")
public static Map<String, Object> parseUrlLinks(String params) {
Map<String, Object> result = new LinkedHashMap<>();
if (params == null || params.isEmpty()) {
return result;
}
for (String param : params.split("&")) {
String[] split = param.split("=");
String key = split[0];
String value = "";
if (split.length > 1) {
value = split[1];
}
if (result.containsKey(key)) {
Object o = result.get(key);
if (o instanceof List) {
((List<Object>) o).add(value);
} else {
List<Object> list = new ArrayList<>();
list.add(o);
list.add(value);
result.put(key, list);
}
} else {
result.put(key, value);
}
}
return result;
}
/**
*
*/
public static HttpResponse request(HttpRequest request) {
return request(request, 0);
}
private static HttpResponse request(HttpRequest request, int retryCount) {
HttpRequestBase requestBase = toRequest(request);
Map<String, String> headers = request.getHeaders();
ContentType contentType = null;
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
String key = entry.getKey();
if (key == null || key.isEmpty()) {
continue;
}
String value = entry.getValue();
if (CONTENT_TYPE.equalsIgnoreCase(key) && value != null) {
contentType = ContentType.parse(value);
}
requestBase.setHeader(key, value);
}
}
// body
setBodyEntity(requestBase, contentType, request.getBody());
try {
HttpClient client = getHttpClient(request, requestBase);
org.apache.http.HttpResponse response;
long startTime = System.currentTimeMillis();
response = client.execute(requestBase);
HttpResponse httpResponse = new HttpResponse();
httpResponse.setReqTime(System.currentTimeMillis() - startTime);
httpResponse.setStatus(response.getStatusLine().getStatusCode());
Header[] allHeaders = response.getAllHeaders();
if (allHeaders != null && allHeaders.length > 0) {
httpResponse.setHeaders(new HashMap<>());
for (Header header : allHeaders) {
httpResponse.getHeaders().put(header.getName(), header.getValue());
}
}
HttpEntity entity = response.getEntity();
if (request.responseHandler != null) {
httpResponse.setResponse(request.responseHandler.apply(entity));
} else {
String charset = null;
if (entity.getContentType() != null && entity.getContentType().getValue() != null) {
contentType = ContentType.parse(entity.getContentType().getValue());
if (contentType.getCharset() != null) {
charset = contentType.getCharset().name();
}
}
if (charset == null) {
charset = CHARSET_DEFAULT;
}
httpResponse.setResponse(IOUtils.toString(entity.getContent(), charset));
}
return httpResponse;
} catch (Exception e) {
requestBase.abort();
if (request.getMaxRetryCount() > retryCount) {
return request(request, retryCount + 1);
} else if (e instanceof SocketException && "Connection reset".equals(e.getMessage()) && retryCount == 0 && request.getMaxRetryCount() == 0) {
// 遇到 Connection reset 默认重试一次
return request(request, retryCount + 1);
} else {
throw new RuntimeException("请求异常", e);
}
} finally {
requestBase.releaseConnection();
}
}
private static void setBodyEntity(HttpRequestBase requestBase, ContentType contentType, Object body) {
if (body != null && requestBase instanceof HttpEntityEnclosingRequest) {
HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) requestBase;
if (body instanceof HttpEntity) {
entityRequest.setEntity((HttpEntity) body);
} else if (body instanceof String) {
entityRequest.setEntity(getStringEntity((String) body, contentType));
} else if (body instanceof byte[]) {
entityRequest.setEntity(new ByteArrayEntity((byte[]) body, contentType));
} else if (body instanceof File) {
entityRequest.setEntity(new FileEntity((File) body, contentType));
} else if (body instanceof InputStream) {
entityRequest.setEntity(new InputStreamEntity((InputStream) body, contentType));
} else if (ContentType.APPLICATION_JSON.equals(contentType)) {
entityRequest.setEntity(getStringEntity(JSON.toJSONString(body), contentType));
} else {
entityRequest.setEntity(getStringEntity(body.toString(), contentType));
}
}
}
private static StringEntity getStringEntity(String body, ContentType contentType) {
if (contentType != null && contentType.getCharset() != null) {
return new StringEntity(body, contentType);
} else {
return new StringEntity(body, CHARSET_DEFAULT);
}
}
public static HttpRequestBase toRequest(HttpRequest request) {
String url = request.getUrl();
String method = request.getMethod();
if (url == null || url.isEmpty()) {
throw new RuntimeException("url不能为空");
}
if (method == null || method.isEmpty()) {
method = "GET";
}
switch (method.toUpperCase()) {
case "GET":
return new HttpGet(url);
case "POST":
return new HttpPost(url);
case "PUT":
return new HttpPut(url);
case "PATCH":
return new HttpPatch(url);
case "DELETE":
return new HttpDelete(url);
default:
throw new RuntimeException("不支持的请求方式:" + method);
}
}
private static HttpClient getHttpClient(HttpRequest req, HttpRequestBase request) {
RequestConfig.Builder customReqConf = RequestConfig.custom();
if (req.getMaxSocketTimeout() != null) {
customReqConf.setSocketTimeout(req.getMaxSocketTimeout());
} else {
customReqConf.setSocketTimeout(MAX_SOCKET_TIMEOUT);
}
customReqConf.setConnectTimeout(MAX_CONNECT_TIMEOUT);
customReqConf.setConnectionRequestTimeout(MAX_CONNECT_TIMEOUT);
if (req.getRequestConfigConsumer() != null) {
req.getRequestConfigConsumer().accept(customReqConf);
}
request.setConfig(customReqConf.build());
return HttpClients.custom().setConnectionManager(CONNECTION_MANAGER).build();
}
private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
try {
// ssl: TLS / TLSv1.2 / TLSv1.3
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[]{new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
}
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}}, new SecureRandom());
return RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", new SSLConnectionSocketFactory(context))
.build();
} catch (Exception e) {
return RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build();
}
}
public static String toParamLinks(Map<String, Object> params, boolean encode) {
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
StringBuilder sb = new StringBuilder();
try {
for (String key : keys) {
if (key == null || "".equals(key)) {
continue;
}
Object value = params.get(key);
if (value == null || "".equals(value)) {
continue;
}
if (encode) {
sb.append(key).append("=").append(URLEncoder.encode(value.toString(), "UTF-8")).append("&");
} else {
sb.append(key).append("=").append(value).append("&");
}
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("编码失败", e);
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
return sb.toString();
}
public static class HttpRequest implements Serializable {
private String url;
private String method;
private Map<String, String> headers;
private Object body;
private int maxRetryCount = 0;
private Integer maxSocketTimeout;
private Consumer<RequestConfig.Builder> requestConfigConsumer;
private Function<HttpEntity, Object> responseHandler;
public static HttpRequest build(String url, String method) {
HttpRequest request = new HttpRequest();
request.url = url;
request.method = method;
return request;
}
public static HttpRequest get(String url) {
return build(url, "GET");
}
public static HttpRequest postJson(String url) {
return build(url, "POST").setContentType(CONTENT_TYPE_JSON);
}
public static HttpRequest postFormData(String url) {
return build(url, "POST").setContentType(CONTENT_TYPE_FORM_DATA);
}
public String getUrl() {
return url;
}
public HttpRequest setUrl(String url) {
this.url = url;
return this;
}
public String getMethod() {
return method;
}
public HttpRequest setMethod(String method) {
this.method = method;
return this;
}
public Map<String, String> getHeaders() {
return headers;
}
public HttpRequest setHeaders(Map<String, String> headers) {
this.headers = headers;
return this;
}
public HttpRequest setContentType(String contentType) {
if (this.headers == null) {
this.headers = new HashMap<>();
}
this.headers.put(CONTENT_TYPE, contentType);
return this;
}
public HttpRequest addHeaders(String key, Object value) {
if (headers == null) {
headers = new HashMap<>();
}
headers.put(key, value != null ? value.toString() : null);
return this;
}
public Object getBody() {
return body;
}
public HttpRequest setBody(Object body) {
this.body = body;
return this;
}
public void setMaxRetryCount(int maxRetryCount) {
this.maxRetryCount = maxRetryCount;
}
public int getMaxRetryCount() {
return maxRetryCount;
}
public HttpRequest setMaxSocketTimeout(Integer maxSocketTimeout) {
this.maxSocketTimeout = maxSocketTimeout;
return this;
}
public Integer getMaxSocketTimeout() {
return maxSocketTimeout;
}
public Consumer<RequestConfig.Builder> getRequestConfigConsumer() {
return requestConfigConsumer;
}
public void setRequestConfigConsumer(Consumer<RequestConfig.Builder> requestConfigConsumer) {
this.requestConfigConsumer = requestConfigConsumer;
}
public Function<HttpEntity, Object> getResponseHandler() {
return responseHandler;
}
public HttpRequest setResponseHandler(Function<HttpEntity, Object> responseHandler) {
this.responseHandler = responseHandler;
return this;
}
}
public static class HttpResponse implements Serializable {
private int status;
private long reqTime;
private Object response;
private Map<String, String> headers;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public long getReqTime() {
return reqTime;
}
public void setReqTime(long reqTime) {
this.reqTime = reqTime;
}
public Object getResponse() {
return response;
}
public String getResponseToString() {
if (response == null) {
return null;
}
return response instanceof String ? (String) response : String.valueOf(response);
}
public JSONObject getResponseToJson() {
return JSON.parseObject(getResponseToString());
}
public void setResponse(Object response) {
this.response = response;
}
public Map<String, String> getHeaders() {
return headers;
}
public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}
}
}

@ -72,3 +72,7 @@ KeLing:
# GPTNB GOAPI
GPTNB:
sk: sk-amQHwiEzPIZIB2KuF5A10dC23a0e4b02B48a7a2b6aFa0662
# 人工智能生成PPT
AIPPT:
BASE_URL: https://goapi.gptnb.ai/docmee/v1

@ -72,3 +72,7 @@ KeLing:
# GPTNB GOAPI
GPTNB:
sk: sk-amQHwiEzPIZIB2KuF5A10dC23a0e4b02B48a7a2b6aFa0662
# 人工智能生成PPT
AIPPT:
BASE_URL: https://docmee.cn

@ -72,3 +72,7 @@ KeLing:
# GPTNB GOAPI
GPTNB:
sk: sk-amQHwiEzPIZIB2KuF5A10dC23a0e4b02B48a7a2b6aFa0662
# 人工智能生成PPT
AIPPT:
BASE_URL: https://goapi.gptnb.ai/docmee/v1

@ -72,3 +72,7 @@ KeLing:
# GPTNB GOAPI
GPTNB:
sk: sk-amQHwiEzPIZIB2KuF5A10dC23a0e4b02B48a7a2b6aFa0662
# 人工智能生成PPT
AIPPT:
BASE_URL: https://docmee.cn
Loading…
Cancel
Save