常用通讯方式socket,http,https

1.socket

1.1 client

1.1.1 方式1

public static String signAndVerify(String message, String signServeHost, int signServePort)  {
        LOGGER.info("签名验签请求:" + message);
        Socket socket = null;
        OutputStream outs = null;
        BufferedOutputStream bouts = null;
        InputStream ins = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            socket = new Socket();
            // 设置连接请求超时时间10s
            socket.connect(new InetSocketAddress(signServeHost, signServePort), MAX_TIMEOUT);
            // 设置读操作超时时间15s,setSoTimeout()设置的是读取数据时阻塞链路的超时时间,原文(Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.)
            socket.setSoTimeout(MAX_TIMEOUT);
            // 获取输出流
            outs = socket.getOutputStream();
            /* 写入请求数据 */
            bouts = new BufferedOutputStream(outs);
            bouts.write(message.getBytes("GBK"));
            bouts.flush();
            // 结束发送
            socket.shutdownOutput();
            // 获取输入流
            ins = socket.getInputStream();
            isr = new InputStreamReader(ins, "GBK");
            br = new BufferedReader(isr);
            /* 读取返回数据 */
            StringBuffer sb = new StringBuffer();
            String info = null;
            while ((info = br.readLine()) != null) {
                sb.append(info);
            }
            String resultMsg = sb.toString();
            LOGGER.info("返回:" + resultMsg);
            return resultMsg;
        } catch (Exception e) {
            LOGGER.error("失败", e);
            BankAdapterException te = new BankAdapterException("失败" + e.getMessage(), e);
            te.setErrorCode(String.valueOf(ErrorCode.RECEIVE_FROM_BANK_ERROR));
            throw te;
        } finally {
            try {
                br.close();
                isr.close();
                ins.close();
                socket.close();
            } catch (IOException e) {
                LOGGER.error("释放异常");
            }
        }
    }

1.1.2 方式2

public String sendMessageRequest(String message, String bankFrontIP, int bankFrontPort) throws BankAdapterException {
        Socket socket = null;
        OutputStream outs = null;
        PrintWriter pw = null;
        InputStream ins = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            try {
                // 建立sockt连接
                socket = new Socket();
                // 设置连接请求超时时间15s
                socket.connect(new InetSocketAddress(bankFrontIP, bankFrontPort), 15000);
                // 设置读操作超时时间30s
                socket.setSoTimeout(30000);
                // 获取输出流
                outs = socket.getOutputStream();
                /* 写入请求数据 */
                pw = new PrintWriter(outs);
                pw.print(message);
                pw.flush();
                socket.shutdownOutput();
            } catch (Exception e) {
                LOGGER.error("报文发送异常", e);
                BankAdapterException te = new BankAdapterException("报文发送异常:" + e.getMessage(), e);
                te.setErrorCode(String.valueOf(ErrorCode.SEND_TO_BANK_ERROR));
                throw te;
            }
            try {
                // 获取输入流
                ins = socket.getInputStream();
                isr = new InputStreamReader(ins);
                br = new BufferedReader(isr);
                /* 读取返回数据 */
                StringBuffer sb = new StringBuffer();
                String info = null;
                while ((info = br.readLine()) != null) {
                    sb.append(info);
                }

                return sb.toString();
            } catch (Exception e) {
                LOGGER.error("接收回复异常", e);
                BankAdapterException te = new BankAdapterException("接收回复异常:" + e.getMessage(), e);
                te.setErrorCode(String.valueOf(ErrorCode.RECEIVE_FROM_BANK_ERROR));
                throw te;
            }

        }finally {
            try {
                socket.shutdownInput();
                ins.close();
                isr.close();
                br.close();
            } catch (IOException e) {
                LOGGER.error("关闭输入流失败");
            }
            try {
                LOGGER.info("正在关闭套接字");
                socket.close();
            } catch (IOException e) {
                LOGGER.error("关闭套接字失败");
            }
        }
    }

1.2 server

2.http

2.1 client

2.2 server

3.https

3.1 client

3.3.1 不校验证书

public String sendBankServer(String postData, String reqUrl) throws Exception {
        LOGGER.info("\n请求银行URL:" + reqUrl + "\n发送银行内容:" + postData);
        CloseableHttpClient httpClient = getIgnoredCertHttpClient();
        StringEntity stringEntity = new StringEntity(postData, "GBK");
        stringEntity.setContentEncoding("GBK");
        stringEntity.setContentType("text/xml; charset=GBK");

        HttpPost httpPost = new HttpPost(reqUrl);
        httpPost.setHeader("Content-Type", "text/xml; charset=GBK");
        httpPost.setHeader("Host", BANK_HOST);
        httpPost.setEntity(stringEntity);

        String responseBody = "";
        try {
            // 执行请求操作,并拿到结果(同步阻塞)
            CloseableHttpResponse response = httpClient.execute(httpPost);
            // 获取结果实体
            HttpEntity httpEntity = response.getEntity();
            if (httpEntity != null) {
                // 按指定编码转换结果实体为String类型
                responseBody = EntityUtils.toString(httpEntity, "GBK");
            }
            
            // 释放httpEntity占用的所有资源,实质是释放底层的流并将连接归还连接池
            EntityUtils.consume(httpEntity);
            // 释放链接
            response.close();
        } finally {
            httpClient.close();
        }
        LOGGER.info("收到银行回复:" + responseBody);
        return responseBody;
    }

    public CloseableHttpClient getIgnoredCertHttpClient() throws KeyManagementException, NoSuchAlgorithmException {
        // 实现一个X509TrustManager接口,信任证书用于绕过验证,不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException {}

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException {}

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        SSLContext sslContext = SSLContext.getInstance("SSLv3");

        // 采用绕过验证的方式处理https请求
        sslContext.init(null, new TrustManager[] { trustManager }, null);

        // 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                // 不校验主机名
                .register("https", new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier()))
                .build();

        //创建http连接池管理器
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        // 请求参数设置
        RequestConfig requestConfig = RequestConfig.custom()
                // 从连接池中获取连接的超时时间
                .setConnectionRequestTimeout(MAX_TIMEOUT)
                // 与服务器连接超时时间:httpclient会创建一个异步线程用以创建socket连接,此处设置该socket的连接超时时间
                .setConnectTimeout(MAX_TIMEOUT)
                // socket读取数据时阻塞链路的超时时间,即从服务器获取响应数据的超时时间
                .setSocketTimeout(MAX_TIMEOUT)
                // 在提交请求之前测试连接是否可用The stale connection check can cause up to 30 millisecond overhead per request 
                //.setStaleConnectionCheckEnabled(true)
                // 不做认证
                .setAuthenticationEnabled(false)
                .build();
        // 创建自定义的httpclient对象
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connManager)
                .setDefaultRequestConfig(requestConfig)
                .build();

        return httpClient;
    }

3.1.2使用证书

public  CloseableHttpClient getHttpClient(String certFilePath,String keyStoryPwd) {
        FileInputStream instream = null;
        CloseableHttpClient httpclient = null;
        try {
            // 指定读取证书格式为PKCS12
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            // 读取本机存放的PKCS12证书文件
            instream = new FileInputStream(new File(certFilePath));
            // 指定PKCS12的密码(商户ID)
            keyStore.load(instream, keyStoryPwd.toCharArray());

            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, keyStoryPwd.toCharArray()).build();
            // 指定TLS版本
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,new String[] { "TLSv1" },null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            // 设置httpclient的SSLSocketFactory
            httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyStoreException e) {
            LOGGER.error("私钥文件异常", e);
        } catch (FileNotFoundException e) {
            LOGGER.error("证书文件未找到", e);
        }catch (NoSuchAlgorithmException e) {
            LOGGER.error("算法异常", e);
        } catch (CertificateException e) {
            LOGGER.error("证书异常", e);
        } catch (IOException e) {
            LOGGER.error("读取证书文件异常", e);
        } catch (KeyManagementException e) {
            LOGGER.error("KeyManagementException异常", e);
        } catch (UnrecoverableKeyException e) {
            LOGGER.error("UnrecoverableKeyException异常", e);
        }finally{
            if(instream !=null){
                try {
                    instream.close();
                } catch (IOException e) {
                    LOGGER.error("inputStream close IOException:" + e.getMessage());
                }
            }
        }
        return httpclient;
    }
    
    protected String postRequest(String urlAddr, String reqXml) throws Exception {

        String responseXML = null;
        //import httpclient-4.3.6.jar
        CloseableHttpResponse response = null;
        String keyStoryPwd = "证书密钥";
        String certFilePath = "证书地址";
        
        CloseableHttpClient httpclient =  getHttpClient(certFilePath,keyStoryPwd);

        try {
            HttpPost httppost = new HttpPost(urlAddr);
            
            StringEntity pentity = new StringEntity(reqXml, Charset.forName("UTF-8"));
            pentity.setContentEncoding("UTF-8");
            pentity.setContentType("text/xml");
            httppost.setEntity(pentity);

            response = httpclient.execute(httppost);
            
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                //import httpcore-4.3.3.jar EntityUtils
                byte[] buff = EntityUtils.toByteArray(entity);
                responseXML = new String(buff, "UTF-8");
            }

            LOGGER.info("receive:" + responseXML);
            return responseXML;

        } catch (IOException e) {
            LOGGER.error("读返回信息失败" + e.getMessage());
            
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                LOGGER.error("response close IOException:" + e.getMessage());
            }
            try {
                httpclient.close();
            } catch (IOException e) {
                LOGGER.error("httpclient close IOException:" + e.getMessage());
            }
        }
        return null;
    }

3.2 server

猜你喜欢

转载自blog.csdn.net/cpp1781089410/article/details/78141436