java实现HTTP请求(四)

参考来源地址:HttpClient(4.5.x)正确的使用姿势

-------------------------------------------------------我们开始写代码啦-------------------------------------------------------

配置线程池以及书写  doGet 和 doPost 请求

package com.rhine.blog.http;

import com.google.gson.Gson;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
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.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.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Map;

/**
 * @program: shirodemo
 * @description:
 * @author: Gaojq
 * @create: 2020-03-20 10:33
 **/
public class PooledHttpClientAdaptor {

    private static final int DEFAULT_POOL_MAX_TOTAL = 200;
    private static final int DEFAULT_POOL_MAX_PER_ROUTE = 200;
    private static final int DEFAULT_CONNECT_TIMEOUT = 500;
    private static final int DEFAULT_CONNECT_REQUEST_TIMEOUT = 500;
    private static final int DEFAULT_SOCKET_TIMEOUT = 2000;

    private PoolingHttpClientConnectionManager gcm = null;
    private CloseableHttpClient httpClient = null;
    private IdleConnectionMonitorThread idleThread = null;

    private final int maxTotal;// 连接池的最大连接数
    private final int maxPerRoute;// 连接池按route配置的最大连接数
    private final int connectTimeout;// tcp connect的超时时间
    private final int connectRequestTimeout;// 从连接池获取连接的超时时间
    private final int socketTimeout;// tcp io的读写超时时间

    public PooledHttpClientAdaptor() {
        this(PooledHttpClientAdaptor.DEFAULT_POOL_MAX_TOTAL,PooledHttpClientAdaptor.DEFAULT_POOL_MAX_PER_ROUTE,
             PooledHttpClientAdaptor.DEFAULT_CONNECT_TIMEOUT,PooledHttpClientAdaptor.DEFAULT_CONNECT_REQUEST_TIMEOUT,
             PooledHttpClientAdaptor.DEFAULT_SOCKET_TIMEOUT);
    }

    public PooledHttpClientAdaptor(int maxTotal,int maxPerRoute,int connectTimeout,int connectRequestTimeout,int socketTimeout) {

        this.maxTotal = maxTotal;
        this.maxPerRoute = maxPerRoute;
        this.connectTimeout = connectTimeout;
        this.connectRequestTimeout = connectRequestTimeout;
        this.socketTimeout = socketTimeout;

        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();

        this.gcm = new PoolingHttpClientConnectionManager(registry);
        this.gcm.setMaxTotal(this.maxTotal);
        this.gcm.setDefaultMaxPerRoute(this.maxPerRoute);

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(this.connectTimeout)                     // 设置连接超时
                .setSocketTimeout(this.socketTimeout)                       // 设置读取超时
                .setConnectionRequestTimeout(this.connectRequestTimeout)    // 设置从连接池获取连接实例的超时
                .build();

        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClient = httpClientBuilder.setConnectionManager(this.gcm).setDefaultRequestConfig(requestConfig).build();
        idleThread = new IdleConnectionMonitorThread(this.gcm);
        idleThread.start();

    }

    /**-----------------------------------------Get请求--------------------------------------------------------**/
    public String doGet(String url) {
        return this.doGet(url, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
    }

    public String doGet(String url, Map<String, Object> params) {
        return this.doGet(url, Collections.EMPTY_MAP, params);
    }

    public String doGet(String url, Map<String, String> headers,Map<String, Object> params) {
        String apiUrl = HttpUtils.getUrlWithParams(url, params);//构建GET请求头
        HttpGet httpGet = new HttpGet(apiUrl);
        //设置header信息
        if ( headers != null && headers.size() > 0 ) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpGet.addHeader(entry.getKey(), entry.getValue());
            }
        }

        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            if (response == null || response.getStatusLine() == null) {
                return null;
            }

            int statusCode = response.getStatusLine().getStatusCode();
            if ( statusCode == HttpStatus.SC_OK ) {
                HttpEntity entityRes = response.getEntity();
                if (entityRes != null) {
                    return EntityUtils.toString(entityRes, "UTF-8");
                }
            }
            return null;
        } catch (IOException e) {
        } finally {
            if ( response != null ) {
                try {
                    response.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }

    /**-----------------------------------------Post请求--------------------------------------------------------**/
    public String doPost(String apiUrl, Map<String, Object> params) {
        return this.doPost(apiUrl, Collections.EMPTY_MAP, params);
    }

    public String doPost(String apiUrl,Map<String, String> headers,Map<String, Object> params) {
        HttpPost httpPost = new HttpPost(apiUrl);
        // 配置请求headers
        if ( headers != null && headers.size() > 0 ) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpPost.addHeader(entry.getKey(), entry.getValue());
            }
        }

        //配置请求参数
        if ( params != null && params.size() > 0 ) {
            if(headers.get("Content-Type").toLowerCase().contains("application/json")){
                StringEntity stringEntity = new StringEntity(new Gson().toJson(params), Charset.forName("UTF-8"));
                httpPost.setEntity(stringEntity);
            }else {
                HttpEntity entityReq = HttpUtils.getUrlEncodedFormEntity(params);
                httpPost.setEntity(entityReq);
            }
        }

        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpPost);
            if (response == null || response.getStatusLine() == null) return null;
            int statusCode = response.getStatusLine().getStatusCode();
            if ( statusCode == HttpStatus.SC_OK ) {
                HttpEntity entityRes = response.getEntity();
                if ( entityRes != null ) {
                    return EntityUtils.toString(entityRes, "UTF-8");
                }
            }
            return null;
        } catch (IOException e) {
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }

    //-----------------------------------------关闭请求--------------------------------------------------------
    public void shutdown() {
        idleThread.shutdown();
    }
}

线程池连接的设置

package com.rhine.blog.http;

import org.apache.http.conn.HttpClientConnectionManager;

import java.util.concurrent.TimeUnit;

/**监控有异常的链接
 * @program: shirodemo
 * @description:
 * @author: Gaojq
 * @create: 2020-03-20 10:40
 **/
//
class IdleConnectionMonitorThread extends Thread {

    private final HttpClientConnectionManager connMgr;
    private volatile boolean exitFlag = false;

    public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
        this.connMgr = connMgr;
        setDaemon(true);
    }

    @Override
    public void run() {
        while (!this.exitFlag) {
            synchronized (this) {
                try {
                    this.wait(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 关闭失效的连接
            connMgr.closeExpiredConnections();
            // 可选的, 关闭30秒内不活动的连接
            connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
        }
    }

    public void shutdown() {
        this.exitFlag = true;
        synchronized (this) {
            notify();
        }
    }
}

 工具类:方法的封装和字符串的拼接

package com.rhine.blog.http;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @program: shirodemo
 * @description:
 * @author: Gaojq
 * @create: 2020-03-20 10:49
 **/
public class HttpUtils {

    public static HttpEntity getUrlEncodedFormEntity(Map<String, Object> params) {
        List<NameValuePair> pairList = new ArrayList<NameValuePair>(params.size());
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
            pairList.add(pair);
        }
        return new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8"));
    }

    public static String getUrlWithParams(String url, Map<String, Object> params) {
        boolean first = true;
        StringBuilder sb = new StringBuilder(url);
        for (String key : params.keySet()) {
            char ch = '&';
            if (first == true) {
                ch = '?';
                first = false;
            }
            String value = params.get(key).toString();
            try {
                String sval = URLEncoder.encode(value, "UTF-8");
                sb.append(ch).append(key).append("=").append(sval);
            } catch (UnsupportedEncodingException e) {
            }
        }
        return sb.toString();
    }
}

测试方法

public static void main(String[] args) {
        PooledHttpClientAdaptor adaptor = new PooledHttpClientAdaptor();
        for (int i = 0; i < 10; i++) {
            Map<String, String> contentType = new HashMap<>();
            contentType.put("Content-Type","application/json");
            String url = "http://localhost:8080/http";
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("msg","very very goog 第"+i);
            String s = adaptor.doPost(url, contentType, paramMap);
            System.out.println("第"+i+"个请求返回值:"+s);
        }
    }

接口

@Controller
@RequestMapping("/")
public class TestController {

    @RequestMapping("http")
    @ResponseBody
    public String httpTest(@RequestBody String body){
        Map map = new Gson().fromJson(body, Map.class);
        map.forEach((key,value) -> {
            System.out.println("key="+key+" value="+value);
        } );
        return "ok";
    }
}
posted @ 2020-03-20 15:24  An-Optimistic-Person  阅读(379)  评论(0)    收藏  举报