首页 > 技术文章 > https

yqlwl66 2019-09-06 11:56 原文

package com.skyecho.product.charter.cutting.test.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class SendUtil {
private static String proxyHost;
private static int proxyPort = 0;
private static Boolean showLog = true;

/

/**
* CONTENT_TYPE_KEY: Content-Type
*/
private static final String CONTENT_TYPE_KEY = "Content-Type";
/**
* CONTENT_TYPE_VALUE: text/html;charset=UTF-8
*/
private static final String CONTENT_TYPE_VALUE = "application/json;charset=UTF-8";

/**
* ACCEPT_ENCODING_KEY: Accept-Encoding
*/
private static final String ACCEPT_ENCODING_KEY = "Accept-Encoding";
/**
* ACCEPT_ENCODING_VALUE: gzip
*/
private static final String ACCEPT_ENCODING_VALUE = "gzip";

/**
* CONTENT_ENCODING_KEY: Content-Encoding
*/
private static final String CONTENT_ENCODING_KEY = "Content-Encoding";
/**
* CONTENT_ENCODING_VALUE: gzip
*/
private static final String CONTENT_ENCODING_VALUE = "gzip";

/**
* DEFAULT_ENCODING: UTF-8
*/
private static final String DEFAULT_ENCODING = "UTF-8";

private static final String COLON = ":";

/**
* 链接超时时间(单位:ms)
*/
private static Integer CONNECTION_TIMEOUT = 5000;

/**
* 请求超时时间(单位:ms)
*/
private static Integer REQUEST_TIMEOUT = 45000;

 

/**
* 发送post请求调用
* @param requestXml 请求xml
* @param ibeplusServantName 接口应用名字
* @return String 响应
* @throws RemoteException
* @since 1.0.0
*/
public String sendHttpPostMethod(String requestXml, String servantUrl, String ibeplusServantName,
String userName, String password) throws Exception {
HttpPost httpPost = null;
try {
HttpClient httpClient = getHttpClient();
log.info("发送请求开始, 地址:{},接口名:{},账号:{},密码:{}", servantUrl, ibeplusServantName, userName, password);
printReqeustLog(requestXml);
httpPost = getHttpPost(requestXml, servantUrl, ibeplusServantName, userName, password);
long b = System.currentTimeMillis();
HttpResponse httpResponse = httpClient.execute(httpPost);
log.info("================"+JSON.toJSONString(httpResponse));
long e = System.currentTimeMillis();
isSendSuccess(httpResponse);
String resp = getResponseString(httpResponse);
printResponseLog(resp);
log.info("发送请求完成,全程耗时{}ms", (e - b));
return resp;
} catch (Exception e) {
log.error("================",e);
throw new Exception(e);
} finally {
if (httpPost != null) {
httpPost.releaseConnection();
}
}
}

private static byte[] coverUserInfo(String username, String password) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
result.append(username);
result.append(COLON);
result.append((password == null) ? "null" : password);
return result.toString().getBytes(DEFAULT_ENCODING);

}

private static CloseableHttpClient getHttpClient()
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
HttpClientBuilder httpClientBuilder = HttpClients.custom();
SSLContext sslContext = getSSLContext();
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
String[] supportedProtocols = new String[] { "TLSv1.2" };
String[] supportedCipherSuites = new String[] { "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" };
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, supportedProtocols,
supportedCipherSuites, hostnameVerifier);
httpClientBuilder.setSSLSocketFactory(sslsf);
// 设置超时时间
RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(CONNECTION_TIMEOUT)
.setSocketTimeout(REQUEST_TIMEOUT).build();
httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig);
if (!StringUtils.isEmpty(proxyHost)) {
HttpHost proxy = new HttpHost(proxyHost, proxyPort, "http");
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
httpClientBuilder.setRoutePlanner(routePlanner);
}
return httpClientBuilder.build();
}

private static SSLContext getSSLContext()
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, (X509Certificate[] chain, String authType) -> {
return true;
}).build();
return sslContext;
}

/**
* 获取httpost
* @param requestXml 请求xml
* @param servantUrl 请求地址
* @param ibeplusServantName 接口应用名字
* @param userName 账号
* @param password 密码
* @return HttpPost
* @since 1.0.0
*/
private HttpPost getHttpPost(String requestXml, String servantUrl, String ibeplusServantName, String userName,
String password) {

HttpPost httpPost = new HttpPost(servantUrl + ibeplusServantName);
httpPost.setHeader(CONTENT_TYPE_KEY, CONTENT_TYPE_VALUE);
httpPost.setHeader(ACCEPT_ENCODING_KEY, ACCEPT_ENCODING_VALUE);
httpPost.setHeader(CONTENT_ENCODING_KEY, CONTENT_ENCODING_VALUE);

ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = null;
try {
setAuthorization(httpPost, userName, password);
gzip = new GZIPOutputStream(out);
if (requestXml != null && requestXml.length() > 0) {
gzip.write(requestXml.getBytes(DEFAULT_ENCODING));
}
gzip.close();
ByteArrayEntity byteArrayEntity = new ByteArrayEntity(out.toByteArray());
httpPost.setEntity(byteArrayEntity);
out.flush();
out.close();
return httpPost;
} catch (IOException e) {
log.error("获取http请求错误:" + e.getMessage());
} finally {
if (null != gzip) {
try {
gzip.close();
} catch (IOException e) {
log.error("关流失败:" + e.getMessage());
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
log.error("关流失败:" + e.getMessage());
}
}
}
return httpPost;

}

private void setAuthorization(HttpPost httpPost, String userName, String password)
throws UnsupportedEncodingException {
// base64 加密用户名密码
final Base64.Encoder encoder = Base64.getEncoder();
byte[] userInfo = coverUserInfo(userName, password);
String decodeUserInfo = new String(encoder.encode(userInfo), DEFAULT_ENCODING);
httpPost.addHeader("Authorization", "Basic " + decodeUserInfo);
}

/**
* 判断调用是否成功
* @param httpResponse 响应
* @throws Exception 调用失败抛出异常
*/
private void isSendSuccess(HttpResponse httpResponse) throws Exception {
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
throw new Exception("response.noAuthority");
}
}

/**
* 获取响应字符串
* @param httpResponse 响应
* @return 响应字符串
* @throws Exception
* @throws IOException
*/
private String getResponseString(HttpResponse httpResponse) throws IOException {
InputStream is = null;
BufferedReader br = null;
try {
is = httpResponse.getEntity().getContent();
InputStreamReader inputStreamReader = new InputStreamReader(getInputStreamRaw(httpResponse, is),
DEFAULT_ENCODING);
br = new BufferedReader(inputStreamReader);
StringBuffer respStr = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
respStr.append(line);
}
is.close();
inputStreamReader.close();
br.close();
return respStr.toString();
} catch (IOException e) {
throw e;
} finally {
if (null != is) {
try {
is.close();
} catch (IOException e) {
log.error("关流失败:" + e.getMessage());
}
}
if (null != br) {
try {
br.close();
} catch (IOException e) {
log.error("关流失败:" + e.getMessage());
}
}
}

}

/**
* 获取响应输入流,如果是GZIP格式的响应,返回GZIP的输入流
* @param httpResponse 响应
* @param inputStream 响应内容输入流
* @return 对应格式的输入流
* @throws IOException
*/
private InputStream getInputStreamRaw(HttpResponse httpResponse, InputStream inputStream) {
// 获取响应的编码头信息
Header[] headers = httpResponse.getHeaders(CONTENT_ENCODING_KEY);
// 判断是否是gzip格式
if (headers.length == 1 && CONTENT_ENCODING_VALUE.equalsIgnoreCase(headers[0].getValue())) {
try {
return new GZIPInputStream(inputStream);
} catch (IOException e) {
log.debug("接收到一个没有使用GZIP编码的返回 ,{} ", e.getMessage());
}
}
log.debug("接收到一个没有使用GZIP编码的返回");
return inputStream;
}

/**
* 打印请求参数
* @param requestXml 请求xml
*/
private void printReqeustLog(String requestXml) {
log.info("[ Request XML]:\r\n{}", requestXml);
}

/**
* 打印响应内容
* @param responseXml 响应xml
*/
private void printResponseLog(String responseXml) {
log.info("[ Reaponse XML]:\r\n{}", responseXml);
}
}

推荐阅读