HttpClient服务请求的一些用法

由于最近公司在对接银行项目,所以我研究了一下关于httpclient的一下基本用法,我这里使用的是httpclient链接池的方式进行的

首先先设置基本参数

private static CloseableHttpClient httpClient;

    private final static Object syncLock = new Object();

    private static final Logger LOGGER = LoggerFactory.getLogger(HTTPUtils.class);

    /**
     * 最大连接数
     */
    private static int MAX_CONNECTION_NUM = 400;

    /**
     * 单路由最大连接数
     */
    private static int DEFAULT_MAX_PER_ROUTE = 50;

    /**
     * 目标主机最大连接数
     */
    private static int MAX_PER_ROUTE = 100;

    /**
     * 向服务器请求超时时间
     */
    private static int SERVER_REQUEST_TIME_OUT = 10000;

    /**
     * 服务端响应超时时间设置(单位:毫秒)
     */
    private static int SERVER_RESPONSE_TIME_OUT = 10000;

    private static final String CHARSET = "utf-8";// 编码设置

2.创建Httpclient链接对象

/**
     * 创建httpClient对象
     *
     * @param hostname
     * @param port
     * @return
     */
    private static CloseableHttpClient createHttpClient(String hostname, int port) {

//        SSLContext sslContext = createIgnoreVerifySSL();

        // 设置协议http和https对应的处理socket链接工厂的对象
        ConnectionSocketFactory socketFactory = PlainConnectionSocketFactory.getSocketFactory();
//		LayeredConnectionSocketFactory connectionSocketFactory = SSLConnectionSocketFactory.getSocketFactory();
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", socketFactory)
                .register("https", trustAllHttpsCert()).build();

        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
        // 将最大连接数添加
        cm.setMaxTotal(MAX_CONNECTION_NUM);
        // 将每一个路由基础的连接添加
        cm.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);
        HttpHost httpHost = new HttpHost(hostname, port);
        // 将目标主机的最大连接数添加
        cm.setMaxPerRoute(new HttpRoute(httpHost), MAX_PER_ROUTE);


        HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                if (executionCount >= 5) {// 假设已经重试了5次,就放弃
                    return false;
                }
                if (exception instanceof NoHttpResponseException) {// 假设server丢掉了连接。那么就重试
                    LOGGER.error("NoHttpResponseException: server丢掉了连接");
//                    logRepositoryService.error("假设server丢掉了连接。那么就重试", exception.getMessage());
                    return true;
                }
                if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
                    LOGGER.error("SSLHandshakeException: 不要重试SSL握手异常");
//                    logRepositoryService.error("不要重试SSL握手异常", exception.getMessage());
                    return false;
                }
                if (exception instanceof InterruptedIOException) {// 超时
                    LOGGER.error("InterruptedIOException:超时");
//                    logRepositoryService.error("超时", exception.getMessage());
                    return false;
                }
                if (exception instanceof UnknownHostException) {// 目标server不可达
                    LOGGER.error("UnknownHostException: 目标server不可达");
//                    logRepositoryService.error("目标server不可达", exception.getMessage());
                    return false;
                }
                if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
                    LOGGER.error("ConnectTimeoutException: 连接被拒绝");
//                    logRepositoryService.error("连接被拒绝", exception.getMessage());
                    return false;
                }
                if (exception instanceof SSLException) {// SSL握手异常
//                    logRepositoryService.error("SSL握手异常", exception.getMessage());
                    LOGGER.error("SSLException: SSL握手异常");
                    return false;
                }
                HttpClientContext clientContext = HttpClientContext
                        .adapt(context);

                HttpRequest request = clientContext.getRequest();
                if (!(request instanceof HttpEntityEnclosingRequest)) {
                    return true;
                }
                return false;
            }
        };

        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .setRetryHandler(httpRequestRetryHandler).build();

        return httpClient;
    }

3.获取Httpclient

/**
     * 获取httpclient
     *
     * @param url
     * @return
     */
    public static CloseableHttpClient getHttpClient(String url) {
        String hostname = url.split("/")[2];
        int port = 80;
        if (hostname.contains(":")) {
            String[] arr = hostname.split(":");
            hostname = arr[0];
            port = Integer.parseInt(arr[1]);
        }
        if (httpClient == null) {
            synchronized (syncLock) {
                if (httpClient == null) {
                    httpClient = createHttpClient(hostname, port);
                }
            }
        }
        return httpClient;
    }

4.创建httpclient之前需要忽略https的证书验证

 /**
     * https忽略证书验证
     *
     * @return
     */

    public static SSLConnectionSocketFactory trustAllHttpsCert() {
        SSLConnectionSocketFactory socketFactory = null;
        TrustManager[] trustManagers = new TrustManager[1];
        TrustManager tm = new miTM();
        trustManagers[0] = tm;
        SSLContext sc = null;
        try {
            sc = SSLContext.getInstance("TLS");//sc = SSLContext.getInstance("TLS")
            sc.init(null, trustManagers, null);
            socketFactory = new SSLConnectionSocketFactory(sc, NoopHostnameVerifier.INSTANCE);
            //HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return socketFactory;
    }

    static class miTM implements TrustManager, X509TrustManager {

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkServerTrusted(X509Certificate[] certs, String authType) {
            //don't check
        }

        public void checkClientTrusted(X509Certificate[] certs, String authType) {
            //don't check
        }
    }
5.设置请求头相关信息,由于httpclient相当于是客户端,所以我们请求需要设置提交服务器的请求头,这里我设置了xml、json、和一般表单方式的请求头
 /**
     * 设置基本信息,相应头,请求时间, 超时时间等...
     * <p>
     * 配置xml格式
     *
     * @param httpRequestBase httpRequestBase
     */
    private static void configXml(HttpRequestBase httpRequestBase) {
        httpRequestBase.setHeader("Content-type", (new StringBuilder()).append("application/xml; charset=")
                .append(CHARSET).toString());
//        httpRequestBase.setHeader("Accept", new StringBuffer("text/xml;charset=").append(CHARSET).toString());
        httpRequestBase.setHeader("Cache-Control", "no-cache");
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(SERVER_REQUEST_TIME_OUT)
                .setConnectTimeout(SERVER_REQUEST_TIME_OUT).setSocketTimeout(SERVER_RESPONSE_TIME_OUT).build();
        httpRequestBase.setConfig(requestConfig);
    }


    /**
     * 设置基本信息,相应头,请求时间, 超时时间等...
     * contentType为x-www-form-urlencoded
     * <p>
     * 配置默认格式
     *
     * @param httpRequestBase httpRequestBase
     */
    private static void configNomal(HttpRequestBase httpRequestBase) {
        httpRequestBase.setHeader("Content-type", (new StringBuilder().append("application/x-www-form-urlencoded; charset="))
                .append(CHARSET).toString());
        httpRequestBase.setHeader("Cache-Control", "no-cache");
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(SERVER_REQUEST_TIME_OUT)
                .setConnectTimeout(SERVER_REQUEST_TIME_OUT).setSocketTimeout(SERVER_RESPONSE_TIME_OUT).build();
        httpRequestBase.setConfig(requestConfig);
    }

    /**
     * json格式提交
     * <p>
     * 设置基本信息,相应头,请求时间, 超时时间等...
     *
     * @param httpRequestBase httpRequestBase
     */
    private static void configJson(HttpRequestBase httpRequestBase) {
        httpRequestBase.setHeader("Content-type", (new StringBuilder()).append("application/json; charset=")
                .append(CHARSET).toString());
//        httpRequestBase.setHeader("Accept", new StringBuffer("text/xml;charset=").append(CHARSET).toString());
        httpRequestBase.setHeader("Cache-Control", "no-cache");
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(SERVER_REQUEST_TIME_OUT)
                .setConnectTimeout(SERVER_REQUEST_TIME_OUT).setSocketTimeout(SERVER_RESPONSE_TIME_OUT).build();
        httpRequestBase.setConfig(requestConfig);
    }

6.发起get请求

  /**
     * get请求
     *
     * @param url 请求地址
     * @return 放回参数
     * @throws Exception 异常
     */
    public static String doGet(String url) throws Exception {
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            response = getHttpClient(url).execute(httpGet);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new Exception("请求失败" + response.getStatusLine().getStatusCode());
            }
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                return "";
            }
            return EntityUtils.toString(entity,"UTF-8");
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

7.提交POST请求(xml、json参数形式都可以传入)

/**
     * post请求提交String类型参数
     *
     * @param url 请求地址
     * @param params 请求参数
     * @param contentType 请求参数类型
     * @return 请求返回参数
     */
    public static String doPostByString(String url, String params, String contentType) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        // 判断请求参数类型为JSON还是XML,不同的类型需要设置不同的Content—type
        if (contentType.equals("xml") || contentType.equals("XML")) {// xml方式
            configXml(httpPost);
        } else if (contentType.equals("json") || contentType.equals("JSON")) {// json方式
            configXml(httpPost);
        } else { // 这里默认的为默认提交方式即表单提交
            configNomal(httpPost);
        }
        CloseableHttpResponse response = null;
        String result = "";
        try {
            if (StringUtils.isNotBlank(params)) {// 判断是否有参数
                StringEntity entity = new StringEntity(params, "UTF-8");
                httpPost.setEntity(entity);
            }
            response =  getHttpClient(url).execute(httpPost);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                return "";
            }
            HttpEntity responseEntity = response.getEntity();
            result = EntityUtils.toString(responseEntity, "UTF-8");
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return result;
    }

8.文件上传

 /**
     * 利用Httpclient上传文件
     * @param url 地址
     * @param map 参数
     * @param file 文件
     * @return 返回信息
     * @throws Exception 异常
     */
    public static String doPostUplodeFile(String url, Map<String, Object> map, File file) throws Exception {
        if (StringUtils.isBlank(url) || map == null || map.isEmpty()) {
            return "";
        }
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;

        try {
            List<BasicNameValuePair> params = new ArrayList<>();
            MultipartEntity entity = new MultipartEntity();
            for (String key : map.keySet()) {
                entity.addPart(key, new StringBody((String) map.get(key), Charset.forName("UTF-8")));
            }
            entity.addPart("param3", new FileBody(file));
            httpPost.setEntity(entity);
            response = getHttpClient(url).execute(httpPost);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new Exception("请求失败" + response.getStatusLine().getStatusCode());
            }
            HttpEntity resEntity = response.getEntity();
            return null == resEntity ? "" : EntityUtils.toString(resEntity, CHARSET);
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值