Browse Source

北森调用

yuanzhi_kuang 1 month ago
parent
commit
56e525fd53
1 changed files with 113 additions and 94 deletions
  1. 113 94
      src/com/kingdee/eas/custom/beisen/utils/BeisenApiClient.java

+ 113 - 94
src/com/kingdee/eas/custom/beisen/utils/BeisenApiClient.java

@@ -1,6 +1,7 @@
 package com.kingdee.eas.custom.beisen.utils;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import okhttp3.*;
 import org.apache.log4j.Logger;
@@ -14,6 +15,7 @@ import java.util.concurrent.TimeUnit;
 public class BeisenApiClient {
     private static final Logger logger = Logger.getLogger(BeisenApiClient.class);
     private static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8");
+    private static final int MAX_RETRIES = 3;
 
     // 单例实例
     private static volatile BeisenApiClient instance;
@@ -41,131 +43,148 @@ public class BeisenApiClient {
         return instance;
     }
 
+  
+    
     /**
-     * 调用北森API (POST)
-     * @param apiUrl API地址
-     * @param requestData 请求数据(JSON格式)
-     * @return API响应内容
-     * @throws IOException 当API调用失败时抛出
+     * api调用qun
+     * @param apiUrl
+     * @param requestData
+     * @return
+     * @throws IOException
      */
     public JSONObject callApi(String apiUrl, JSONObject requestData) throws IOException {
-        return callApi(apiUrl, requestData, true);
+        return callApiInternal(apiUrl, requestData, true, "POST");
     }
-
-    /**
-     * 调用北森API (POST,支持重试)
-     * @param apiUrl API地址
-     * @param requestData 请求数据(JSON格式)
-     * @param retryOnTokenExpired 是否在token过期时自动重试
-     * @return API响应内容
-     * @throws IOException 当API调用失败时抛出
-     */
-    public JSONObject callApi(String apiUrl, JSONObject requestData, boolean retryOnTokenExpired) throws IOException {
-        return callApi(apiUrl, requestData, retryOnTokenExpired, "POST");
+    
+    public JSONObject callApi(String apiUrl, JSONArray dataArray) throws IOException {
+        return callApiInternal(apiUrl, dataArray, true, "POST");
     }
-
-    /**
-     * 调用北森API (PUT)
-     * @param apiUrl API地址
-     * @param requestData 请求数据(JSON格式)
-     * @return API响应内容
-     * @throws IOException 当API调用失败时抛出
-     */
+    
     public JSONObject callPutApi(String apiUrl, JSONObject requestData) throws IOException {
-        return callApi(apiUrl, requestData, true, "PUT");
+        return callApiInternal(apiUrl, requestData, true, "PUT");
     }
 
+    // 核心API调用逻辑----------------------------------------------------------
+    
     /**
      * 通用API调用方法
-     * @param apiUrl API地址
-     * @param requestData 请求数据
-     * @param retryOnTokenExpired 是否重试token过期
-     * @param method HTTP方法 (POST/PUT)
-     * @return API响应
-     * @throws IOException
+     * @param requestBody 支持JSONObject/JSONArray
      */
-    private JSONObject callApi(String apiUrl, JSONObject requestData, boolean retryOnTokenExpired, String method) 
+    private JSONObject callApiInternal(String apiUrl, Object requestBody, boolean retryOnTokenExpired, String method) 
         throws IOException {
         int retryCount = 0;
-        final int maxRetries = 3;
-
-        while (retryCount <= maxRetries) {
+        JSONObject handleResponse = new  JSONObject();
+        while (retryCount <= MAX_RETRIES) {
             try {
                 String accessToken = tokenManager.getAccessToken();
-                Request request = buildRequest(apiUrl, requestData, accessToken, method);
+                Request request = buildRequest(apiUrl, requestBody, accessToken, method);
 
                 try (Response response = httpClient.newCall(request).execute()) {
-                    if (!response.isSuccessful()) {
-                        String errorBody = response.body() != null ? response.body().string() : "null";
-                        logger.error("API request failed. Code: " + response.code() + 
-                                     ", URL: " + apiUrl + ", Method: " + method + 
-                                     ", Body: " + errorBody);
-                        throw new IOException("API request failed with code: " + response.code());
-                    }
-
-                    String responseBody = response.body().string();
-                    JSONObject jsonResponse = JSON.parseObject(responseBody);
-
-                    // 检查API返回的业务状态码
-                    int apiCode = jsonResponse.getIntValue("code");
-                    if (apiCode != 200) {
-                        String apiMessage = jsonResponse.getString("message");
-                        logger.error("API business error. Code: " + apiCode + 
-                                     ", Message: " + apiMessage + ", URL: " + apiUrl);
-//                        throw new IOException("API business error: " + apiMessage + 
-//                                              " (code: " + apiCode + ")");
-                    }
-                    return jsonResponse;
+                    handleResponse = handleResponse(response, apiUrl, method);
+                    return  handleResponse;
                 }
             } catch (IOException e) {
-                // 如果是token过期错误且允许重试,则尝试刷新token后重试
-                if (retryOnTokenExpired && isTokenExpiredError(e) && retryCount < maxRetries) {
+                if (shouldRetry(retryOnTokenExpired, retryCount, e)) {
                     retryCount++;
-                    logger.warn("Token may have expired, refreshing and retrying... (" + 
-                               retryCount + "/" + maxRetries + ")");
-                    try {
-                        tokenManager.refreshToken();
-                    } catch (IOException ex) {
-                        logger.error("Failed to refresh token during retry", ex);
-                    }
+                    handleTokenRefresh(retryCount);
                     continue;
                 }
-                throw e;
             }
         }
-        throw new IOException("API request failed after " + maxRetries + " attempts");
+        return  handleResponse;
+        //不抛出,使用调用的地方存储msg
+//        throw new IOException("API request failed after " + MAX_RETRIES + " attempts");
     }
 
-    /**
-     * 构建请求对象
-     * @param apiUrl API地址
-     * @param requestData 请求数据
-     * @param accessToken 访问令牌
-     * @param method HTTP方法
-     * @return Request对象
-     */
-    private Request buildRequest(String apiUrl, JSONObject requestData, String accessToken, String method) {
-        RequestBody body = RequestBody.create(JSON_MEDIA_TYPE, requestData.toJSONString());
-        Request.Builder requestBuilder = new Request.Builder()
-                .url(apiUrl)
-                .addHeader("Authorization", "Bearer " + accessToken)
-                .addHeader("Content-Type", "application/json");
-
-        // 根据方法设置请求类型
-        if ("PUT".equalsIgnoreCase(method)) {
-            requestBuilder.put(body);
-        } else {
-            requestBuilder.post(body); // 默认为POST
+    // 响应处理逻辑-------------------------------------------------------------
+    
+    private JSONObject handleResponse(Response response, String apiUrl, String method) throws IOException {
+        if (!response.isSuccessful()) {
+            handleHttpError(response, apiUrl, method);
+        }
+
+        String responseBody = response.body().string();
+        JSONObject jsonResponse = parseResponse(responseBody, apiUrl);
+
+        validateBusinessStatus(jsonResponse, apiUrl);
+        return jsonResponse;
+    }
+
+    private void handleHttpError(Response response, String apiUrl, String method) throws IOException {
+        String errorBody = response.body() != null ? response.body().string() : "null";
+        logger.error("API request failed. Code: " + response.code() + 
+                     ", URL: " + apiUrl + ", Method: " + method + 
+                     ", Body: " + errorBody);
+//        throw new IOException("HTTP error: " + response.code());
+    }
+
+    private JSONObject parseResponse(String responseBody, String apiUrl) throws IOException {
+        try {
+            return JSON.parseObject(responseBody);
+        } catch (Exception e) {
+            logger.error("Invalid JSON response from API. URL: " + apiUrl + ", Response: " + responseBody);
+            throw new IOException("Failed to parse API response", e);
+        }
+    }
+
+    private void validateBusinessStatus(JSONObject jsonResponse, String apiUrl) throws IOException {
+        int apiCode = jsonResponse.getIntValue("code");
+        if (apiCode != 200) {
+            String apiMessage = jsonResponse.getString("message");
+            logger.error("API business error. Code: " + apiCode + 
+                         ", Message: " + apiMessage + ", URL: " + apiUrl);
+//            throw new IOException("Business error: " + apiMessage + " (code: " + apiCode + ")");
         }
+    }
 
-        return requestBuilder.build();
+    // Token重试逻辑-----------------------------------------------------------
+    
+    private boolean shouldRetry(boolean retryOnTokenExpired, int retryCount, Exception e) {
+        return retryOnTokenExpired && 
+               isTokenExpiredError(e) && 
+               retryCount < MAX_RETRIES;
+    }
+
+    private void handleTokenRefresh(int retryCount) {
+        logger.warn("Token may have expired, refreshing and retrying... (" + 
+                   retryCount + "/" + MAX_RETRIES + ")");
+        try {
+            tokenManager.refreshToken();
+        } catch (IOException ex) {
+            logger.error("Failed to refresh token during retry", ex);
+        }
+    }
+
+    // 请求构建----------------------------------------------------------------
+    
+    private Request buildRequest(String apiUrl, Object requestBody, String accessToken, String method) {
+        String jsonString = convertToJsonString(requestBody);
+        RequestBody body = RequestBody.create(JSON_MEDIA_TYPE, jsonString);
+        
+        return new Request.Builder()
+            .url(apiUrl)
+            .addHeader("Authorization", "Bearer " + accessToken)
+            .addHeader("Content-Type", "application/json")
+            .method(method, body)
+            .build();
+    }
+
+    private String convertToJsonString(Object data) {
+        if (data instanceof JSONObject) {
+            return ((JSONObject) data).toJSONString();
+        } else if (data instanceof JSONArray) {
+            return ((JSONArray) data).toJSONString();
+        }
+        throw new IllegalArgumentException("Unsupported request data type: " + data.getClass());
     }
 
+    // 辅助方法---------------------------------------------------------------
+    
     private boolean isTokenExpiredError(Exception e) {
-        return e.getMessage() != null &&
-                (e.getMessage().contains("401") ||
-                 e.getMessage().contains("Unauthorized") ||
-                 e.getMessage().contains("token"));
+        String msg = e.getMessage();
+        return msg != null && (msg.contains("401") || 
+                              msg.contains("Unauthorized") || 
+                              msg.contains("token"));
     }
 
     private OkHttpClient buildHttpClient() {