public class PCIHttpClientImpl4 implementsPCIHttpClient {private static LogUtils logger = new LogUtils(PCIHttpClientImpl4.class);private SSLConnectionSocketFactory sslSocketFactory = null;/*** 构造方法
*
*
允许信任任何证书策略和允许任何域名验证
*/publicPCIHttpClientImpl4() {this(false, false, true, true, null, null, null);
}/*** 构造方法
*
*@paramallowAnyTrustMaterial 是否允许信任任何证书策略
*@paramallowAnyHostnameVerifier 是否允许任何域名验证*/
public PCIHttpClientImpl4(boolean allowAnyTrustMaterial, booleanallowAnyHostnameVerifier) {this(false, false, allowAnyTrustMaterial, allowAnyHostnameVerifier, null, null, null);
}/*** 构造方法
*
*@paramloadKeyMaterial 是否加载密钥
*@paramloadTrustMaterial 是否加载信任证书
*@paramkeystoreFilePath 密钥库文件路径
*@paramstorePassword 密钥库密码
*@paramkeyPassword 私钥密码*/
public PCIHttpClientImpl4(boolean loadKeyMaterial, booleanloadTrustMaterial,
String keystoreFilePath, String storePassword, String keyPassword) {this(loadKeyMaterial, loadTrustMaterial, false, true, keystoreFilePath, storePassword, keyPassword);
}/*** 构造方法
*
*@paramloadKeyMaterial 是否加载密钥
*@paramloadTrustMaterial 是否加载信任证书(若allowAnyTrustMaterial=true,则loadTrustMaterial无效)
*@paramallowAnyTrustMaterial 是否允许信任任何证书策略
*@paramallowAnyHostnameVerifier 是否允许任何域名验证
*@paramkeystoreFilePath 密钥库文件路径
*@paramstorePassword 密钥库密码
*@paramkeyPassword 私钥密码*/
public PCIHttpClientImpl4(boolean loadKeyMaterial, booleanloadTrustMaterial,boolean allowAnyTrustMaterial, booleanallowAnyHostnameVerifier,
String keystoreFilePath, String storePassword, String keyPassword) {try{//Create SSLContext
SSLContextBuilder sslContextBuilder = newSSLContextBuilder();if(loadKeyMaterial) {
sslContextBuilder.loadKeyMaterial(newFile(keystoreFilePath), storePassword.toCharArray(), keyPassword.toCharArray());
}if(allowAnyTrustMaterial) {
sslContextBuilder.loadTrustMaterial(null, newAnyTrustStrategy());
}else if(loadTrustMaterial) {
sslContextBuilder.loadTrustMaterial(new File(keystoreFilePath), storePassword.toCharArray(), newTrustSelfSignedStrategy());
}
SSLContext sslContext=sslContextBuilder.build();//Create SSLConnectionSocketFactory
if(allowAnyHostnameVerifier) {
sslSocketFactory= new SSLConnectionSocketFactory(sslContext, newAnyHostnameVerifier());
}else{
sslSocketFactory= newSSLConnectionSocketFactory(sslContext);
}
}catch(NoSuchAlgorithmException e) {
logger.error("Error occurred: NoSuchAlgorithmException", e);
}catch(KeyStoreException e) {
logger.error("Error occurred: KeyStoreException", e);
}catch(UnrecoverableKeyException e) {
logger.error("Error occurred: UnrecoverableKeyException", e);
}catch(CertificateException e) {
logger.error("Error occurred: CertificateException", e);
}catch(IOException e) {
logger.error("Error occurred: IOException", e);
}catch(KeyManagementException e) {
logger.error("Error occurred: KeyManagementException", e);
}
}/*** 信任任何证书策略*/
private static class AnyTrustStrategy implementsTrustStrategy {
@Overridepublic booleanisTrusted(X509Certificate[] chain, String authType)throwsCertificateException {return true;
}
}/*** 允许任何域名验证*/
private static class AnyHostnameVerifier implementsHostnameVerifier {
@Overridepublic booleanverify(String hostname, SSLSession session) {return true;
}
}
@OverridepublicString sendGetAndResponseAsString(String url,int timeout) throwsIOException {return sendGetAndResponseAsString(url, null, null, CustomConstants.CHARSET_UTF8, timeout);
}
@OverridepublicString sendGetAndResponseAsString(String url,
Map headers, int timeout) throwsIOException {return sendGetAndResponseAsString(url, headers, null, CustomConstants.CHARSET_UTF8, timeout);
}
@OverridepublicString sendGetAndResponseAsString(String url,
Map headers, Mapparams,
String charsetName,int timeout) throwsIOException {byte[] buffer =sendGetAndResponseAsByteArray(url, headers, params, charsetName, timeout);if (buffer == null) {return null;
}return newString(buffer, charsetName);
}
@Overridepublic byte[] sendGetAndResponseAsByteArray(String url,int timeout) throwsIOException {return sendGetAndResponseAsByteArray(url, null, null, null, timeout);
}
@Overridepublic byte[] sendGetAndResponseAsByteArray(String url,
Map headers, int timeout) throwsIOException {return sendGetAndResponseAsByteArray(url, headers, null, null, timeout);
}
@Overridepublic byte[] sendGetAndResponseAsByteArray(String url,
Map headers, Mapparams,
String charsetName,int timeout) throwsIOException {
ByteArrayOutputStream output= null;try{
output= newByteArrayOutputStream();
sendGet(url, headers, params, charsetName, timeout, output);returnoutput.toByteArray();
}finally{
IOUtils.closeQuietly(output);
}
}
@OverridepublicInputStream sendGetAndResponseAsStream(String url,
Map headers, Mapparams,
String charsetName,int timeout) throwsIOException {byte[] buffer =sendGetAndResponseAsByteArray(url, headers, params, charsetName, timeout);if (buffer == null) {return null;
}return newByteArrayInputStream(buffer);
}
@Overridepublic void sendGet(String url, Mapheaders,
Map params, String charsetName, inttimeout,
OutputStream output)throwsIOException {if(StringUtils.isEmpty(url)) {
logger.error("The url can not be null.");throw new IllegalArgumentException("The url can not be null.");
}
sendAndResponseAsStream(newHttpGet(createURI(url, params, charsetName)),
headers, timeout, output);
}
@OverridepublicString sendPostAndResponseAsString(String url,
Map params, String charsetName, int timeout) throwsIOException {return sendPostAndResponseAsString(url, null, params, null, charsetName, timeout);
}
@OverridepublicString sendPostAndResponseAsString(String url,
Map headers, Mapparams,int timeout, String charsetName) throwsIOException {return sendPostAndResponseAsString(url, headers, params, null, charsetName, timeout);
}
@OverridepublicString sendPostAndResponseAsString(String url,
Mapheaders, Object stringOrStream,
String charsetName,int timeout) throwsIOException {return sendPostAndResponseAsString(url, headers, null, stringOrStream, charsetName, timeout);
}
@OverridepublicString sendPostAndResponseAsString(String url,
Map headers, Mapparams,
Object stringOrStream, String charsetName,int timeout) throwsIOException {byte[] buffer =sendPostAndResponseAsByteArray(
url, headers, params, stringOrStream, charsetName, timeout);if (buffer == null) {return null;
}return newString(buffer, charsetName);
}
@Overridepublic byte[] sendPostAndResponseAsByteArray(String url,
Map params, String charsetName, int timeout) throwsIOException {return sendPostAndResponseAsByteArray(url, null, params, null, charsetName, timeout);
}
@Overridepublic byte[] sendPostAndResponseAsByteArray(String url,
Map headers, Mapparams,int timeout, String charsetName) throwsIOException {return sendPostAndResponseAsByteArray(url, headers, params, null, charsetName, timeout);
}
@Overridepublic byte[] sendPostAndResponseAsByteArray(String url,
Mapheaders, Object stringOrStream,
String charsetName,int timeout) throwsIOException {return sendPostAndResponseAsByteArray(url, headers, null, stringOrStream, charsetName, timeout);
}
@Overridepublic byte[] sendPostAndResponseAsByteArray(String url,
Map headers, Mapparams,
Object stringOrStream, String charsetName,int timeout) throwsIOException {
ByteArrayOutputStream output= null;try{
output= newByteArrayOutputStream();
sendPost(url, headers, params, stringOrStream, charsetName, timeout, output);returnoutput.toByteArray();
}finally{
IOUtils.closeQuietly(output);
}
}
@OverridepublicInputStream sendPostAndResponseAsStream(String url,
Map headers, Mapparams,
Object stringOrStream, String charsetName,int timeout) throwsIOException {byte[] buffer =sendPostAndResponseAsByteArray(
url, headers, params, stringOrStream, charsetName, timeout);if (buffer == null) {return null;
}return newByteArrayInputStream(buffer);
}
@Overridepublic void sendPost(String url, Mapheaders,
Mapparams, Object stringOrStream,
String charsetName,int timeout, OutputStream output) throwsIOException {if(StringUtils.isEmpty(url)) {
logger.error("The url can not be null.");throw new IllegalArgumentException("The url can not be null.");
}//post请求方式
HttpPost method = newHttpPost(createURI(url, params, charsetName));//设置请求头信息
if (headers == null) {
headers= new HashMap();
}if (!headers.containsKey(CONTENT_TYPE)) {
headers.put(CONTENT_TYPE, DEFAULT_CONTENTTYPE);
}//设置请求体内容
if (stringOrStream != null) {
HttpEntity entity= null;if (stringOrStream instanceofInputStream) {
entity= newInputStreamEntity((InputStream) stringOrStream);
}else{
entity= newStringEntity(stringOrStream.toString(),
ContentType.create(CONTENT_TYPE, charsetName));
}
method.setEntity(entity);
}//发送请求数据,并接收响应数据
sendAndResponseAsStream(method, headers, timeout, output);
}/*** 发送请求数据,并接收响应数据
*@parammethod 请求方式
*@paramheaders 请求头信息
*@paramtimeout 超时时间
*@paramoutput 响应内容(输出流)
*@throwsIOException*/
private voidsendAndResponseAsStream(HttpRequestBase method,
Map headers, int timeout, OutputStream output) throwsIOException {//设置请求配置信息
RequestConfig config =RequestConfig.custom()
.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT)//连接超时时间
.setSocketTimeout(timeout) //读取超时时间
.setCircularRedirectsAllowed(true) //设置是否允许循环重定向(重定向到相同路径)
.build();
method.setConfig(config);//设置请求头信息
if (headers == null) {
headers= new HashMap();
}if (!headers.containsKey(USER_AGENT)) {
headers.put(USER_AGENT, DEFAULT_USERAGENT);
}for (Map.Entryentry : headers.entrySet()) {
method.setHeader(entry.getKey(), entry.getValue());
}//发送请求
CloseableHttpClient httpClient =createHttpClient(method.getURI());
CloseableHttpResponse httpResponse= null;
InputStream input= null;try{
httpResponse=httpClient.execute(method);int status =httpResponse.getStatusLine().getStatusCode();if (status !=HttpStatus.SC_OK) {
String errorMsg= CustomStringUtils.append("The remote service[",
method.getURI(),"] respose an error status:", status);
logger.error(errorMsg);if (status >= 500 && status < 600) {throw newIOException(errorMsg);
}
}
HttpEntity httpEntity=httpResponse.getEntity();if (httpEntity == null) {
String errorMsg= CustomStringUtils.append("The remote service[",
method.getURI(),"] respose entity is null. status:", status);
logger.error(errorMsg);throw newIOException(errorMsg);
}
input=httpEntity.getContent();if (input == null) {
String errorMsg= CustomStringUtils.append("The remote service[",
method.getURI(),"] respose entity content is null. status:", status);
logger.error(errorMsg);throw newIOException(errorMsg);
}
IOUtils.copy(input, output);
}catch(IOException e) {
logger.error("Access to the remote service[" + method.getURI() + "] error.", e);throwe;
}finally{
IOUtils.closeQuietly(input);//method.releaseConnection();
IOUtils.closeQuietly(httpResponse);
IOUtils.closeQuietly(httpClient);
}
}/*** 创建HttpClient对象
*@paramuri
*@return
*/
privateCloseableHttpClient createHttpClient(URI uri) {if ("https".equalsIgnoreCase(uri.getScheme()) && sslSocketFactory != null) {returnHttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
}else{returnHttpClients.createDefault();
}
}/*** 创建请求URI
*@paramurl
*@paramparams
*@paramcharsetName
*@return*@throwsIOException*/
privateURI createURI(String url,
Map params, String charsetName) throwsIOException {if (params == null ||params.isEmpty()) {returnURI.create(url);
}//设置请求参数
List parameters = new ArrayList(params.size());for (Map.Entryentry : params.entrySet()) {
parameters.add(newBasicNameValuePair(entry.getKey(), entry.getValue()));
}try{return newURIBuilder(url)
.addParameters(parameters)
.setCharset(Charset.forName(charsetName))
.build();
}catch(URISyntaxException e) {
String errorMsg= "Build request URI error, the url is [" + url + "].";
logger.error(errorMsg, e);throw newIOException(errorMsg, e);
}
}/***@seePCIHttpClient.com.bestpay.pgw.tools.http.PGWHttpClient#sendGet(java.lang.String, java.util.Map, java.util.Map, java.lang.String, int)*/@Overridepublic PCIHttpResponse sendGet(String url, Mapheaders,
Map params, String charsetName, inttimeout)throwsIOException {if(StringUtils.isEmpty(url)) {
logger.error("The url can not be null.");throw new IllegalArgumentException("The url can not be null.");
}returnsendAndResponseAsStream(newHttpGet(createURI(url, params, charsetName)), headers, timeout);
}/***@seePCIHttpClient.com.bestpay.pgw.tools.http.PGWHttpClient#sendPost(java.lang.String, java.util.Map, java.util.Map, java.lang.Object, java.lang.String, int)*/@Overridepublic PCIHttpResponse sendPost(String url, Mapheaders,
Mapparams, Object stringOrStream,
String charsetName,int timeout) throwsIOException {if(StringUtils.isEmpty(url)) {
logger.error("The url can not be null.");throw new IllegalArgumentException("The url can not be null.");
}//post请求方式
HttpPost method = newHttpPost(createURI(url, params, charsetName));//设置请求头信息
if (headers == null) {
headers= new HashMap();
}if (!headers.containsKey(CONTENT_TYPE)) {
headers.put(CONTENT_TYPE, DEFAULT_CONTENTTYPE);
}//设置请求体内容
if (stringOrStream != null) {
HttpEntity entity= null;if (stringOrStream instanceofInputStream) {
entity= newInputStreamEntity((InputStream) stringOrStream);
}else{
entity= newStringEntity(stringOrStream.toString(),
ContentType.create(CONTENT_TYPE, charsetName));
}
method.setEntity(entity);
}//发送请求数据,并接收响应数据
returnsendAndResponseAsStream(method, headers, timeout);
}/*** 发送请求数据,并接收响应数据
*
*@parammethod 请求方式
*@paramheaders 请求头信息
*@paramtimeout 超时时间
*@return*@throwsIOException
*
*@since2.0.0*/
privatePCIHttpResponse sendAndResponseAsStream(HttpRequestBase method,
Map headers, int timeout) throwsIOException {//设置请求配置信息
RequestConfig config =RequestConfig.custom()
.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT)//连接超时时间
.setSocketTimeout(timeout) //读取超时时间
.setCircularRedirectsAllowed(true) //设置是否允许循环重定向(重定向到相同路径)
.build();
method.setConfig(config);//设置请求头信息
if (headers == null) {
headers= new HashMap();
}if (!headers.containsKey(USER_AGENT)) {
headers.put(USER_AGENT, DEFAULT_USERAGENT);
}for (Map.Entryentry : headers.entrySet()) {
method.setHeader(entry.getKey(), entry.getValue());
}//发送请求
CloseableHttpClient httpClient =createHttpClient(method.getURI());
CloseableHttpResponse httpResponse= null;
InputStream responseBodyInputStream= null;
ByteArrayOutputStream responseBodyOutputStream= null;try{
httpResponse=httpClient.execute(method);int status =httpResponse.getStatusLine().getStatusCode();if (status !=HttpStatus.SC_OK) {
String errorMsg= CustomStringUtils.append("The remote service[",
method.getURI(),"] respose an error status:", status);
logger.error(errorMsg);if (status >= 500 && status < 600) {throw newIOException(errorMsg);
}
}//获取响应头
Map responseHeaders = null;
Header[] httpHeaders=httpResponse.getAllHeaders();if (httpHeaders != null && httpHeaders.length > 0) {
responseHeaders= new HashMap(httpHeaders.length);for(Header header : httpHeaders) {
responseHeaders.put(header.getName(), header.getValue());
}
}//获取响应体
byte[] responseBody = null;
HttpEntity httpEntity=httpResponse.getEntity();if (httpEntity != null) {
responseBodyInputStream=httpEntity.getContent();if (responseBodyInputStream != null) {
responseBodyOutputStream= newByteArrayOutputStream();
IOUtils.copy(responseBodyInputStream, responseBodyOutputStream);
responseBody=responseBodyOutputStream.toByteArray();
}else{
logger.warn(CustomStringUtils.append("The remote service[",
method.getURI(),"] respose entity content is null. status:", status));
}
}else{
logger.warn(CustomStringUtils.append("The remote service[",
method.getURI(),"] respose entity is null. status:", status));
}return newPCIHttpResponse(responseHeaders, responseBody);
}catch(IOException e) {
logger.error("Access to the remote service[" + method.getURI() + "] error.", e);throwe;
}finally{
IOUtils.closeQuietly(responseBodyInputStream);
IOUtils.closeQuietly(responseBodyOutputStream);//method.releaseConnection();
IOUtils.closeQuietly(httpResponse);
IOUtils.closeQuietly(httpClient);
}
}
}