| package com.jzq.common.http; | 
|   | 
| import com.alibaba.fastjson.JSONObject; | 
| import com.jzq.common.CommonUtil; | 
| import com.jzq.common.ResultInfo; | 
| import com.jzq.common.exception.ResultInfoException; | 
| import org.apache.commons.lang3.StringUtils; | 
| import org.apache.http.*; | 
| import org.apache.http.client.HttpRequestRetryHandler; | 
| import org.apache.http.client.config.RequestConfig; | 
| import org.apache.http.client.entity.UrlEncodedFormEntity; | 
| import org.apache.http.client.methods.CloseableHttpResponse; | 
| import org.apache.http.client.methods.HttpGet; | 
| import org.apache.http.client.methods.HttpPost; | 
| import org.apache.http.client.methods.HttpRequestBase; | 
| import org.apache.http.client.utils.URIBuilder; | 
| import org.apache.http.config.ConnectionConfig; | 
| import org.apache.http.config.Registry; | 
| import org.apache.http.config.RegistryBuilder; | 
| import org.apache.http.conn.socket.ConnectionSocketFactory; | 
| import org.apache.http.conn.socket.PlainConnectionSocketFactory; | 
| import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | 
| import org.apache.http.conn.ssl.TrustSelfSignedStrategy; | 
| import org.apache.http.entity.ContentType; | 
| import org.apache.http.entity.mime.MultipartEntityBuilder; | 
| import org.apache.http.entity.mime.content.ByteArrayBody; | 
| import org.apache.http.entity.mime.content.FileBody; | 
| import org.apache.http.entity.mime.content.InputStreamBody; | 
| import org.apache.http.entity.mime.content.StringBody; | 
| import org.apache.http.impl.client.CloseableHttpClient; | 
| import org.apache.http.impl.client.HttpClients; | 
| import org.apache.http.impl.client.LaxRedirectStrategy; | 
| import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | 
| import org.apache.http.message.BasicHeader; | 
| import org.apache.http.message.BasicNameValuePair; | 
| import org.apache.http.protocol.ExecutionContext; | 
| import org.apache.http.protocol.HttpContext; | 
| import org.apache.http.ssl.SSLContexts; | 
| import org.apache.http.util.EntityUtils; | 
| import org.slf4j.Logger; | 
| import org.slf4j.LoggerFactory; | 
|   | 
| import javax.net.ssl.SSLContext; | 
| import javax.net.ssl.SSLException; | 
| import javax.net.ssl.TrustManager; | 
| import javax.net.ssl.X509TrustManager; | 
| import java.io.File; | 
| import java.io.IOException; | 
| import java.io.InterruptedIOException; | 
| import java.io.UnsupportedEncodingException; | 
| import java.net.ConnectException; | 
| import java.net.URI; | 
| import java.net.URISyntaxException; | 
| import java.net.UnknownHostException; | 
| import java.nio.charset.CodingErrorAction; | 
| import java.security.KeyManagementException; | 
| import java.security.KeyStore; | 
| import java.security.KeyStoreException; | 
| import java.security.NoSuchAlgorithmException; | 
| import java.security.cert.CertificateException; | 
| import java.security.cert.X509Certificate; | 
| import java.util.ArrayList; | 
| import java.util.List; | 
| import java.util.Map; | 
|   | 
| /** | 
|  * http的请求服务类 | 
|  * 也可以考虑使用spring restTemplate调用 | 
|  */ | 
| public class HttpClientUtils { | 
|     public static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); | 
|     private static Object objTg = new Object(); | 
|     private static HttpClientUtils httpClientUtils; | 
|     /** | 
|      * 默认连接超时时间 | 
|      */ | 
|     private final static int DEFAULT_CONN_TIMEOUT = 6000; | 
|     /**最大重试次数*/ | 
|     private final static int DEFAULT_RETRY_TIMES = 3; | 
|   | 
|     private CloseableHttpClient client; | 
|   | 
|     /** | 
|      * ssl trust管理 | 
|      */ | 
|     public static class SSLTrustAllManager implements X509TrustManager { | 
|         @Override | 
|         public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { | 
|         } | 
|         @Override | 
|         public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { | 
|         } | 
|         @Override | 
|         public X509Certificate[] getAcceptedIssuers() { | 
|             return null; | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 初始化ssl管理 | 
|      * @return | 
|      * @throws KeyStoreException | 
|      * @throws CertificateException | 
|      * @throws NoSuchAlgorithmException | 
|      * @throws IOException | 
|      * @throws KeyManagementException | 
|      */ | 
|     private SSLConnectionSocketFactory initSSLConnectionSocketFactory() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, KeyManagementException { | 
|         KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); | 
|         trustStore.load(null, null); | 
|         SSLContext sslcontext = SSLContexts.custom() | 
|                 .loadTrustMaterial(trustStore, | 
|                         new TrustSelfSignedStrategy()) | 
|                 .build(); | 
|         sslcontext.init(null, new TrustManager[] { new SSLTrustAllManager() }, null); | 
|         SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( | 
|                 sslcontext, | 
|                 //new String[] { "TLSv1","TLSv1.1","TLSv1.2","SSLv3"},//参考ProtocolVersion//这里写为null为所有 | 
|                 null, | 
|                 null, | 
|                 SSLConnectionSocketFactory.getDefaultHostnameVerifier()); | 
|         return sslsf; | 
|     } | 
|   | 
|   | 
|     public HttpClientUtils() throws Exception { | 
|         // 设置协议http和https对应的处理socket链接工厂的对象 | 
|         Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() | 
|                 .register("http", PlainConnectionSocketFactory.INSTANCE) | 
|                 .register("https", initSSLConnectionSocketFactory()) | 
|                 .build(); | 
|         PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); | 
|         connManager.setValidateAfterInactivity(1000); | 
|         ConnectionConfig connectionConfig = ConnectionConfig.custom() | 
|                 .setMalformedInputAction(CodingErrorAction.IGNORE) | 
|                 .setUnmappableInputAction(CodingErrorAction.IGNORE) | 
|                 .setCharset(Consts.UTF_8) | 
|                 .build(); | 
|         connManager.setDefaultConnectionConfig(connectionConfig); | 
|         connManager.setMaxTotal(100); | 
|         connManager.setDefaultMaxPerRoute(10);//最大路由深度,即301次数 | 
|   | 
|         //默认头信息,创建自定义的httpclient对象 | 
|         List<Header> defaultHeaders=new ArrayList<Header>(); | 
|         defaultHeaders.add(new BasicHeader("Accept","text/html,application/xhtml+xml,application/xml,application/json;q=0.9,*/*;q=0.8")); | 
|         defaultHeaders.add(new BasicHeader("Accept-Language","zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2")); | 
|         defaultHeaders.add(new BasicHeader("Connection","close")); | 
|         defaultHeaders.add(new BasicHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0")); | 
|         //默认请求配置 | 
|         RequestConfig requestConfig = RequestConfig.custom() | 
|                 .setSocketTimeout(DEFAULT_CONN_TIMEOUT) | 
|                 .setConnectTimeout(DEFAULT_CONN_TIMEOUT) | 
|                 //.setProxy(new HttpHost("myotherproxy", 8080)) //设置代理 | 
|                 .setConnectionRequestTimeout(DEFAULT_CONN_TIMEOUT).build(); | 
|         //重试拦截 | 
|         HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() { | 
|             @Override | 
|             public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { | 
|                 if (executionCount >= DEFAULT_RETRY_TIMES) { | 
|                     //Do not retry if over max retry count | 
|                     return false; | 
|                 } | 
|                 if (exception instanceof InterruptedIOException) { | 
|                     // Timeout | 
|                     return false; | 
|                 } | 
|                 if (exception instanceof UnknownHostException) { | 
|                     // Unknown host | 
|                     return false; | 
|                 } | 
|                 if (exception instanceof ConnectException) { | 
|                     // Connection refused | 
|                     return false; | 
|                 } | 
|                 if (exception instanceof SSLException) { | 
|                     // SSL handshake exception | 
|                     return false; | 
|                 } | 
|                 HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST); | 
|                 boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); | 
|                 if (idempotent) { | 
|                     return true; | 
|                 } | 
|                 return false; | 
|             } | 
|         }; | 
|   | 
|         client = HttpClients.custom() | 
|                 .setConnectionManager(connManager) | 
|                 .setDefaultHeaders(defaultHeaders) | 
|                 .setDefaultRequestConfig(requestConfig) | 
|                 .setRetryHandler(myRetryHandler) | 
|                 .setRedirectStrategy(new LaxRedirectStrategy()) | 
|                 .build(); | 
|     } | 
|     /** | 
|      * init实例 | 
|      * @return | 
|      */ | 
|     public static HttpClientUtils init(){ | 
|         synchronized (objTg) { | 
|             if (httpClientUtils == null) { | 
|                 try { | 
|                     httpClientUtils = new HttpClientUtils(); | 
|                 } catch (Exception e) { | 
|                     throw new ResultInfoException("ACCESS_SIGN_ERROR","httpClient初始化出错",e); | 
|                 } | 
|             } | 
|         } | 
|         return httpClientUtils; | 
|     } | 
|   | 
|   | 
|     /** | 
|      * 工具类,通过url和params 生成url地址 | 
|      * @param url | 
|      * @param params | 
|      * @return | 
|      * @throws URISyntaxException | 
|      */ | 
|     public static URI builderUrl(String url, Map<String, Object> params){ | 
|         URIBuilder builder = null; | 
|         try { | 
|             builder = new URIBuilder(url); | 
|             if(params!=null&¶ms.size()>0){ | 
|                 for(String key: params.keySet()){ | 
|                     Object obj=params.get(key); | 
|                     if(obj==null){continue;} | 
|                     builder.setParameter(key, CommonUtil.parValNoErr(obj, String.class)); | 
|                 } | 
|             } | 
|             return builder.build(); | 
|         } catch (URISyntaxException e) { | 
|            throw new ResultInfoException("HTTP_URL_FORMART","转换地址出错:"+url,e); | 
|         } | 
|     } | 
|   | 
|     public static void fillHeader(HttpRequestBase request, Map<String, Object> heads){ | 
|         //请求头 | 
|         if (heads != null && heads.size() > 0) { | 
|             for (String key : heads.keySet()) { | 
|                 request.addHeader(key, heads.get(key) + ""); | 
|             } | 
|         } | 
|     } | 
|     /** | 
|      * get请求 | 
|      * @param uri | 
|      * @param heads | 
|      * @param params | 
|      * @return | 
|      * @throws Exception | 
|      */ | 
|     public String getGet(String uri, Map<String, Object> heads, Map<String, Object> params) { | 
|         HttpGet request = new HttpGet(builderUrl(uri,params)); | 
|         fillHeader(request,heads); | 
|         CloseableHttpResponse response = null; | 
|         try { | 
|             response = client.execute(request); | 
|             if (response.getStatusLine().getStatusCode() == 200) { | 
|                 // 获得返回的字符串 | 
|                 String result = EntityUtils.toString(response.getEntity(), "UTF-8"); | 
|                 return result; | 
|             } else { | 
|                 String result = EntityUtils.toString(response.getEntity(), "UTF-8"); | 
|                 result= StringUtils.isNotBlank(result)?result.substring(0,result.length()>200?200:result.length()) : ""; | 
|                 ResultInfo<String> res=new ResultInfo<String>(); | 
|                 res.setData(result); | 
|                 res.setSuccess(false); | 
|                 res.setResultCode(response.getStatusLine().getStatusCode()+""); | 
|                 throw new ResultInfoException("HTTP_RESPONSE_ERROR", JSONObject.toJSONString(res)); | 
|             } | 
|         } catch (IOException e) { | 
|             throw new ResultInfoException("EXCEPTION","网络请求失败",e); | 
|         } finally { | 
|             try { | 
|                 response.close(); | 
|             } catch (Exception e) {} | 
|         } | 
|     } | 
|   | 
|     public byte[] getGetByte(String uri, Map<String, Object> heads, Map<String, Object> params) { | 
|         HttpGet request = new HttpGet(builderUrl(uri,params)); | 
|         fillHeader(request,heads); | 
|         CloseableHttpResponse response = null; | 
|         try { | 
|             response = client.execute(request); | 
|             if (response.getStatusLine().getStatusCode() == 200) { | 
|                 // 获得返回的字符串 | 
|                 byte[] result = EntityUtils.toByteArray(response.getEntity()); | 
|                 return result; | 
|             } else { | 
|                 ResultInfo<String> res=new ResultInfo<String>(); | 
|                 res.setSuccess(false); | 
|                 res.setResultCode(response.getStatusLine().getStatusCode()+""); | 
|                 throw new ResultInfoException("HTTP_RESPONSE_ERROR", JSONObject.toJSONString(res)); | 
|             } | 
|         } catch (IOException e) { | 
|             throw new ResultInfoException("EXCEPTION","网络请求失败",e); | 
|         } finally { | 
|             try { | 
|                 response.close(); | 
|             } catch (Exception e) {} | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 直接获取返回体,注意要手动关闭response | 
|      * @param uri | 
|      * @param heads | 
|      * @param params | 
|      * @return | 
|      */ | 
|     public CloseableHttpResponse getGetResponse(String uri, Map<String, Object> heads, Map<String, Object> params) throws IOException { | 
|         HttpGet request = new HttpGet(builderUrl(uri,params)); | 
|         fillHeader(request,heads); | 
|         CloseableHttpResponse response = null; | 
|         response = client.execute(request); | 
|         return response; | 
|     } | 
|   | 
|     /** | 
|      * 构建post的body信息, | 
|      * @param request | 
|      * @param params | 
|      * @param ifMutipart 是否启用富文件方式上传 | 
|      */ | 
|     private void buildPostBody(HttpPost request, Map<String, Object> params, boolean ifMutipart){ | 
|         if(ifMutipart){ | 
|             //富文本请求 | 
|             MultipartEntityBuilder meBuiler = MultipartEntityBuilder.create(); | 
|             if (params != null && params.size() > 0) { | 
|                 for (String key : params.keySet()) { | 
|                     Object obj = params.get(key); | 
|                     if(obj==null){ | 
|                         continue; | 
|                     }else if (obj instanceof File) { | 
|                         FileBody fb = new FileBody((File) obj); | 
|                         meBuiler.addPart(key, fb); | 
|                     } else if (obj instanceof ByteArrayBody) { | 
|                         meBuiler.addPart(key, (ByteArrayBody) obj); | 
|                     } else if (obj instanceof FileBody) { | 
|                         meBuiler.addPart(key, (FileBody) obj); | 
|                     } else if (obj instanceof InputStreamBody) { | 
|                         meBuiler.addPart(key, (InputStreamBody) obj); | 
|                     }else { | 
|                         StringBody sb = new StringBody(CommonUtil.parValNoErrDef(obj, String.class, ""), ContentType.create("text/plain", "UTF-8")); | 
|                         meBuiler.addPart(key, sb); | 
|                     } | 
|                 } | 
|             } | 
|             HttpEntity httpEntity = meBuiler.build(); | 
|             request.setEntity(httpEntity); | 
|         }else{ | 
|             //普通请求 | 
|             List<NameValuePair> pList = new ArrayList<NameValuePair>(); | 
|             if (params != null && params.size() > 0) { | 
|                 for (String key : params.keySet()) { | 
|                     Object obj=params.get(key); | 
|                     if(obj==null){continue;} | 
|                     pList.add(new BasicNameValuePair(key, obj + "")); | 
|                 } | 
|             } | 
|             try { | 
|                 request.setEntity(new UrlEncodedFormEntity(pList, "UTF-8")); | 
|             } catch (UnsupportedEncodingException e) { | 
|                 throw new ResultInfoException("HTTP_REQ_ENCODE_ERROR","请求参数格式化出错",e); | 
|             } | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * post的上传请求 | 
|      * @param uri | 
|      * @param heads | 
|      * @param params | 
|      * @return | 
|      * @throws Exception | 
|      */ | 
|     public String getPost(String uri, Map<String, Object> heads, Map<String, Object> params, boolean ifMutipart) { | 
|         HttpPost request = new HttpPost(uri); | 
|         fillHeader(request,heads); | 
|         buildPostBody(request,params,ifMutipart); | 
|         CloseableHttpResponse response = null; | 
|         try { | 
|             response = client.execute(request); | 
|             if (response.getStatusLine().getStatusCode() == 200) { | 
|                 // 获得返回的字符串 | 
|                 String result = EntityUtils.toString(response.getEntity(), "UTF-8"); | 
|                 return result; | 
|             } else { | 
|                 String result = EntityUtils.toString(response.getEntity(), "UTF-8"); | 
|                 result= StringUtils.isNotBlank(result) ?result.substring(0,result.length()>200?200:result.length()) : ""; | 
|                 ResultInfo<String> res=new ResultInfo<String>(); | 
|                 res.setData(result); | 
|                 res.setSuccess(false); | 
|                 res.setResultCode(response.getStatusLine().getStatusCode()+""); | 
|                 throw new ResultInfoException("HTTP_RESPONSE_ERROR", JSONObject.toJSONString(res)); | 
|             } | 
|         } catch (IOException e) { | 
|             throw new ResultInfoException("HTTP_IO_ERROR","网络请求失败",e); | 
|         } finally { | 
|             try { | 
|                 response.close(); | 
|             } catch (Exception e) {} | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * post的上传请求,返回byte[] | 
|      * @param uri | 
|      * @param heads | 
|      * @param params | 
|      * @return | 
|      * @throws Exception | 
|      */ | 
|     public byte[] getPostByte(String uri, Map<String, Object> heads, Map<String, Object> params, boolean ifMutipart) { | 
|         HttpPost request = new HttpPost(uri); | 
|         fillHeader(request,heads); | 
|         buildPostBody(request,params,ifMutipart); | 
|         CloseableHttpResponse response = null; | 
|         try { | 
|             response = client.execute(request); | 
|             if (response.getStatusLine().getStatusCode() == 200) { | 
|                 // 获得返回的byte[] | 
|                 byte[] result = EntityUtils.toByteArray(response.getEntity()); | 
|                 return result; | 
|             } else { | 
|                 ResultInfo<String> res=new ResultInfo<String>(); | 
|                 res.setSuccess(false); | 
|                 res.setResultCode(response.getStatusLine().getStatusCode()+""); | 
|                 throw new ResultInfoException("HTTP_RESPONSE_ERROR", JSONObject.toJSONString(res)); | 
|             } | 
|         } catch (IOException e) { | 
|             throw new ResultInfoException("HTTP_IO_ERROR","网络请求失败",e); | 
|         } finally { | 
|             try { | 
|                 response.close(); | 
|             } catch (Exception e) {} | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * post的上传请求,返回CloseableHttpResponse,必须手动关闭 | 
|      * @param uri | 
|      * @param heads | 
|      * @param params | 
|      * @return | 
|      * @throws Exception | 
|      */ | 
|     public CloseableHttpResponse getPostResponse(String uri, Map<String, Object> heads, Map<String, Object> params, boolean ifMutipart) { | 
|         HttpPost request = new HttpPost(uri); | 
|         fillHeader(request,heads); | 
|         buildPostBody(request,params,ifMutipart); | 
|         CloseableHttpResponse response = null; | 
|         try { | 
|             response = client.execute(request); | 
|             if (response.getStatusLine().getStatusCode() == 200) { | 
|                 return response; | 
|             } else { | 
|                 String result = EntityUtils.toString(response.getEntity(), "UTF-8"); | 
|                 result= StringUtils.isNotBlank(result)?result.substring(0,result.length()>200?200:result.length()) : ""; | 
|                 ResultInfo<String> res=new ResultInfo<String>(); | 
|                 res.setData(result); | 
|                 res.setSuccess(false); | 
|                 res.setResultCode(response.getStatusLine().getStatusCode()+""); | 
|                 throw new ResultInfoException("HTTP_RESPONSE_ERROR", JSONObject.toJSONString(res)); | 
|             } | 
|         } catch (IOException e) { | 
|             throw new ResultInfoException("HTTP_IO_ERROR","网络请求失败",e); | 
|         } finally { | 
|             try { | 
|                 response.close(); | 
|             } catch (Exception e) {} | 
|         } | 
|     } | 
| } |