liusheng
5 天以前 cc479e6a056785103996cc7ea67dbd5faa3e800e
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
@@ -72,6 +72,8 @@
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(10000);
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
            String line;
@@ -106,10 +108,11 @@
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
    public static Boolean sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        boolean success = false;
        try {
            log.info("sendPost - {}", url);
            URL realUrl = new URL(url);
@@ -120,6 +123,8 @@
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Charsert", "UTF-8");
            conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(10000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8));
@@ -131,6 +136,7 @@
                result.append(line);
            }
            log.info("recv - {}", result);
            success = true;
        } catch (ConnectException e) {
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        } catch (SocketTimeoutException e) {
@@ -151,7 +157,7 @@
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
        return success;
    }
    public static String sendPostByHeaderOld(String url, String param, Map<String, String> headers) {
@@ -167,6 +173,8 @@
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(10000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            if (!Objects.isNull(headers)) {
@@ -207,6 +215,23 @@
    }
    public static String sendPostByHeader(String url, String param, Map<String, String> headers) {
        // 不设超时:与历史行为一致(老调用方一个字节都不变)
        return sendPostByHeader(url, param, headers, 0, 0);
    }
    /**
     * 带超时的 POST(JSON 报文头 + 自定义 header)。
     * <p>
     * ⚠️ <b>为什么会有这个重载</b>:上面的老方法<b>没有连接/读超时</b>,
     * 一旦对端不响应,调用线程会无限期挂住。批量按患者调用的采集
     * (如"在院信息刷新",一轮几千次)承受不起这个风险,所以补一个显式超时的重载;
     * 老方法改为委托本方法并传 0(0 = 不设超时),行为与改造前完全一致。
     *
     * @param connectTimeoutMs 连接超时(毫秒);{@code <=0} 表示不设
     * @param readTimeoutMs    读超时(毫秒);{@code <=0} 表示不设
     */
    public static String sendPostByHeader(String url, String param, Map<String, String> headers,
                                          int connectTimeoutMs, int readTimeoutMs) {
        StringBuilder result = new StringBuilder();
        HttpURLConnection conn = null;
        try {
@@ -220,6 +245,12 @@
            conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            if (connectTimeoutMs > 0) {
                conn.setConnectTimeout(connectTimeoutMs);
            }
            if (readTimeoutMs > 0) {
                conn.setReadTimeout(readTimeoutMs);
            }
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
@@ -332,4 +363,49 @@
        return "调用失败";
    }
    /**
     * 对URL参数进行编码,处理中文乱码问题
     *
     * @param params 参数字符串,格式:name1=value1&name2=value2
     * @param charset 编码格式
     * @return 编码后的参数字符串
     */
    private static String encodeParams(String params, String charset) {
        if (StringUtils.isBlank(params)) {
            return params;
        }
        try {
            StringBuilder encodedParams = new StringBuilder();
            String[] pairs = params.split("&");
            for (int i = 0; i < pairs.length; i++) {
                String pair = pairs[i];
                if (StringUtils.isNotBlank(pair)) {
                    int idx = pair.indexOf("=");
                    if (idx > 0) {
                        String key = pair.substring(0, idx);
                        String value = pair.substring(idx + 1);
                        // 对key和value都进行URL编码
                        encodedParams.append(URLEncoder.encode(key, charset))
                                .append("=")
                                .append(URLEncoder.encode(value, charset));
                    } else {
                        // 没有等号,整个作为key
                        encodedParams.append(URLEncoder.encode(pair, charset));
                    }
                    if (i < pairs.length - 1) {
                        encodedParams.append("&");
                    }
                }
            }
            return encodedParams.toString();
        } catch (UnsupportedEncodingException e) {
            log.error("URL参数编码失败", e);
            return params;
        }
    }
}