package com.iamberry.wechat.tools;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
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.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.alibaba.dubbo.common.json.JSONObject;
import com.google.common.base.Strings;

/**
 * @author 何秀刚
 * Class Description:http请求封装
 * Create Date:2016年5月3日
 * Update Date:2016年5月3日
 */
public class HttpClient431Util {
    protected static final Logger log = Logger.getLogger(HttpClient431Util.class);

    private static final RequestConfig config;

    /**
     * 用于单向加密的POST请求的缓存connection
     */
    public static CloseableHttpClient singleSSLConnection = null;
    
    /**
     * 用于缓存双向加密的请求的Connection,通用
     */
    public static CloseableHttpClient dualSSLConnectionJKS;
    
    /**
     * 用于缓存双向加密的请求的Connection by Key,微信支付使用的
     */
    public static CloseableHttpClient dualSSLConnectionByKey;

    static {
        config = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(5000).build();
    }

    public static String doGet( Map<String, String> params,String url,String cookie) throws Exception{
        return doGet(params,url,NameUtils.DEFAULT_SEND_CHARSET,NameUtils.DEFAULT_RES_CHARSET,cookie);
    }

    public static String doGet( Map<String, String> params,String url) throws Exception{
        return doGet(params,url,NameUtils.DEFAULT_SEND_CHARSET,NameUtils.DEFAULT_RES_CHARSET,"");
    }
    public static String doPost(Map<String, String> params,String url) throws Exception{
        return doPost(params,url,NameUtils.DEFAULT_SEND_CHARSET,NameUtils.DEFAULT_RES_CHARSET);
    }
    public static String doDualSSLPost(Map<String, String> params,String url,String keyStorePath,String keyStorePass) throws Exception{
        return doDualSSLPost(params, url, NameUtils.DEFAULT_SEND_CHARSET, NameUtils.DEFAULT_RES_CHARSET, keyStorePath, keyStorePass);
    }
    public static String doDualSSLPost(String params,String url,String keyStorePath,String keyStorePass) throws Exception{
        return doDualSSLPost(params, url, NameUtils.DEFAULT_SEND_CHARSET, NameUtils.DEFAULT_RES_CHARSET, keyStorePath, keyStorePass);
    }
    public static String doPostContent(String dataContent,String contentType,String contentCharset,String resCharset,String url) throws Exception{
        CloseableHttpClient httpClient = getSingleSSLConnection();
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);

            httpPost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpPost.addHeader("Content-Type", contentType);
            httpPost.addHeader("Connection" , "close");
            HttpEntity reqentity = new StringEntity(dataContent, ContentType.create(contentType, contentCharset) );
            httpPost.setEntity(reqentity);

            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, resCharset==null?NameUtils.DEFAULT_RES_CHARSET:resCharset);
            }
            EntityUtils.consume(entity);

            return result;
        } catch (Exception e) {
            throw new Exception(e);
        } finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                }
        }
    }

    public static String doPostContent(String dataContent,String contentType,String url) throws Exception{
        CloseableHttpClient httpClient = getSingleSSLConnection();
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);

            httpPost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpPost.addHeader("Content-Type", contentType);
            httpPost.addHeader("Connection" , "close");
            HttpEntity reqentity = new StringEntity(dataContent, ContentType.create(contentType, NameUtils.DEFAULT_RES_CHARSET) );
            httpPost.setEntity(reqentity);

            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, NameUtils.DEFAULT_RES_CHARSET);
            }
            EntityUtils.consume(entity);

            return result;
        } catch (Exception e) {
            throw new Exception(e);
        } finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                }
        }
    }
    /**
     * HTTP Get 获取内容
     * @param params 请求的参数
     * @param url  请求的url地址 ?之前的地址
     * @param reqCharset    编码格式
     * @param resCharset    编码格式
     * @return    页面内容
     * @throws Exception 
     */
    public static String doGet(Map<String,String> params,String url,String reqCharset,String resCharset,String cookie) throws Exception{
        CloseableHttpClient httpClient = getSingleSSLConnection();
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            if(params != null && !params.isEmpty()){
                List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
                for(Map.Entry<String,String> entry : params.entrySet()){
                    String value = entry.getValue();
                    if(value != null){
                        pairs.add(new BasicNameValuePair(entry.getKey(),value));
                    }
                }
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, reqCharset==null?NameUtils.DEFAULT_SEND_CHARSET:reqCharset));
            }
            HttpGet httpGet = new HttpGet(url);
            httpGet.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpGet.addHeader("Connection" , "close");
            if (!Strings.isNullOrEmpty(cookie)){
                httpGet.setHeader("Cookie", cookie);
            }

            response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, resCharset==null ? NameUtils.DEFAULT_RES_CHARSET:resCharset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            throw new Exception(e);
        } finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                	e.printStackTrace();
                }
        }
    }
    
    /**
     * 下载远程文件
     * @param url
     * @param path
     * @return
     * @throws Exception
     */
    public static boolean downloadFile(String url, String path) throws Exception {

        CloseableHttpClient httpClient = getSingleSSLConnection();
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return false;
        }
        try {
            HttpGet httpGet = new HttpGet(url);
            httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36");
            httpGet.addHeader("Connection" , "close");
            response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            byte[] data = EntityUtils.toByteArray(response.getEntity()); 
            try {
            	// 保存文件
            	FileUtils.writeByteArrayToFile(new File(path), data);
            } catch (Exception e) {  
                log.error("save File Error, path = " + path + ",url=" + url, e);  
            } finally {  
                try {
                } catch (Exception e) {
                    log.error("finally BufferedOutputStream shutdown close", e);  
                }  
            }  
            EntityUtils.consume(response.getEntity());
            response.close();
            return true;
        } catch (Exception e) {
        	log.error("htt client error.", e);  
        } finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                }
        }
        return false;
    }

    /**
     * HTTP Post 获取内容
     * @param params 请求的参数
     * @param url  请求的url地址 ?之前的地址
     * @param reqCharset    编码格式
     * @param resCharset    编码格式
     * @return    页面内容
     */
    public static String doPost(Map<String,String> params,String url,String reqCharset,String resCharset) throws Exception{
        CloseableHttpClient httpClient = getSingleSSLConnection();
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            List<NameValuePair> pairs = null;
            if(params != null && !params.isEmpty()){
                pairs = new ArrayList<NameValuePair>(params.size());
                for(Map.Entry<String,String> entry : params.entrySet()){
                    String value = entry.getValue();
                    if(value != null){
                        pairs.add(new BasicNameValuePair(entry.getKey(),value));
                    }
                }
            }
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpPost.addHeader("Connection" , "close");
            if(pairs != null && pairs.size() > 0){
                httpPost.setEntity(new UrlEncodedFormEntity(pairs,reqCharset==null?NameUtils.DEFAULT_SEND_CHARSET:reqCharset));
            }
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, resCharset==null?NameUtils.DEFAULT_RES_CHARSET:resCharset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        }
        catch (Exception e) {
            throw e;
        }finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                }
        }
    }

    /**
     * HTTP Post 获取内容
     * @param params 请求的参数
     * @param url  请求的url地址 ?之前的地址
     * @param reqCharset    编码格式
     * @param resCharset    编码格式
     * @return    页面内容
     */
    public static String doPost(Map<String,String> params,String url,String reqCharset,String resCharset,String contentType) throws Exception{
        CloseableHttpClient httpClient = getSingleSSLConnection();
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            List<NameValuePair> pairs = null;
            if(params != null && !params.isEmpty()){
                pairs = new ArrayList<NameValuePair>(params.size());
                for(Map.Entry<String,String> entry : params.entrySet()){
                    String value = entry.getValue();
                    if(value != null){
                        pairs.add(new BasicNameValuePair(entry.getKey(),value));
                    }
                }
            }
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpPost.addHeader("Content-Type",contentType);
            httpPost.addHeader("Connection" , "close");
            if(pairs != null && pairs.size() > 0){
                httpPost.setEntity(new UrlEncodedFormEntity(pairs,reqCharset==null?NameUtils.DEFAULT_SEND_CHARSET:reqCharset));
            }
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, resCharset==null?NameUtils.DEFAULT_RES_CHARSET:resCharset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            throw new Exception(e);
        } finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                }
        }
    }

    public static String doPost(JSONObject jsonObject, String url, String resCharset) throws Exception{
        CloseableHttpClient httpClient = getSingleSSLConnection();
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpPost.addHeader("Content-Type","JSON");
            httpPost.addHeader("Connection" , "close");
            StringEntity myEntity = new StringEntity(jsonObject.toString(), "UTF-8");
            httpPost.setEntity(myEntity);
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, resCharset==null?NameUtils.DEFAULT_RES_CHARSET:resCharset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            throw new Exception(e);
        } finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                }
        }
    }

    /**
     * HTTP Post 获取内容
     * @param params 请求的参数
     * @param url  请求的url地址 ?之前的地址
     * @param reqCharset    编码格式
     * @param resCharset    编码格式
     * @return    页面内容
     * @throws Exception 
     */
    public static String doDualSSLPost(Map<String,String> params,String url,String reqCharset,String resCharset,String keyStorePath,String keyStorePass) throws Exception{
        CloseableHttpClient httpClient = getDualSSLConnection(keyStorePath,keyStorePass);
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            List<NameValuePair> pairs = null;
            if(params != null && !params.isEmpty()){
                pairs = new ArrayList<NameValuePair>(params.size());
                for(Map.Entry<String,String> entry : params.entrySet()){
                    String value = entry.getValue();
                    if(value != null){
                        pairs.add(new BasicNameValuePair(entry.getKey(),value));
                    }
                }
            }
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpPost.addHeader("Connection" , "close");
            if(pairs != null && pairs.size() > 0){
                httpPost.setEntity(new UrlEncodedFormEntity(pairs,reqCharset==null?NameUtils.DEFAULT_SEND_CHARSET:reqCharset));
            }
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, resCharset==null?NameUtils.DEFAULT_RES_CHARSET:resCharset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            throw new Exception(e);
        } finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                }
        }
    }

    /**
     * HTTP Post 获取内容
     * @param params 请求的参数
     * @param url  请求的url地址 ?之前的地址
     * @param reqCharset    编码格式
     * @param resCharset    编码格式
     * @return    页面内容
     * @throws Exception
     */
    public static String doDualSSLPost(String params,String url,String reqCharset,String resCharset,String keyStorePath,String keyStorePass) throws Exception{
        CloseableHttpClient httpClient = getDualSSLConnection(keyStorePath,keyStorePass);
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpPost.addHeader("Connection" , "close");
            httpPost.setEntity(new StringEntity(params, "UTF-8"));
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, resCharset==null?NameUtils.DEFAULT_RES_CHARSET:resCharset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            throw new Exception(e);
        } finally{
            if(response!=null)
                try {
                    response.close();
                } catch (IOException e) {
                }
        }
    }
    
    /**
     * 创建双向ssl的连接
     * @param keyStorePath
     * @param keyStorePass
     * @return
     * @throws Exception
     */
    private static CloseableHttpClient getDualSSLConnection(String keyStorePath,String keyStorePass) throws Exception{
    	
    	if (HttpClient431Util.dualSSLConnectionJKS != null) {
    		return HttpClient431Util.dualSSLConnectionJKS;
    	}
    	
        CloseableHttpClient httpClient = null;
        try {
            File file = new File(keyStorePath);
            URL sslJksUrl = file.toURI().toURL();
            KeyStore keyStore  = KeyStore.getInstance("jks");
            InputStream is = null;
            try {
                is = sslJksUrl.openStream();
                keyStore.load(is, keyStorePass != null ? keyStorePass.toCharArray(): null);
            } finally {
                if (is != null) is.close();
            }
            SSLContext sslContext = new SSLContextBuilder().loadKeyMaterial(keyStore, keyStorePass != null ? keyStorePass.toCharArray(): null)
                    .loadTrustMaterial(null,new TrustStrategy() {
                        @Override
                        public boolean isTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException {return true;}
                    })
                    .build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            httpClient =  HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(config).build();
            HttpClient431Util.dualSSLConnectionJKS = httpClient;
            return httpClient;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }
    

    /**
     * 创建双向ssl的连接
     * @param keyStorePath
     * @param keyStorePass
     * @return
     * @throws Exception
     */
    private static CloseableHttpClient getSendDualSSLConnection(String keyStorePath,String keyStorePass) throws Exception{
    	if (HttpClient431Util.dualSSLConnectionByKey != null) {
    		return HttpClient431Util.dualSSLConnectionByKey;
    	}
        CloseableHttpClient httpClient = null;
        try {
            InputStream is = null;
            try {
                is = StaticInfo.sslJksUrl.openStream();
                StaticInfo.keyStore.load(is, keyStorePass != null ? keyStorePass.toCharArray(): null);
            } finally {
                if (is != null) is.close();
            }
            SSLContext sslContext = new SSLContextBuilder().loadKeyMaterial(StaticInfo.keyStore, keyStorePass != null ? keyStorePass.toCharArray(): null)
                    .loadTrustMaterial(null,new TrustStrategy() {
                        @Override
                        public boolean isTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException {return true;}
                    }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            httpClient =  HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(config).build();
            HttpClient431Util.dualSSLConnectionByKey = httpClient;
            return httpClient;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    /**
     * 获取一个SSL加密的socket
     */
    public static CloseableHttpClient getHttpClient() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, UnrecoverableKeyException {
    	KeyStore keyStore = KeyStore.getInstance("PKCS12");
		InputStream instream = MoneyUtils.class.getResourceAsStream("/apiclient_cert.p12");
		try {
			keyStore.load(instream, NameUtils.getConfig("KEYSTORE_PASSWORD").toCharArray());// 这里写密码..默认是你的MCHID
		} finally {
			instream.close();
		}
		SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, NameUtils.getConfig("KEYSTORE_PASSWORD").toCharArray()).build();
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		return HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(config).build();
    }
    

    /**
     * HTTP Post 获取内容
     * @param params 请求的参数
     * @param url  请求的url地址 ?之前的地址
     * @param reqCharset    编码格式
     * @param resCharset    编码格式
     * @return    页面内容
     */
    public static String doSendWechatRedPack(Map<String, Object> params,String url,String reqCharset,String resCharset,String contentType) throws Exception{
        CloseableHttpClient httpClient = getSendDualSSLConnection(StaticInfo.getResourcekey(), NameUtils.getConfig("KEYSTORE_PASSWORD"));
        CloseableHttpResponse response = null;
        if(StringUtils.isBlank(url)){
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            httpPost.addHeader("Content-Type",contentType);
            httpPost.addHeader("Connection" , "close");
            httpPost.setEntity(new StringEntity(MoneyUtils.createXML(params), "UTF-8"));
            response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new Exception("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null){
                result = EntityUtils.toString(entity, resCharset==null?NameUtils.DEFAULT_RES_CHARSET:resCharset);
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            throw new Exception(e);
        } finally{
            if(response!=null)
	            try {
	                response.close();
	            } catch (IOException e) {
	            }
        }
    }
    
    /**
     * 创建单向ssl的连接
     * @return
     * @throws Exception
     */
    private static CloseableHttpClient getSingleSSLConnection() throws Exception{
    	if (singleSSLConnection != null) {
    		return singleSSLConnection;
    	}
        CloseableHttpClient httpClient = null;
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException {
                	return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            httpClient =  HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(config).build();
            HttpClient431Util.singleSSLConnection = httpClient;
            return httpClient;
        } catch (Exception e) {
            throw new Exception(e);
        }

    }

    public static String sendXmlData(String url,Map<String,String> params) throws Exception{
        HttpClient client = HttpClients.createDefault();
//      client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
        List<NameValuePair> pairs = null;
        if(params != null && !params.isEmpty()){
            pairs = new ArrayList<NameValuePair>(params.size());
            for(Map.Entry<String,String> entry : params.entrySet()){
                String value = entry.getValue();
                if(value != null){
                    pairs.add(new BasicNameValuePair(entry.getKey(),value));
                }
            }
        }
        HttpPost post = new HttpPost(url);

        post.setHeader("Content-Type","text/xml;charset=GB2312");
        post.setEntity(new UrlEncodedFormEntity(pairs,"GB2312"));
        HttpResponse response = client.execute(post);
        Integer code = response.getStatusLine().getStatusCode();
        if(code == 200){
            String result = EntityUtils.toString(response.getEntity(), "GB18030");
            EntityUtils.consume(response.getEntity());
            post.abort();
            return result;
        }
        return "";
    }

    public static void main(String[] args) throws Exception {
//    	long start = System.currentTimeMillis();
//    	boolean b = downloadFile("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQHT8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xLzgwamFXRURsc3AzTE1pQnoxbUFfAAIEkhQsVwMEAAAAAA%3D%3D", "D://abcdefgj.png");
//    	long end = System.currentTimeMillis();
//    	System.out.println(b + "," + (end - start));

        // 生成系统级请求数据
//        Map<String, String> params = new HashMap<String, String>();
//        params.put("nu", "221435993148");
//        String url = "http://api.open.baidu.com/pae/common/api/Redirect";
//        // 发送请求
//        String html = HttpClient431Util.doGet(params, url);
//        Document doc = Jsoup.parse(html);
//        Element content = doc.getElementById("companyCode");
//        String value = content.val();
    }

}
