285 lines
12 KiB
Java
285 lines
12 KiB
Java
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);
|
||
}
|
||
}
|
||
}
|
||
|