1
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package com.ruoyi.jarvis.util;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 调用金山文档开放平台 HTTP 接口(含 OAuth 换票与 Open API)
|
||||
*/
|
||||
public final class KdocsOpenApiClient {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(KdocsOpenApiClient.class);
|
||||
|
||||
static {
|
||||
System.setProperty("java.net.useSystemProxies", "false");
|
||||
}
|
||||
|
||||
private KdocsOpenApiClient() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求 JSON 接口,返回根对象(含 code、data)
|
||||
*
|
||||
* @param jsonContentTypeForGet 部分 GET(如 oauth2/access_token)要求 Content-Type: application/json
|
||||
*/
|
||||
public static JSONObject exchange(String method, String fullUrl, String jsonBody, boolean jsonContentTypeForGet) {
|
||||
try {
|
||||
URL u = new URL(fullUrl);
|
||||
HttpURLConnection conn = (HttpURLConnection) u.openConnection(java.net.Proxy.NO_PROXY);
|
||||
conn.setRequestMethod(method);
|
||||
conn.setConnectTimeout(15000);
|
||||
conn.setReadTimeout(60000);
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
if ("GET".equals(method) && jsonContentTypeForGet) {
|
||||
conn.setRequestProperty("Content-Type", "application/json");
|
||||
}
|
||||
if ("POST".equals(method) || "PUT".equals(method)) {
|
||||
conn.setRequestProperty("Content-Type", "application/json");
|
||||
conn.setDoOutput(true);
|
||||
if (jsonBody != null && !jsonBody.isEmpty()) {
|
||||
try (OutputStreamWriter w = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8)) {
|
||||
w.write(jsonBody);
|
||||
w.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int status = conn.getResponseCode();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
InputStream stream = status >= 200 && status < 300 ? conn.getInputStream() : conn.getErrorStream();
|
||||
if (stream != null) {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
String text = sb.toString();
|
||||
log.debug("Kdocs HTTP {} {} -> {} body: {}", method, fullUrl, status, text.length() > 500 ? text.substring(0, 500) + "..." : text);
|
||||
if (status < 200 || status >= 300) {
|
||||
throw new RuntimeException("HTTP " + status + ": " + text);
|
||||
}
|
||||
if (StringUtils.isBlank(text)) {
|
||||
return new JSONObject();
|
||||
}
|
||||
return JSON.parseObject(text);
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Kdocs 请求失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务 Open API:code 必须为 0,返回 data
|
||||
*/
|
||||
public static JSONObject requireBusinessData(JSONObject root) {
|
||||
if (root == null) {
|
||||
throw new RuntimeException("Kdocs 响应为空");
|
||||
}
|
||||
Integer c = root.getInteger("code");
|
||||
if (c == null || c != 0) {
|
||||
throw new RuntimeException("Kdocs 业务错误: " + root.toJSONString());
|
||||
}
|
||||
JSONObject data = root.getJSONObject("data");
|
||||
return data != null ? data : new JSONObject();
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
package com.ruoyi.jarvis.util;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* WPS365 API工具类
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
public class WPS365ApiUtil {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WPS365ApiUtil.class);
|
||||
|
||||
// 静态初始化块:禁用系统代理
|
||||
static {
|
||||
System.setProperty("java.net.useSystemProxies", "false");
|
||||
System.clearProperty("http.proxyHost");
|
||||
System.clearProperty("http.proxyPort");
|
||||
System.clearProperty("https.proxyHost");
|
||||
System.clearProperty("https.proxyPort");
|
||||
log.info("已禁用系统代理设置,WPS365 API将直接连接");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取访问令牌
|
||||
*
|
||||
* @param appId 应用ID
|
||||
* @param appKey 应用密钥
|
||||
* @param code 授权码
|
||||
* @param redirectUri 回调地址
|
||||
* @param tokenUrl Token地址
|
||||
* @return 包含access_token和refresh_token的JSON对象
|
||||
*/
|
||||
public static JSONObject getAccessToken(String appId, String appKey, String code, String redirectUri, String tokenUrl) {
|
||||
try {
|
||||
// 构建请求参数
|
||||
StringBuilder params = new StringBuilder();
|
||||
params.append("grant_type=authorization_code");
|
||||
params.append("&client_id=").append(appId);
|
||||
params.append("&client_secret=").append(appKey);
|
||||
params.append("&code=").append(code);
|
||||
params.append("&redirect_uri=").append(java.net.URLEncoder.encode(redirectUri, "UTF-8"));
|
||||
|
||||
// 使用HttpURLConnection,不使用代理
|
||||
URL url = new URL(tokenUrl);
|
||||
java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
conn.setConnectTimeout(10000);
|
||||
conn.setReadTimeout(30000);
|
||||
|
||||
// 写入请求参数
|
||||
try (OutputStream os = conn.getOutputStream();
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
|
||||
osw.write(params.toString());
|
||||
osw.flush();
|
||||
}
|
||||
|
||||
// 读取响应
|
||||
int statusCode = conn.getResponseCode();
|
||||
BufferedReader reader;
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
||||
} else {
|
||||
reader = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
StringBuilder response = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
|
||||
String responseStr = response.toString();
|
||||
log.info("获取访问令牌响应: statusCode={}, response={}", statusCode, responseStr);
|
||||
|
||||
if (statusCode < 200 || statusCode >= 300) {
|
||||
throw new RuntimeException("获取访问令牌失败: HTTP " + statusCode + ", response=" + responseStr);
|
||||
}
|
||||
|
||||
return JSON.parseObject(responseStr);
|
||||
} catch (Exception e) {
|
||||
log.error("获取访问令牌失败", e);
|
||||
throw new RuntimeException("获取访问令牌失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新访问令牌
|
||||
*
|
||||
* @param appId 应用ID
|
||||
* @param appKey 应用密钥
|
||||
* @param refreshToken 刷新令牌
|
||||
* @param refreshTokenUrl 刷新令牌地址
|
||||
* @return 包含新的access_token和refresh_token的JSON对象
|
||||
*/
|
||||
public static JSONObject refreshAccessToken(String appId, String appKey, String refreshToken, String refreshTokenUrl) {
|
||||
try {
|
||||
// 构建请求参数
|
||||
StringBuilder params = new StringBuilder();
|
||||
params.append("grant_type=refresh_token");
|
||||
params.append("&client_id=").append(appId);
|
||||
params.append("&client_secret=").append(appKey);
|
||||
params.append("&refresh_token=").append(refreshToken);
|
||||
|
||||
// 使用HttpURLConnection,不使用代理
|
||||
URL url = new URL(refreshTokenUrl);
|
||||
java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
conn.setConnectTimeout(10000);
|
||||
conn.setReadTimeout(30000);
|
||||
|
||||
// 写入请求参数
|
||||
try (OutputStream os = conn.getOutputStream();
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
|
||||
osw.write(params.toString());
|
||||
osw.flush();
|
||||
}
|
||||
|
||||
// 读取响应
|
||||
int statusCode = conn.getResponseCode();
|
||||
StringBuilder response = new StringBuilder();
|
||||
|
||||
try {
|
||||
BufferedReader reader;
|
||||
InputStream inputStream;
|
||||
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
inputStream = conn.getInputStream();
|
||||
} else {
|
||||
// 对于错误响应,尝试读取错误流
|
||||
inputStream = conn.getErrorStream();
|
||||
// 如果错误流为null,尝试读取正常流(某些服务器可能将错误信息放在正常流中)
|
||||
if (inputStream == null) {
|
||||
inputStream = conn.getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
// 如果输入流仍然为null,说明无法读取响应
|
||||
if (inputStream == null) {
|
||||
log.warn("无法读取HTTP响应流,状态码: {}", statusCode);
|
||||
response.append("无法读取响应内容");
|
||||
} else {
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("读取HTTP响应失败", e);
|
||||
response.append("读取响应失败: ").append(e.getMessage());
|
||||
}
|
||||
|
||||
String responseStr = response.toString();
|
||||
log.info("刷新访问令牌响应: statusCode={}, response={}", statusCode, responseStr);
|
||||
|
||||
if (statusCode < 200 || statusCode >= 300) {
|
||||
throw new RuntimeException("刷新访问令牌失败: HTTP " + statusCode + ", response=" + responseStr);
|
||||
}
|
||||
|
||||
return JSON.parseObject(responseStr);
|
||||
} catch (Exception e) {
|
||||
log.error("刷新访问令牌失败", e);
|
||||
throw new RuntimeException("刷新访问令牌失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送HTTP请求
|
||||
*
|
||||
* @param method 请求方法(GET/POST/PUT/DELETE)
|
||||
* @param url 请求URL
|
||||
* @param accessToken 访问令牌
|
||||
* @param body 请求体(JSON字符串,GET请求可为null)
|
||||
* @return 响应JSON对象
|
||||
*/
|
||||
public static JSONObject httpRequest(String method, String url, String accessToken, String body) {
|
||||
try {
|
||||
log.debug("发送HTTP请求: method={}, url={}", method, url);
|
||||
|
||||
URL requestUrl = new URL(url);
|
||||
java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
|
||||
HttpURLConnection conn = (HttpURLConnection) requestUrl.openConnection(proxy);
|
||||
conn.setRequestMethod(method);
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
|
||||
conn.setConnectTimeout(10000);
|
||||
conn.setReadTimeout(30000);
|
||||
|
||||
if ("POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method)) {
|
||||
conn.setRequestProperty("Content-Type", "application/json");
|
||||
conn.setDoOutput(true);
|
||||
|
||||
if (body != null && !body.isEmpty()) {
|
||||
try (OutputStream os = conn.getOutputStream();
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
|
||||
osw.write(body);
|
||||
osw.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 读取响应
|
||||
int statusCode = conn.getResponseCode();
|
||||
StringBuilder response = new StringBuilder();
|
||||
|
||||
try {
|
||||
BufferedReader reader;
|
||||
InputStream inputStream;
|
||||
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
inputStream = conn.getInputStream();
|
||||
} else {
|
||||
// 对于错误响应,尝试读取错误流
|
||||
inputStream = conn.getErrorStream();
|
||||
// 如果错误流为null,尝试读取正常流(某些服务器可能将错误信息放在正常流中)
|
||||
if (inputStream == null) {
|
||||
inputStream = conn.getInputStream();
|
||||
}
|
||||
}
|
||||
|
||||
// 如果输入流仍然为null,说明无法读取响应
|
||||
if (inputStream == null) {
|
||||
log.warn("无法读取HTTP响应流,状态码: {}", statusCode);
|
||||
response.append("无法读取响应内容");
|
||||
} else {
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("读取HTTP响应失败", e);
|
||||
response.append("读取响应失败: ").append(e.getMessage());
|
||||
}
|
||||
|
||||
String responseStr = response.toString();
|
||||
log.info("HTTP响应: statusCode={}, url={}, response={}", statusCode, url, responseStr);
|
||||
|
||||
if (statusCode < 200 || statusCode >= 300) {
|
||||
String errorMsg = String.format("HTTP请求失败: statusCode=%d, url=%s, response=%s",
|
||||
statusCode, url, responseStr);
|
||||
log.error(errorMsg);
|
||||
throw new RuntimeException(errorMsg);
|
||||
}
|
||||
|
||||
if (responseStr == null || responseStr.trim().isEmpty()) {
|
||||
return new JSONObject();
|
||||
}
|
||||
|
||||
return JSON.parseObject(responseStr);
|
||||
} catch (Exception e) {
|
||||
log.error("HTTP请求失败: method={}, url={}", method, url, e);
|
||||
throw new RuntimeException("HTTP请求失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user