Files
ruoyi-java/ruoyi-system/src/main/java/com/ruoyi/jarvis/util/WPS365ApiUtil.java
2026-01-15 21:49:38 +08:00

285 lines
12 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}