ApiClientUtils.java 11.6 KB
package com.xiniunet.service.railway.util;

import com.alibaba.fastjson.JSON;
import com.taobao.api.Constants;
import com.taobao.api.internal.util.StringUtils;
import com.xiniunet.basic.enumeration.SmsTemplateProviderEnum;
import com.xiniunet.open.api.client.DefaultClient;
import com.xiniunet.open.api.client.XClient;
import com.xiniunet.open.api.client.XRequest;
import com.xiniunet.open.api.client.XResponse;
import com.xiniunet.service.railway.util.thread.SmsSendRequest;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.*;

import static com.xiniunet.service.railway.Constant.RAILWAY_TENANT_ID;

/**
 * @author
 */
public class ApiClientUtils {

    public static void main(String[] args) throws Exception {
        String description = "李先生在上海站拾取500根金条,拾金不昧上交给了国家!真是了不起!";

        Map<String, String> params = new HashMap<>(8);
        params.put("line_carriage", "2号线3号车厢");
        params.put("event_time", "2023-06-21 22:22:22");
        params.put("event_number", "202306210001");
        params.put("event_titile", "友好现象");
        params.put("event_description", description == null ? "" : description.length() > 10 ? description.substring(0, 10) + "... " : description);
        params.put("timeout_minutes", "20");
        // params.put("station_name", "上海站");


        SmsSendRequest smsSendRequest = new SmsSendRequest();
        smsSendRequest.setTenantId(RAILWAY_TENANT_ID);
        smsSendRequest.setFunction("shmetro.carriage.event.hotline.deal");
        smsSendRequest.setParam(JSON.toJSONString(params));
        smsSendRequest.setMobile("15651238393");
        smsSendRequest.setProvider(SmsTemplateProviderEnum.ALIYUN.name());
        smsSendRequest.setBusinessId(111_222_333_444L);
        smsSendRequest.setBusinessType("hotline");
        smsSendRequest.setSign("平安地铁");

        XResponse response = execute(smsSendRequest);
        System.out.println("response = " + JSON.toJSONString(response));

    }

    private static final String API_URI = "https://metro-api.xiniunet.com/router2";

    private static final XClient API_CLIENT;

    static {
        API_CLIENT = new DefaultClient(API_URI, "0617CA8376F9901F28FF46B69BF9CF55", "28570C9D069ED51226DD9F028BD5E6EE");
    }

    public static XResponse execute(XRequest<?> request) throws Exception {
        return API_CLIENT.execute(request);
    }

    private static class ApiClient {

        public String execute(Map<String, String> request, String openMethod) throws Exception {
            Map<String, String> requestParameters = new HashMap<>(request);

            Map<String, String> params = new HashMap<>();
            String ctype = "application/x-www-form-urlencoded;charset=" + StandardCharsets.UTF_8;
            String query = buildQuery(params);
            byte[] content = {};
            if (query != null) {
                content = query.getBytes(StandardCharsets.UTF_8);
            }

            Map<String, String> protocolMustParams = new HashMap<>();
            protocolMustParams.put(METHOD, openMethod);
            protocolMustParams.put(VERSION, "1.0");
            protocolMustParams.put(APP_KEY, appKey);
            // protocolMustParams.put(TIMESTAMP, System.currentTimeMillis() + "");
            protocolMustParams.put(TIMESTAMP, "1687356831444");
            requestParameters.putAll(protocolMustParams);

            // protocolOptParams
            requestParameters.put(FORMAT, format);
            requestParameters.put(SIGN_METHOD, signMethod);

            protocolMustParams.put(SIGN, signTopRequestNew(requestParameters, appSecret));

            StringBuilder reqUrl = new StringBuilder(serverUrl);
            try {
                String sysMustQuery = buildQuery(protocolMustParams);
                String sysOptQuery = buildQuery(protocolMustParams);

                if (reqUrl.indexOf("?") != -1) {
                    reqUrl.append("&");
                } else {
                    reqUrl.append("?");
                }
                reqUrl.append(sysMustQuery);
                if (sysOptQuery != null && sysOptQuery.length() > 0) {
                    reqUrl.append("&").append(sysOptQuery);
                }
            } catch (IOException e) {
                throw new RuntimeException(e.getMessage(), e);
            }

            HttpURLConnection conn = null;
            try {
                conn = getConnection(new URL(reqUrl.toString()), ctype, connectTimeout, readTimeout);
                try (OutputStream out = conn.getOutputStream()) {
                    out.write(content);
                    return getResponseAsString(conn);
                }
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }


        // region

        private static final String APP_KEY = "app_key";
        private static final String FORMAT = "format";
        private static final String METHOD = "method";
        private static final String TIMESTAMP = "timestamp";
        private static final String VERSION = "v";
        private static final String SIGN = "sign";
        private static final String SIGN_METHOD = "sign_method";
        private static final String PASSPORT_ID = "passportId";
        private final String serverUrl;
        private final String appKey;
        private final String appSecret;
        private final String format;
        private final String signMethod;
        private final int connectTimeout;
        private final int readTimeout;

        public ApiClient(String serverUrl, String appKey, String appSecret) {
            this.format = "json";
            this.signMethod = "md5";
            this.connectTimeout = 3000;
            this.readTimeout = 60000;
            this.appKey = appKey;
            this.appSecret = appSecret;
            this.serverUrl = serverUrl;
        }

        // endregion

        private static String buildQuery(Map<String, String> params) throws IOException {
            if (params == null || params.isEmpty()) {
                return null;
            }
            StringBuilder query = new StringBuilder();
            Set<Map.Entry<String, String>> entries = params.entrySet();
            boolean hasParam = false;

            for (Map.Entry<String, String> entry : entries) {
                String name = entry.getKey();
                String value = entry.getValue();
                // 忽略参数名或参数值为空的参数
                if (StringUtils.areNotEmpty(name, value)) {
                    if (hasParam) {
                        query.append("&");
                    } else {
                        hasParam = true;
                    }
                    query.append(name).append("=").append(URLEncoder.encode(value, Constants.CHARSET_UTF8));
                }
            }
            return query.toString();
        }

        private static HttpURLConnection getConnection(URL url, String ctype, int connectTimeout, int readTimeout) throws IOException {
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setRequestProperty("Accept", "text/xml,text/javascript");
            conn.setRequestProperty("User-Agent", "xiniunet-sdk-java");
            conn.setRequestProperty("Content-Type", ctype);
            conn.setConnectTimeout(connectTimeout);
            conn.setReadTimeout(readTimeout);
            return conn;
        }

        protected static String getResponseAsString(HttpURLConnection conn) throws IOException {
            String charset = getResponseCharset(conn.getContentType());
            InputStream es = conn.getErrorStream();
            if (es == null) {
                return getStreamAsString(conn.getInputStream(), charset);
            } else {
                String msg = getStreamAsString(es, charset);
                if (StringUtils.isEmpty(msg)) {
                    throw new IOException(conn.getResponseCode() + ":" + conn.getResponseMessage());
                } else {
                    throw new IOException(msg);
                }
            }
        }

        private static String getResponseCharset(String ctype) {
            String charset = Constants.CHARSET_UTF8;

            if (!StringUtils.isEmpty(ctype)) {
                String[] params = ctype.split(";");
                for (String param : params) {
                    param = param.trim();
                    if (param.startsWith("charset")) {
                        String[] pair = param.split("=", 2);
                        if (pair.length == 2) {
                            if (!StringUtils.isEmpty(pair[1])) {
                                charset = pair[1].trim();
                            }
                        }
                        break;
                    }
                }
            }

            return charset;
        }

        private static String getStreamAsString(InputStream stream, String charset) throws IOException {
            try {
                Reader reader = new InputStreamReader(stream, charset);
                StringBuilder response = new StringBuilder();

                final char[] buff = new char[1024];
                int read = 0;
                while ((read = reader.read(buff)) > 0)
                {
                    response.append(buff, 0, read);
                }

                return response.toString();
            } finally {
                if (stream != null) {
                    stream.close();
                }
            }
        }

        private static String signTopRequestNew(Map<String, String> paramValues, String secret) throws IOException {

            StringBuilder sb = new StringBuilder();
            List<String> paramNames = new ArrayList<String>(paramValues.size());
            paramNames.addAll(paramValues.keySet());
            Collections.sort(paramNames);
            sb.append(secret);
            for (String paramName : paramNames) {
                sb.append(paramName).append(paramValues.get(paramName));
            }
            sb.append(secret);
            byte[] digests = encryptMd5(sb.toString());
            return byte2hex(digests);

        }

        private static byte[] encryptMd5(String data) throws IOException {
            byte[] bytes;
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                bytes = md.digest(data.getBytes(StandardCharsets.UTF_8));
            } catch (GeneralSecurityException gse) {
                String msg = getStringFromException(gse);
                throw new IOException(msg);
            }
            return bytes;
        }

        private static String getStringFromException(Throwable e) {
            String result = "";
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PrintStream ps = new PrintStream(bos);
            e.printStackTrace(ps);
            try {
                result = bos.toString(Constants.CHARSET_UTF8);
            } catch (IOException ignore) {}
            return result;
        }

        private static String byte2hex(byte[] bytes) {
            StringBuilder sign = new StringBuilder();
            for(byte aByte : bytes) {
                String hex = Integer.toHexString(aByte & 0xFF);
                if(hex.length() == 1) {
                    sign.append("0");
                }
                sign.append(hex.toUpperCase());
            }
            return sign.toString();
        }

    }

}