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"; } }

浙公网安备 33010602011771号