• Java httpclent请求httpclentUtils工具类


    第一种写法:

    import java.io.IOException;
    import java.io.InterruptedIOException;
    import java.io.UnsupportedEncodingException;
    import java.net.SocketTimeoutException;
    import java.net.URLEncoder;
    import java.net.UnknownHostException;
    import java.nio.charset.Charset;
    import java.security.KeyManagementException;
    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;
    
    import javax.activation.MimetypesFileTypeMap;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLException;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.http.Header;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpEntityEnclosingRequest;
    import org.apache.http.HttpHost;
    import org.apache.http.HttpRequest;
    import org.apache.http.NameValuePair;
    import org.apache.http.ParseException;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpRequestRetryHandler;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.config.RequestConfig.Builder;
    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.protocol.HttpClientContext;
    import org.apache.http.conn.ConnectTimeoutException;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.TrustStrategy;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.mime.MultipartEntityBuilder;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.protocol.HTTP;
    import org.apache.http.protocol.HttpContext;
    import org.apache.http.ssl.SSLContextBuilder;
    import org.apache.http.util.EntityUtils;
    
    import lombok.extern.slf4j.Slf4j;
    import net.dreamlu.common.entity.DownLoadFile;
    import net.sf.json.JSONObject;
    import net.sf.json.JsonConfig;
    import net.sf.json.util.PropertyFilter;
    
    
    @Slf4j
    public class HttpclientUtils implements IDictConst {
        private final static int    CONNECT_TIMEOUT            = 4000;        // 连接超时毫秒
        private final static int    SOCKET_TIMEOUT            = 30000;    // 传输超时毫秒
        private final static int    REQUESTCONNECT_TIMEOUT    = 3000;        // 获取请求超时毫秒
        private final static String    ENCODE_CHARSET            = "utf-8";    // 响应报文解码字符集
    
        static class RetryHandler implements HttpRequestRetryHandler {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                if (executionCount >= 3) {
                    // 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 ConnectTimeoutException) {
                    // Connection refused
                    return false;
                }
                if (exception instanceof SSLException) {
                    // SSL handshake exception
                    return false;
                }
                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                if (idempotent) {
                    // Retry if the request is considered idempotent
                    return true;
                }
                return false;
            }
    
        };
    
        public static CloseableHttpClient createSSLClientDefault(HttpHost proxy) {
            try {
                SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                    // 信任所有
                    @Override
                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        return true;
                    }
                }).build();
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
                HttpRequestRetryHandler retryHandler = new RetryHandler();
                Builder buider = RequestConfig.custom().setConnectionRequestTimeout(REQUESTCONNECT_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT);
                if (null != proxy) {
                    buider.setProxy(proxy);
                }
                RequestConfig requestConfig = buider.build();
                HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(requestConfig).setRetryHandler(retryHandler).build();
            } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
                log.error(e.getMessage(), e);
            }
            return HttpClients.createDefault();
        }
    
        public static String buildMap(Map<String, Object> map) {
            StringBuffer sb = new StringBuffer();
            if (map != null && map.size() > 0) {
                for (String key : map.keySet()) {
                    sb.append(key + "=");
                    if (null == map.get(key)) {
                        sb.append("&");
                    } else {
                        String value = String.valueOf(map.get(key));
                        try {
                            value = URLEncoder.encode(value, "UTF-8");
                        } catch (UnsupportedEncodingException e) {
                            log.error(e.getMessage(), e);
                        }
                        sb.append(value + "&");
                    }
                }
            }
            return sb.toString();
        }
    
        /**
         * 发送HTTP_GET请求
         *
         * @see 1)该方法会自动关闭连接,释放资源
         * @see 2)方法内设置了连接和读取超时时间,单位为毫秒,超时或发生其它异常时方法会自动返回"通信失败"字符串
         * @see 3)请求参数含中文时,经测试可直接传入中文,HttpClient会自动编码发给Server,应用时应根据实际效果决 定传入前是否转码
         * @see 4)该方法会自动获取到响应消息头中[Content-Type:text/html; charset=GBK]的charset值作为响应报文的 解码字符集
         * @see 5)若响应消息头中无Content-Type属性,则会使用HttpClient内部默认的ISO-8859-1作为响应报文的解码字符 集
         * @param reqURL 请求地址(含参数)
         * @return 远程主机响应正文 HttpHost proxy = new HttpHost("192.168.15.4", 3128);
         */
        public static JSONObject sendGetRequest(String reqURL, Map<String, Object> map, HttpHost proxy) {
            String param = buildMap(map);
            if (null != param) {
                reqURL += "?" + param;
            }
            JSONObject respContent = new JSONObject(); // 响应内容
    //         reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
            HttpGet httpget = new HttpGet(reqURL);
            httpget.setHeader("Connection", "close");
            CloseableHttpResponse response = null;
            try {
                response = createSSLClientDefault(proxy).execute(httpget, HttpClientContext.create()); // 执行GET请求
                HttpEntity entity = response.getEntity(); // 获取响应实体
                if (null != entity) {
                    Charset respCharset = Charset.forName(ENCODE_CHARSET);
                    respContent = JSONObject.fromObject(EntityUtils.toString(entity, respCharset), getJsonConfig());
                    log.info("发送get请求返回结果:{}", respContent);
                    EntityUtils.consume(entity);
                } else {
                    log.error("发送get请求返回错误:{}", response);
                }
            } catch (ConnectTimeoutException cte) {
                log.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
                respContent.put(CODE, -1000);
                respContent.put(MSG, cte.getMessage());
            } catch (SocketTimeoutException ste) {
                log.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
                respContent.put(CODE, -1000);
                respContent.put(MSG, ste.getMessage());
            } catch (ClientProtocolException cpe) {
                log.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, cpe.getMessage());
            } catch (ParseException pe) {
                log.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, pe.getMessage());
            } catch (IOException ioe) {
                log.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, ioe.getMessage());
            } catch (Exception e) {
                log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
                respContent.put(CODE, -1000);
                respContent.put(MSG, e.getMessage());
            } finally {
                try {
                    if (response != null)
                        response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (httpget != null) {
                    httpget.releaseConnection();
                }
            }
            return respContent;
        }
    
        /**
         * 将null值的字段去掉
         * 
         * @return
         */
        private static JsonConfig getJsonConfig() {
            JsonConfig jsonConfig = new JsonConfig();
            jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
                @Override
                public boolean apply(Object arg0, String arg1, Object arg2) {
                    return StringUtils.equals("null", String.valueOf(arg2));
                }
            });
            return jsonConfig;
        }
    
        /**
         * 发送HTTP_POST请求 type: 默认是表单请求,
         * 
         * @see 1)该方法允许自定义任何格式和内容的HTTP请求报文体
         * @see 2)该方法会自动关闭连接,释放资源
         * @see 3)方法内设置了连接和读取超时时间,单位为毫秒,超时或发生其它异常时方法会自动返回"通信失败"字符串
         * @see 4)请求参数含中文等特殊字符时,可直接传入本方法,并指明其编码字符集encodeCharset参数,方法内部会自 动对其转码
         * @see 5)该方法在解码响应报文时所采用的编码,取自响应消息头中的[Content-Type:text/html; charset=GBK]的 charset值
         * @see 6)若响应消息头中未指定Content-Type属性,则会使用HttpClient内部默认的ISO-8859-1
         * @param reqURL 请求地址
         * @param param 请求参数,若有多个参数则应拼接为param11=value11&22=value22&33=value33的形式
         * @param type 编码字符集,编码请求数据时用之,此参数为必填项(不能为""或null)
         * @return 远程主机响应正文
         */
        public static JSONObject sendPostRequest(String reqURL, Map<String, Object> map, String type, HttpHost proxy) {
            JSONObject respContent = new JSONObject();
            // 设置请求和传输超时时间
            HttpPost httpPost = new HttpPost(reqURL);
            httpPost.setHeader("Connection", "close");
            // 这就有可能会导致服务端接收不到POST过去的参数,比如运行在Tomcat6.0.36中的Servlet,所以我们手工指定CONTENT_TYPE头消息
            if (type != null && type.length() > 0) {
                httpPost.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=" + ENCODE_CHARSET);
            } else {
                httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=" + ENCODE_CHARSET);
            }
            CloseableHttpResponse response = null;
            try {
                // 判断map不为空
                if (map != null) {
                    // 声明存放参数的List集合
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    // 遍历map,设置参数到list中
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        if (null != entry.getValue()) {
                            params.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
                        }
                    }
                    // 创建form表单对象
                    UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, ENCODE_CHARSET);
                    formEntity.setContentType("Content-Type:application/json");
                    // 把表单对象设置到httpPost中
                    httpPost.setEntity(formEntity);
                }
                // reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
                response = createSSLClientDefault(proxy).execute(httpPost, HttpClientContext.create());
                HttpEntity entity = response.getEntity();
                if (null != entity) {
                    respContent = JSONObject.fromObject(EntityUtils.toString(entity, Charset.forName(ENCODE_CHARSET)), getJsonConfig());
                    log.info("发送post请求返回结果:{}", respContent);
                    EntityUtils.consume(entity);
                } else {
                    log.error("发送post请求返回错误:{}", response);
                }
            } catch (ConnectTimeoutException cte) {
                log.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
                respContent.put(CODE, -1000);
                respContent.put(MSG, cte.getMessage());
            } catch (SocketTimeoutException ste) {
                log.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
                respContent.put(CODE, -1000);
                respContent.put(MSG, ste.getMessage());
            } catch (ClientProtocolException cpe) {
                log.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, cpe.getMessage());
            } catch (ParseException pe) {
                log.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, pe.getMessage());
            } catch (IOException ioe) {
                log.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, ioe.getMessage());
            } catch (Exception e) {
                log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
                respContent.put(CODE, -1000);
                respContent.put(MSG, e.getMessage());
            } finally {
                try {
                    if (response != null)
                        response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (httpPost != null) {
                    httpPost.releaseConnection();
                }
            }
            return respContent;
        }
    
        public static String getContentType(String filename) {
            String contentType = null;
            try {
                contentType = new MimetypesFileTypeMap().getContentType(filename);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return contentType;
        }
    
        /**
         * 上传文件功能
         * 
         * @param reqURL
         * @param b
         * @param filename
         * @param map
         * @param type
         * @return
         */
        public static JSONObject sendPostFileRequest(String reqURL, byte[] b, String filename, Map<String, Object> map, HttpHost proxy) {
            JSONObject respContent = new JSONObject();
            HttpPost httpPost = new HttpPost(reqURL);
            httpPost.setHeader("Connection", "close");
            CloseableHttpResponse response = null;
            try {
                // 判断map不为空
                if (map != null) {
                    MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
                    multipartEntityBuilder.setCharset(Charset.forName(ENCODE_CHARSET));
                    multipartEntityBuilder.addBinaryBody("file", b, ContentType.create(getContentType(filename)), filename);
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        multipartEntityBuilder.addTextBody(entry.getKey(), String.valueOf(entry.getValue()));
                    }
                    HttpEntity httpEntity = multipartEntityBuilder.build();
                    httpPost.setEntity(httpEntity);
                }
                // reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
                response = createSSLClientDefault(proxy).execute(httpPost, HttpClientContext.create());
                HttpEntity entity = response.getEntity();
                if (null != entity) {
                    respContent = JSONObject.fromObject(EntityUtils.toString(entity, Charset.forName(ENCODE_CHARSET)), getJsonConfig());
                    log.info("发送post请求返回结果:{}", respContent);
                    EntityUtils.consume(entity);
                } else {
                    log.error("发送post请求返回错误:{}", response);
                }
            } catch (ConnectTimeoutException cte) {
                log.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
                respContent.put(CODE, -1000);
                respContent.put(MSG, cte.getMessage());
            } catch (SocketTimeoutException ste) {
                log.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
                respContent.put(CODE, -1000);
                respContent.put(MSG, ste.getMessage());
            } catch (ClientProtocolException cpe) {
                log.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, cpe.getMessage());
            } catch (ParseException pe) {
                log.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, pe.getMessage());
            } catch (IOException ioe) {
                log.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
                respContent.put(CODE, -1000);
                respContent.put(MSG, ioe.getMessage());
            } catch (Exception e) {
                log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
                respContent.put(CODE, -1000);
                respContent.put(MSG, e.getMessage());
            } finally {
                try {
                    if (response != null)
                        response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (httpPost != null) {
                    httpPost.releaseConnection();
                }
            }
            return respContent;
        }
    
        /**
         * 上传文件功能
         * 
         * @param reqURL
         * @param b
         * @param filename
         * @param map
         * @param type
         * @return
         */
        public static DownLoadFile downFileRequest(String reqURL, Map<String, Object> map, HttpHost proxy) {
            DownLoadFile respContent = new DownLoadFile();
            HttpPost httpPost = new HttpPost(reqURL);
            httpPost.setHeader("Connection", "close");
            CloseableHttpResponse response = null;
            try {
                // 判断map不为空
                if (map != null) {
                    // 声明存放参数的List集合
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    // 遍历map,设置参数到list中
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        if (null != entry.getValue()) {
                            params.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
                        }
                    }
                    // 创建form表单对象
                    UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, ENCODE_CHARSET);
                    formEntity.setContentType("Content-Type:application/json");
                    // 把表单对象设置到httpPost中
                    httpPost.setEntity(formEntity);
                }
                // reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
                response = createSSLClientDefault(proxy).execute(httpPost, HttpClientContext.create());
                int code = response.getStatusLine().getStatusCode();
                if (code == 302) {
                    Header header = response.getFirstHeader("location"); // 跳转的目标地址是在 HTTP-HEAD上
                    String newuri = header.getValue(); // 这就是跳转后的地址,再向这个地址发出新申请
                    httpPost = new HttpPost(newuri);
                    httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
                    response = createSSLClientDefault(proxy).execute(httpPost, HttpClientContext.create());
                    code = response.getStatusLine().getStatusCode();
                    if (code == 200) {
                        respContent.setFileName(StringUtils.substringAfterLast(newuri, "/"));
                        HttpEntity entity = response.getEntity();
                        if (null != entity) {
                            respContent.setFileContent(EntityUtils.toByteArray(entity));
                            EntityUtils.consume(entity);
                        } else {
                            log.error("发送post请求返回错误:{}", response);
                        }
                    }
                } else if (code == 200) {
                    Header header = response.getFirstHeader("location"); // 跳转的目标地址是在 HTTP-HEAD上
                    String newuri = header.getValue();
                    HttpEntity entity = response.getEntity();
                    if (null != entity) {
                        respContent.setFileName(StringUtils.substringAfterLast(newuri, "/"));
                        respContent.setFileContent(EntityUtils.toByteArray(entity));
                        EntityUtils.consume(entity);
                    } else {
                        log.error("发送post请求返回错误:{}", response);
                    }
                }
            } catch (ConnectTimeoutException cte) {
                log.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
            } catch (SocketTimeoutException ste) {
                log.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
            } catch (ClientProtocolException cpe) {
                log.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
            } catch (ParseException pe) {
                log.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
            } catch (IOException ioe) {
                log.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
            } catch (Exception e) {
                log.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
            } finally {
                try {
                    if (response != null)
                        response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (httpPost != null) {
                    httpPost.releaseConnection();
                }
            }
            return respContent;
        }
    }

    第二种写法;

    import java.io.IOException;
    import java.io.InterruptedIOException;
    import java.net.SocketTimeoutException;
    import java.net.UnknownHostException;
    import java.nio.charset.Charset;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLException;
    import javax.net.ssl.SSLHandshakeException;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.http.Header;
    import org.apache.http.HeaderElement;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpEntityEnclosingRequest;
    import org.apache.http.HttpHeaders;
    import org.apache.http.HttpHost;
    import org.apache.http.HttpRequest;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.NoHttpResponseException;
    import org.apache.http.ParseException;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpRequestRetryHandler;
    import org.apache.http.client.config.RequestConfig;
    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.protocol.HttpClientContext;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.config.SocketConfig;
    import org.apache.http.conn.ConnectTimeoutException;
    import org.apache.http.conn.routing.HttpRoute;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.entity.ByteArrayEntity;
    import org.apache.http.entity.ContentType;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.pool.PoolStats;
    import org.apache.http.protocol.HTTP;
    import org.apache.http.protocol.HttpContext;
    import org.apache.http.util.EntityUtils;
    import org.apache.poi.util.IOUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.sinoeyes.common.IDictConst;
    import com.sinoeyes.web.entity.achieve.DownLoadFile;
    
    import net.sf.json.JSONObject;
    
    public class HttpClientUtil implements IDictConst {
    	private static Logger								logger					= LoggerFactory.getLogger(HttpClientUtil.class);
    	private final static int							CONNECT_TIMEOUT			= 4000;											// 连接超时毫秒
    	private final static int							SOCKET_TIMEOUT			= 30000;										// 传输超时毫秒
    	private final static int							SOCKET_TIMEOUT_DELAY	= 180000;										// 最长传输超时毫秒
    	private final static int							REQUESTCONNECT_TIMEOUT	= 3000;											// 获取请求超时毫秒
    	private final static int							CONNECT_TOTAL			= 800;											// 最大连接数
    	private final static int							CONNECT_ROUTE			= 800;											// 每个路由基础的连接数
    	private final static String							ENCODE_CHARSET			= "utf-8";										// 响应报文解码字符集
    	private final static String							RESP_CONTENT			= "通信失败";
    	public static PoolingHttpClientConnectionManager	connManager				= null;
    	private static CloseableHttpClient					httpClient				= null;
    	static {
    		ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
    		LayeredConnectionSocketFactory sslsf = createSSLConnSocketFactory();
    		Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", plainsf).register("https", sslsf).build();
    		connManager = new PoolingHttpClientConnectionManager(registry);
    		// 将最大连接数增加到200
    		connManager.setMaxTotal(CONNECT_TOTAL);
    		// 将每个路由基础的连接增加到20
    		connManager.setDefaultMaxPerRoute(CONNECT_ROUTE);
    		// 可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立
    		connManager.setValidateAfterInactivity(30000);
    		// 设置socket超时时间
    		SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(SOCKET_TIMEOUT).build();
    		connManager.setDefaultSocketConfig(socketConfig);
    
    		RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(REQUESTCONNECT_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT)
    				.build();
    		HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
    			@Override
    			public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
    				if (executionCount >= 3) {// 如果已经重试了3次,就放弃
    					return false;
    				}
    				if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
    					return true;
    				}
    				if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
    					return false;
    				}
    				if (exception instanceof InterruptedIOException) {// 超时
    					return true;
    				}
    				if (exception instanceof UnknownHostException) {// 目标服务器不可达
    					return false;
    				}
    				if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
    					return false;
    				}
    				if (exception instanceof SSLException) {// ssl握手异常
    					return false;
    				}
    				HttpClientContext clientContext = HttpClientContext.adapt(context);
    				HttpRequest request = clientContext.getRequest();
    				// 如果请求是幂等的,就再次尝试
    				if (!(request instanceof HttpEntityEnclosingRequest)) {
    					return true;
    				}
    				return false;
    			}
    		};
    		httpClient = HttpClients.custom().setConnectionManager(connManager).setDefaultRequestConfig(requestConfig).setRetryHandler(httpRequestRetryHandler).build();
    		if (connManager != null && connManager.getTotalStats() != null) {
    			logger.info("now client pool " + connManager.getTotalStats().toString());
    		}
    	}
    
    	/**
    	 * 发送HTTP_GET请求
    	 *
    	 * @see 1)该方法会自动关闭连接,释放资源
    	 * @see 2)方法内设置了连接和读取超时时间,单位为毫秒,超时或发生其它异常时方法会自动返回"通信失败"字符串
    	 * @see 3)请求参数含中文时,经测试可直接传入中文,HttpClient会自动编码发给Server,应用时应根据实际效果决 定传入前是否转码
    	 * @see 4)该方法会自动获取到响应消息头中[Content-Type:text/html; charset=GBK]的charset值作为响应报文的 解码字符集
    	 * @see 5)若响应消息头中无Content-Type属性,则会使用HttpClient内部默认的ISO-8859-1作为响应报文的解码字符 集
    	 * @param reqURL 请求地址(含参数)
    	 * @return 远程主机响应正文
    	 */
    	public static String sendGetRequest(String reqURL, String param) {
    		if (null != param) {
    			reqURL += "?" + param;
    		}
    		String respContent = RESP_CONTENT; // 响应内容
    // reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
    		HttpGet httpget = new HttpGet(reqURL);
    		CloseableHttpResponse response = null;
    		try {
    			response = httpClient.execute(httpget, HttpClientContext.create()); // 执行GET请求
    			HttpEntity entity = response.getEntity(); // 获取响应实体
    			if (null != entity) {
    				Charset respCharset = ContentType.getOrDefault(entity).getCharset();
    				respContent = EntityUtils.toString(entity, respCharset);
    				EntityUtils.consume(entity);
    			}
    		} catch (ConnectTimeoutException cte) {
    			logger.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
    		} catch (SocketTimeoutException ste) {
    			logger.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
    		} catch (ClientProtocolException cpe) {
    // 该异常通常是协议错误导致:比如构造HttpGet对象时传入协议不对(将'http'写成'htp')or响应内容不符合HTTP协议要求等
    			logger.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
    		} catch (ParseException pe) {
    			logger.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
    		} catch (IOException ioe) {
    // 该异常通常是网络原因引起的,如HTTP服务器未启动等
    			logger.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
    		} catch (Exception e) {
    			logger.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
    		} finally {
    			try {
    				if (response != null)
    					response.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    			if (httpget != null) {
    				httpget.releaseConnection();
    			}
    		}
    		return respContent;
    	}
    
    	public static String sendPostRequest(String reqURL, String param) throws IOException {
    		return sendPostRequest(reqURL, param, "");
    	}
    
    	/**
    	 * 发送HTTP_POST请求 type: 默认是表单请求,
    	 * 
    	 * @see 1)该方法允许自定义任何格式和内容的HTTP请求报文体
    	 * @see 2)该方法会自动关闭连接,释放资源
    	 * @see 3)方法内设置了连接和读取超时时间,单位为毫秒,超时或发生其它异常时方法会自动返回"通信失败"字符串
    	 * @see 4)请求参数含中文等特殊字符时,可直接传入本方法,并指明其编码字符集encodeCharset参数,方法内部会自 动对其转码
    	 * @see 5)该方法在解码响应报文时所采用的编码,取自响应消息头中的[Content-Type:text/html; charset=GBK]的 charset值
    	 * @see 6)若响应消息头中未指定Content-Type属性,则会使用HttpClient内部默认的ISO-8859-1
    	 * @param reqURL 请求地址
    	 * @param param 请求参数,若有多个参数则应拼接为param11=value11&22=value22&33=value33的形式
    	 * @param type 编码字符集,编码请求数据时用之,此参数为必填项(不能为""或null)
    	 * @return 远程主机响应正文
    	 */
    	public static String sendPostRequest(String reqURL, String param, String type) {
    		String result = RESP_CONTENT;
    		// 设置请求和传输超时时间
    		HttpPost httpPost = new HttpPost(reqURL);
    		// 这就有可能会导致服务端接收不到POST过去的参数,比如运行在Tomcat6.0.36中的Servlet,所以我们手工指定CONTENT_TYPE头消息
    		if (type != null && type.length() > 0) {
    			httpPost.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=" + ENCODE_CHARSET);
    		} else {
    			httpPost.setHeader(HTTP.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=" + ENCODE_CHARSET);
    		}
    		CloseableHttpResponse response = null;
    		try {
    			if (param != null) {
    				StringEntity entity = new StringEntity(param, ENCODE_CHARSET);
    				httpPost.setEntity(entity);
    			}
    			logger.info("开始执行请求:" + reqURL);
    			// reqURL = URLDecoder.decode(reqURL, ENCODE_CHARSET);
    			response = httpClient.execute(httpPost, HttpClientContext.create());
    			HttpEntity entity = response.getEntity();
    			if (null != entity) {
    				result = EntityUtils.toString(entity, ContentType.getOrDefault(entity).getCharset());
    				logger.info("执行请求完毕:" + result);
    				EntityUtils.consume(entity);
    			}
    		} catch (ConnectTimeoutException cte) {
    			logger.error("请求通信[" + reqURL + "]时连接超时,堆栈轨迹如下", cte);
    		} catch (SocketTimeoutException ste) {
    			logger.error("请求通信[" + reqURL + "]时读取超时,堆栈轨迹如下", ste);
    		} catch (ClientProtocolException cpe) {
    			logger.error("请求通信[" + reqURL + "]时协议异常,堆栈轨迹如下", cpe);
    		} catch (ParseException pe) {
    			logger.error("请求通信[" + reqURL + "]时解析异常,堆栈轨迹如下", pe);
    		} catch (IOException ioe) {
    			logger.error("请求通信[" + reqURL + "]时网络异常,堆栈轨迹如下", ioe);
    		} catch (Exception e) {
    			logger.error("请求通信[" + reqURL + "]时偶遇异常,堆栈轨迹如下", e);
    		} finally {
    			try {
    				if (response != null)
    					response.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    			if (httpPost != null) {
    				httpPost.releaseConnection();
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * 上传文件
    	 * 
    	 * @param url
    	 * @param bodyBytes
    	 * @param boundary
    	 * @return
    	 * @throws ClientProtocolException
    	 * @throws IOException
    	 */
    	public static JSONObject uploadFile(String url, byte[] bodyBytes, String boundary) throws ClientProtocolException, IOException {
    		if (null != connManager) {
    			connManager.closeExpiredConnections();
    			connManager.closeIdleConnections(180L, TimeUnit.SECONDS);
    		}
    		JSONObject result = new JSONObject();
    		HttpPost post = new HttpPost(url);
    		post.setHeader(HttpHeaders.CONNECTION, "close");
    		RequestConfig requestConfig = doProxy(true, false);
    		post.setConfig(requestConfig);
    		post.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
    		post.setEntity(new ByteArrayEntity(bodyBytes));
    		CloseableHttpResponse response = null;
    		try {
    			response = httpClient.execute(post);
    			int code = response.getStatusLine().getStatusCode();
    			if (code == 200) {
    				HttpEntity entity = response.getEntity();
    				byte[] entityByte = EntityUtils.toByteArray(entity);
    				byte[] entityStr = AesUtil.decrypt(entityByte);
    				EntityUtils.consume(entity);
    				if (null != entityStr && entityStr.length > 0) {// 正常解密
    					result = JSONObject.fromObject(new String(entityStr, ENCODE_CHARSET));
    				} else {
    					// 解密失败
    					String s = new String(entityByte, ENCODE_CHARSET);
    					if (StringUtils.isNotBlank(s) && StringUtils.startsWith(s, "{")) {
    						result = JSONObject.fromObject(s);
    					} else {
    						result.put(ERROR_CODE, ERROR_EXCEPTION);
    						result.put(ERROR_MESSAGE, s);
    					}
    				}
    				return result;
    			} else {
    				result.put(ERROR_CODE, code);
    				result.put(ERROR_MESSAGE, "请求失败!");
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			result.put(ERROR_CODE, ERROR_EXCEPTION);
    			result.put(ERROR_MESSAGE, e.getMessage());
    		} finally {
    			if (response != null) {
    				EntityUtils.consumeQuietly(response.getEntity());
    			}
    			if (post != null) {
    				post.releaseConnection();
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * 正常httpclent请求
    	 * 
    	 * @param reqURL
    	 * @param json
    	 * @param isProxy
    	 * @return
    	 */
    	public static JSONObject sendPostRequest(String reqURL, JSONObject json, boolean isProxy) {
    		return sendPostRequestCommon(reqURL, json, isProxy, false);
    	}
    
    	/**
    	 * 加长传输时间httpclent请求
    	 * 
    	 * @param reqURL
    	 * @param json
    	 * @param isProxy
    	 * @return
    	 */
    	public static JSONObject sendPostRequestSlow(String reqURL, JSONObject json, boolean isProxy) {
    		return sendPostRequestCommon(reqURL, json, isProxy, true);
    	}
    
    	/**
    	 * 下载文件功能
    	 * 
    	 * @param url
    	 * @param json
    	 * @return
    	 */
    	public static DownLoadFile downLoadFile(String url, String json) {
    		if (null != connManager) {
    			connManager.closeExpiredConnections();
    			connManager.closeIdleConnections(180L, TimeUnit.SECONDS);
    		}
    		byte[] encryptByte = AesUtil.encrypt(json);
    		HttpPost post = new HttpPost(url);
    		RequestConfig requestConfig = doProxy(true, false);
    		post.setHeader(HttpHeaders.CONNECTION, "close");
    		post.setConfig(requestConfig);
    		post.setEntity(new ByteArrayEntity(encryptByte));
    		CloseableHttpResponse response = null;
    		DownLoadFile file = new DownLoadFile();
    		try {
    			response = httpClient.execute(post);
    			if (response.getStatusLine().getStatusCode() == 200) {
    				HttpEntity entity = response.getEntity();
    				if (entity.getContentType().getValue().contains("application/octet-stream")) {
    					byte[] toByte = IOUtils.toByteArray(response.getEntity().getContent());
    					byte[] derByte = AesUtil.decrypt(toByte);
    					file.setError_code(0);
    					file.setError_message("ok");
    					file.setBytes(derByte);
    					file.setFileName(getFileName(response));
    					file.setContentType(entity.getContentType().getValue());
    					return file;
    				} else if (response.getEntity().getContentType().getValue().contains("text/plain")) {
    					byte[] entityByte = EntityUtils.toByteArray(response.getEntity());
    					byte[] entityStr = AesUtil.decrypt(entityByte);
    					JSONObject jsonResult;
    					if (null != entityStr && entityStr.length > 0) {
    						jsonResult = JSONObject.fromObject(new String(entityStr, ENCODE_CHARSET));
    					} else {
    						String s = new String(entityByte, ENCODE_CHARSET);
    						logger.info("下载文件返回的字符串是:{}", s);
    						jsonResult = JSONObject.fromObject(s);
    					}
    					file.setError_code(jsonResult.getInt(ERROR_CODE));
    					file.setError_message(jsonResult.getString(ERROR_MESSAGE));
    					return file;
    				}
    			}
    		} catch (Exception e) {
    			file.setError_code(ERROR_EXCEPTION);
    			file.setError_message(e.getMessage());
    			logger.error(e.getMessage(), e);
    		} finally {
    			if (response != null) {
    				EntityUtils.consumeQuietly(response.getEntity());
    			}
    			if (post != null) {
    				post.releaseConnection();
    			}
    		}
    		return file;
    	}
    
    	/**
    	 * 获取Header标头中的filename,文件名称
    	 *
    	 * @param response
    	 * @return
    	 */
    	public static String getFileName(HttpResponse response) {
    		Header contentHeader = response.getFirstHeader("Content-Disposition");
    		String filename = null;
    		if (contentHeader != null) {
    			HeaderElement[] values = contentHeader.getElements();
    			if (values.length == 1) {
    				NameValuePair param = values[0].getParameterByName("filename");
    				if (param != null) {
    					try {
    						filename = new String(param.getValue().getBytes("iso-8859-1"), ENCODE_CHARSET);
    					} catch (Exception e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}
    		return filename;
    	}
    
    	/**
    	 * 代理设置
    	 * 
    	 * @param isProxy
    	 * @return
    	 */
    	private static RequestConfig doProxy(boolean isProxy, boolean delay) {
    		RequestConfig.Builder configBuilder = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT);
    		if (delay) {
    			configBuilder.setSocketTimeout(SOCKET_TIMEOUT_DELAY);
    		}
    		if (CloudBootStrapUtils.PROXY_START && isProxy) {
    			HttpHost proxy = new HttpHost(CloudBootStrapUtils.PROXY_ADDRESS, CloudBootStrapUtils.PROXY_PORT);
    			configBuilder.setProxy(proxy);
    		}
    		return configBuilder.build();
    	}
    
    	/**
    	 * 发送post请求
    	 * 
    	 * @param reqURL
    	 * @param json
    	 * @param isProxy
    	 * @return
    	 */
    	private static JSONObject sendPostRequestCommon(String reqURL, JSONObject json, boolean isProxy, boolean delay) {
    		if (null != connManager) {
    			connManager.closeExpiredConnections();
    			connManager.closeIdleConnections(180L, TimeUnit.SECONDS);
    		}
    		PoolStats poolStats;
    		if (connManager != null && (poolStats = connManager.getTotalStats()) != null) {
    			if (poolStats.getLeased() > 100 || poolStats.getPending() > 1) {
    				logger.info("now client pool {}", poolStats);
    			}
    		}
    		JSONObject jsonResult = new JSONObject();
    		// 创建HTTP请求
    		HttpPost post = new HttpPost(reqURL);
    		post.setHeader(HttpHeaders.CONNECTION, "close");
    		// 参数AEC加密
    		byte[] encryptByte = AesUtil.encrypt(json.toString());
    		if (isProxy) {
    			RequestConfig requestConfig = doProxy(isProxy, delay);
    			if (null != requestConfig) {
    				post.setConfig(requestConfig);
    			}
    		}
    		// 设置访问字节型
    		post.setEntity(new ByteArrayEntity(encryptByte));
    		CloseableHttpResponse response = null;
    		try {
    			response = httpClient.execute(post);
    			HttpEntity entity = response.getEntity();
    			if (response.getStatusLine().getStatusCode() == 200 && null != entity) {
    				byte[] entityByte = EntityUtils.toByteArray(entity);
    				byte[] entityStr = AesUtil.decrypt(entityByte);
    				EntityUtils.consume(entity);
    				if (null != entityStr && entityStr.length > 0) {// 正常解密
    					jsonResult = JSONObject.fromObject(new String(entityStr, ENCODE_CHARSET));
    				} else {
    					// 解密失败
    					String s = new String(entityByte, ENCODE_CHARSET);
    					if (StringUtils.isNotBlank(s) && StringUtils.startsWith(s, "{")) {
    						jsonResult = JSONObject.fromObject(s);
    					} else {
    						jsonResult.put(ERROR_CODE, ERROR_EXCEPTION);
    						jsonResult.put(ERROR_MESSAGE, s);
    					}
    				}
    				return jsonResult;
    			}
    			jsonResult.put(ERROR_CODE, response.getStatusLine().getStatusCode());
    			jsonResult.put(ERROR_MESSAGE, response.getStatusLine().toString());
    		} catch (Exception e) {
    			jsonResult.put(ERROR_CODE, ERROR_EXCEPTION);
    			jsonResult.put(ERROR_MESSAGE, e.getMessage());
    		} finally {
    			if (response != null) {
    				EntityUtils.consumeQuietly(response.getEntity());
    			}
    			if (post != null) {
    				post.releaseConnection();
    			}
    		}
    		return jsonResult;
    	}
    
    	/**
    	 * SSL的socket工厂创建
    	 */
    	private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
    		SSLConnectionSocketFactory sslsf = null;
    		// 创建TrustManager() 用于解决javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    		X509TrustManager trustManager = new X509TrustManager() {
    			@Override
    			public X509Certificate[] getAcceptedIssuers() {
    				return null;
    			}
    
    			@Override
    			public void checkClientTrusted(X509Certificate[] arg0, String authType) throws CertificateException {
    			}
    
    			@Override
    			public void checkServerTrusted(X509Certificate[] arg0, String authType) throws CertificateException {
    			}
    		};
    		SSLContext sslContext;
    		try {
    			sslContext = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
    			sslContext.init(null, new TrustManager[] { (TrustManager) trustManager }, null);
    			// 创建SSLSocketFactory , // 不校验域名 ,取代以前验证规则
    			sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    		} catch (Exception e) {
    			logger.error(e.getMessage(), e);
    		}
    		return sslsf;
    	}
    
    	/**
    	 * httpclent连接池的状态
    	 * 
    	 * @return
    	 */
    	public static Map<HttpRoute, PoolStats> getConnManagerStats() {
    		if (connManager != null) {
    			Set<HttpRoute> routeSet = connManager.getRoutes();
    			if (routeSet != null && !routeSet.isEmpty()) {
    				Map<HttpRoute, PoolStats> routeStatsMap = new HashMap<HttpRoute, PoolStats>();
    				for (HttpRoute route : routeSet) {
    					PoolStats stats = connManager.getStats(route);
    					routeStatsMap.put(route, stats);
    				}
    				return routeStatsMap;
    			}
    		}
    		return null;
    	}
    
    	/**
    	 * 获取当前连接池的状态
    	 * 
    	 * @return
    	 */
    	public static PoolStats getConnManagerTotalStats() {
    		if (connManager != null) {
    			return connManager.getTotalStats();
    		}
    		return null;
    	}
    
    	/**
    	 * 关闭系统时关闭httpClient
    	 */
    	public static void releaseHttpClient() {
    		try {
    			httpClient.close();
    		} catch (IOException e) {
    			logger.error("关闭httpClient异常" + e);
    		} finally {
    			if (connManager != null) {
    				connManager.shutdown();
    			}
    		}
    	}
    }
    

      

  • 相关阅读:
    CCoolBar 的替代方案 CDockablePane。
    CTreeView 的教程
    散列表
    Add and Search Word
    Contains Duplicate II
    Word Search II
    Implement Trie (Prefix Tree)
    (转)多进程 & 多线程的区别与适用场景
    (转)进程控制:进程的创建、终止、阻塞、唤醒和切换
    (转)几个常用的操作系统进程调度算法
  • 原文地址:https://www.cnblogs.com/lambertwe/p/11718533.html
Copyright © 2020-2023  润新知