springboot对接上上签(二)

325 阅读4分钟

常用工具类

工具类

HttpClientSender

public class HttpClientSender {

    private static PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = null;
    private static Map<String, CloseableHttpClient> httpClients = new HashMap<String, CloseableHttpClient>();

    private static Object o = new Object();

    public static String sendHttpPost(String host, String method, String urlParams, String sendData) throws IOException {

        String requestUrl = host + method + urlParams;

        Map<String, Object> response = request("POST", requestUrl, sendData, null);
        int responseCode = Integer.parseInt(response.get("responseCode").toString());
        byte[] responseBytes = (byte[]) response.get("responseData");
        String responseString;
        try {
            responseString = new String(responseBytes, "UTF-8");
        }
        catch (UnsupportedEncodingException e) {
            responseString = new String(responseBytes);
        }
        //请求返回结果无论成功失败,http-status均为200
        if(responseCode == 200){
            //返回结果
            return responseString;
        }else{
            throw new IOException(responseCode+":"+responseString);
        }
    }

    public static byte[] sendHttpGet(String host, String method, String urlParams) throws IOException {
        String requestUrl = host + method + urlParams;
        Map<String, Object> response =  request("GET", requestUrl, null, null);
        int responseCode = Integer.parseInt(response.get("responseCode").toString());
        byte[] responseBytes = (byte[]) response.get("responseData");
        //请求返回结果无论成功失败,http-status均为200
        if(responseCode == 200){
            //返回结果
            return responseBytes;
        }else{
            throw new IOException(responseCode+"");
        }
    }

    public static String urlencode(String data) {
        return urlencode(data, "UTF-8");
    }

    public static String urlencode(String data, String charset) {
        try {
            return URLEncoder.encode(data, charset);
        }
        catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static Map<String, Object> request(String method, String url, Object sendData, Map<String, String> headers) throws IOException {


        String requestPath;
        try {
            requestPath = new URL(url).getPath();
        }
        catch (MalformedURLException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        CloseableHttpClient httpClient = getHttpClient(requestPath);

        Map<String, Object> response = null;
        if("POST".equals(method)){
            response = sendPost(httpClient, url, headers, sendData);
        }else{
            response = sendGet(httpClient, url, headers);
        }
        return response;
    }

    private static Map<String, Object> sendPost(CloseableHttpClient httpClient, String url, Map<String, String> headers, Object sendData) throws IOException{
        String tag = "[HttpRequester] [POST " + url + "]";
        int responseCode = -1;
        byte[] responseBytes = null;

        HttpPost request = new HttpPost(url);
        if (headers != null && headers.size() > 0) {
            for (String name : headers.keySet()) {
                String value = headers.get(name);
                request.setHeader(name,value);
            }
        }
        if (sendData != null) {
            StringEntity stringEntity = new StringEntity((String)sendData, "UTF-8");
            stringEntity.setContentType("application/json");
            request.setEntity(stringEntity);

            HttpEntity httpEntity = null;
            IOException exception = null;
            for (int i = 0; i < 3; i++) {
                try {
                    CloseableHttpResponse response = httpClient.execute(request);
                    responseCode = response.getStatusLine().getStatusCode();
                    httpEntity = response.getEntity();

                    String responseBody = EntityUtils.toString(httpEntity, "utf-8");
                    if(responseBody != null){
                        responseBytes = responseBody.getBytes();
                    }else{
                       InputStream respStream = null;
                        try{
                           respStream = httpEntity.getContent();
                            int respBodySize = respStream.available();
                            if (respBodySize <= 0)
                                throw new IOException("Invalid respBodySize: " + respBodySize);
                            responseBytes = new byte[respBodySize];
                            if (respStream.read(responseBytes) != respBodySize)
                                throw new IOException("Read respBody Error");
                        } catch (Exception e) {
                        } finally{
                           if(respStream != null){
                              respStream.close();
                           }
                        }
                    }

                    exception = null;
                    break;
                }
                catch (UnsupportedOperationException e) {
                    try {
                        EntityUtils.consume(httpEntity);
                    }
                    catch (IOException e2) {

                    }
                    throw new RuntimeException(e.getMessage(), e);
                }
                catch (IOException e) {
                    e.printStackTrace();
                    exception = e;
                    try {
                        EntityUtils.consume(httpEntity);
                    }
                    catch (IOException e2) {

                    }
                    if (i < 2) {
                        try {
                            Thread.sleep(5);
                        }
                        catch (InterruptedException e2) {

                        }
                    }
                }
            }
            if (exception != null) {
                throw exception;
            }

        }
        Map<String, Object> response = new HashMap<String, Object>();
        response.put("responseCode", responseCode);
        response.put("responseData", responseBytes);
        String loggerResponseString = getLoggerString(responseBytes, 256);
        return response;
    }

    private static Map<String, Object> sendGet(CloseableHttpClient httpClient, String url, Map<String, String> headers) throws IOException{
        String tag = "[HttpRequester] [GET " + url + "]";
        int responseCode = -1;
        byte[] responseBytes = null;

        HttpGet request = new HttpGet(url);
        if (headers != null && headers.size() > 0) {
            for (String name : headers.keySet()) {
                String value = headers.get(name);
                request.setHeader(name,value);
            }
        }
        HttpEntity httpEntity = null;
        IOException exception = null;
        for (int i = 0; i < 3; i++) {
            try {
                CloseableHttpResponse response = httpClient.execute(request);
                responseCode = response.getStatusLine().getStatusCode();
                httpEntity = response.getEntity();

                byte[] responseBody = EntityUtils.toByteArray(httpEntity);
                if(responseBody != null){
                    responseBytes = responseBody;
                }else{
                   InputStream respStream = null;
                    try{
                       respStream = httpEntity.getContent();
                        int respBodySize = respStream.available();
                        if (respBodySize <= 0)
                            throw new IOException("Invalid respBodySize: " + respBodySize);
                        responseBytes = new byte[respBodySize];
                        if (respStream.read(responseBytes) != respBodySize)
                            throw new IOException("Read respBody Error");
                    } catch (Exception e) {
                    } finally{
                       if(respStream != null){
                          respStream.close();
                       }
                    }
                }

                exception = null;
                break;
            }
            catch (UnsupportedOperationException e) {
                try {
                    EntityUtils.consume(httpEntity);
                }
                catch (IOException e2) {

                }
                throw new RuntimeException(e.getMessage(), e);
            }
            catch (IOException e) {
                e.printStackTrace();
                exception = e;
                try {
                    EntityUtils.consume(httpEntity);
                }
                catch (IOException e2) {

                }
                if (i < 2) {
                    try {
                        Thread.sleep(5);
                    }
                    catch (InterruptedException e2) {

                    }
                }
            }
        }
        if (exception != null) {
            throw exception;
        }
        Map<String, Object> response = new HashMap<String, Object>();
        response.put("responseCode", responseCode);
        response.put("responseData", responseBytes);
        String loggerResponseString = getLoggerString(responseBytes, 256);
        System.out.println(tag + " response " + responseCode + " " + loggerResponseString);
        return response;
    }

    private static String getLoggerString(final byte[] data, int maxLength) {
        String loggerString;
        if (data.length > maxLength) {
            byte[] shortData = new byte[maxLength];
            System.arraycopy(data, 0, shortData, 0, shortData.length);
            try {
                loggerString = new String(shortData, "UTF-8") + "...";
            }
            catch (UnsupportedEncodingException e) {
                loggerString = new String(shortData) + "...";
            }
        }
        else {
            try {
                loggerString = new String(data, "UTF-8");
            }
            catch (UnsupportedEncodingException e) {
                loggerString = new String(data);
            }
        }

        char[] chars = new char[loggerString.length()];
        loggerString.getChars(0, loggerString.length(), chars, 0);
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (c == '\n' || c == '\r') {
                chars[i] = ' ';
            }
        }
        return new String(chars);
    }

    private static CloseableHttpClient getHttpClient(String requestPath) {
        if (httpClients.containsKey(requestPath)) {
            return httpClients.get(requestPath);
        }
        if (poolingHttpClientConnectionManager == null) {
            synchronized(o) {
                if (poolingHttpClientConnectionManager == null) {
                    poolingHttpClientConnectionManager = HttpClientUtils.createHttpClientConnectionManager();
                }
            }
        }
        synchronized (httpClients) {
            if (httpClients.containsKey(requestPath)) {
                return httpClients.get(requestPath);
            }
            CloseableHttpClient httpClient = HttpClientUtils.createHttpClient(poolingHttpClientConnectionManager);
            httpClients.put(requestPath, httpClient);
            return httpClient;
        }
    }

    private static class HttpClientUtils {

        // 默认连接超时
        private static int defaultConnectTimeout = 6000;
        // 默认读取超时
        private static int defaultReadTimeout = 30000;

        public static CloseableHttpClient createHttpClient(PoolingHttpClientConnectionManager connManager) {
            //HttpHost httpHost = new HttpHost("10.211.55.4", 8888);
            CloseableHttpClient httpClient = HttpClients.custom()
                    //.setProxy(httpHost)
                    .setConnectionManager(connManager)
                    .disableContentCompression()
                    .setSSLContext(getSslcontext())
                    .setDefaultRequestConfig(getRequestConfig())
                    .build();
            return httpClient;
        }

        public static PoolingHttpClientConnectionManager createHttpClientConnectionManager() {
            SSLConnectionSocketFactory sslConnectionSocketFactory = null;
            try {
                sslConnectionSocketFactory = new SSLConnectionSocketFactory(getSslcontext(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                    .register("https", sslConnectionSocketFactory)
                    .register("http", new PlainConnectionSocketFactory())
                    .build();
            PoolingHttpClientConnectionManager cm =new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            cm.setMaxTotal(500);
            cm.setDefaultMaxPerRoute(500);
            return cm;
        }

        private static RequestConfig getRequestConfig() {
            RequestConfig defaultRequestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(defaultConnectTimeout)
                    .setSocketTimeout(defaultReadTimeout)
                    .build();
            return defaultRequestConfig;
        }

        private static SSLContext getSslcontext() {
            SSLContext sslContext = null;
            try {
                sslContext = SSLContext.getInstance("TLS");
                TrustManager tm = new X509TrustManager() {
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                };
                sslContext.init(null, new TrustManager[] { tm }, null);

            }
            catch (Exception e) {
                e.printStackTrace();
            }
            return sslContext;
        }
    }
}

工具类

RSAUtils

public class RSAUtils {

    /**
     * 获取当前的时间戳参数
     * @return
     */
    public static String getRtick(){
        long timestamp = new Date().getTime();
        int rnd = (int)Math.random() * 1000;
        String rtick = timestamp + "" + rnd;
        return rtick;
    }

    /**
     * 计算参数签名
     * @param developerId 开发者ID
     * @param privateKey 用户私钥
     * @param host 请求的HOST地址(http://ip:port/context)
     * @param methodName 请求的接口方法名
     * @param rtick 时间戳参数
     * @param urlParams url参数(param1=value1&param2=value2&param3=value3)
     * @param requestBody request body 参数(JSON字符串)
     * @return
     */
    public static String calcRsaSign(String developerId, String privateKey, String host, String methodName, String rtick, String urlParams, String requestBody) {
        String url = host+methodName;

        Map<String, String> mySignedURLParams = new TreeMap<String, String>();
        mySignedURLParams.put("developerId", developerId);
        mySignedURLParams.put("rtick", rtick);
        mySignedURLParams.put("signType", "rsa");

        if(urlParams != null && !"".equals(urlParams)){
            String[] params = urlParams.split("&");
            for(String p1 : params){
                String[] p2 = p1.split("=");
                String key = p2[0];
                String value = "";
                if(p2.length == 2){
                    value = p2[1];
                }
                mySignedURLParams.put(key, value);
            }
        }

        String requestPath;
        try {
            requestPath = new URL(url).getPath();
        }
        catch (MalformedURLException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        StringBuilder signStringBuilder = new StringBuilder();
        for (String name : mySignedURLParams.keySet()) {
            String value = mySignedURLParams.get(name);
            signStringBuilder.append(name);
            signStringBuilder.append("=");
            signStringBuilder.append(value);
        }
        signStringBuilder.append(requestPath);

        if (requestBody != null && !"".equals(requestBody) ) {
            String requestMd5 = getRequestMd5(requestBody);
            signStringBuilder.append(requestMd5);
        }

        String signString = signStringBuilder.toString();
        String rsaSign =  calcRsaSign(privateKey, signString);
        //rsa算出来的sign,需要urlencode
        try {
            rsaSign = URLEncoder.encode(rsaSign,"UTF-8");
        } catch (UnsupportedEncodingException e) {
            rsaSign = null;
        }
        return rsaSign;
    }

    /**
     * 获取request body 的MD5
     * @param requestBody
     * @return
     */
    private static String getRequestMd5(final String requestBody) {
        byte[] data;

        String newRequestBody = convertToUtf8(requestBody);
        try {
            data = newRequestBody.getBytes("UTF-8");
        }
        catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        return md5(data);
    }

    /**
     * 计算参数RSA签名
     * @param privateKey
     * @param signData
     * @return
     */
    private static String calcRsaSign(String privateKey, final String signData) {
        byte[] data;
        try {
            data = signData.getBytes("UTF-8");
        }
        catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        byte[] sign = null;
        // 解密由base64编码的私钥
        byte[] privateKeyBytes = base64decode(privateKey.getBytes());

        // 构造PKCS8EncodedKeySpec对象
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);

        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        // 取私钥匙对象
        PrivateKey priKey;
        try {
            priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        }
        catch (InvalidKeySpecException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        // 用私钥对信息生成数字签名
        Signature signature;
        try {
            signature = Signature.getInstance("SHA1withRSA");
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        try {
            signature.initSign(priKey);
        }
        catch (InvalidKeyException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        try {
            signature.update(data);
            sign = signature.sign();
        }
        catch (SignatureException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        return new String(base64encode(sign));
    }

    /**
     * 转换字符集到utf8
     *
     * @param src
     * @return
     */
    private static String convertToUtf8(String src) {
        if (src == null || src.length() == 0) {
            return src;
        }
        if ("UTF-8".equalsIgnoreCase(Charset.defaultCharset().name())) {
            return src;
        }

        byte[] srcData = src.getBytes();
        try {
            return new String(srcData, "UTF-8");
        }
        catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * md5
     * @param data
     * @return
     */
    public static String md5(byte[] data) {
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
        byte[] btInput = data;
        // 获得MD5摘要算法的 MessageDigest 对象
        MessageDigest mdInst;
        try {
            mdInst = MessageDigest.getInstance("MD5");
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        // 使用指定的字节更新摘要
        mdInst.update(btInput);
        // 获得密文
        byte[] md = mdInst.digest();
        // 把密文转换成十六进制的字符串形式
        int j = md.length;
        char str[] = new char[j * 2];
        int k = 0;
        for (int i = 0; i < j; i++) {
            byte byte0 = md[i];
            str[k++] = hexDigits[byte0 >>> 4 & 0xf];
            str[k++] = hexDigits[byte0 & 0xf];
        }
        return new String(str);
    }

    /**
     * base64编码
     * @param data
     * @return
     */
    public static byte[] base64encode(byte[] data) {
        return Base64.encodeBase64(data);
    }

    /**
     * base64编码字符串
     * @param data
     * @return
     */
    public static String base64encodeString(byte[] data) {
        return Base64.encodeBase64String(data);
    }

    /**
     * base64解码
     * @param data
     * @return
     */
    public static byte[] base64decode(byte[] data) {
        try {
            return Base64.decodeBase64(data);
        } catch (Exception e) {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            for (int i = 0; i < data.length; i++) {
                byte c = data[i];
                if (c == 13 || c == 10) {
                    continue;
                }
                outputStream.write(c);
            }
            try {
                outputStream.close();
            } catch (IOException e2) {

            }
            data = outputStream.toByteArray();
            return Base64.decodeBase64(data);
        }
    }
}