Explain
http request is the most commonly used method of inter system interface call.
In java, there are many ways of http request. httpClient is a common way at present, and it is easy to use.
However, creating an httpClient is a time-consuming process. To improve performance, the http connection pool is usually used to get the httpClient object from the connection pool every time.
Introduction of jar package
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>fluent-hc</artifactId> <version>4.5.6</version> </dependency>
Code example
1. Custom connection pool
public class HttpUtils { private final static Logger log = LoggerFactory.getLogger(HttpUtils.class); private static final int REQUEST_TIMEOUT = 12 * 1000; // Set request timeout 12 seconds private static final int TIMEOUT = 12 * 1000; // Connection timeout private static final int SO_TIMEOUT = 12 * 1000; // Data transmission timeout private static final String CHARSET = "UTF8"; private static CloseableHttpClient httpClient = null; static { init(); } public static void init() { try { // SSLContext SSLContextBuilder sslContextbuilder = new SSLContextBuilder(); SSLContext sslContext = sslContextbuilder.loadTrustMaterial(null, (chain, authType) -> true).build(); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)) .build(); // Create ConnectionManager PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); // Create socket configuration SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).build(); connManager.setDefaultSocketConfig(socketConfig); // Create message constraints MessageConstraints messageConstraints = MessageConstraints.custom().setMaxHeaderCount(200) .setMaxLineLength(2000).build(); // Create connection configuration ConnectionConfig connectionConfig = ConnectionConfig.custom() .setMalformedInputAction(CodingErrorAction.IGNORE) .setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Consts.UTF_8) .setMessageConstraints(messageConstraints).build(); connManager.setDefaultConnectionConfig(connectionConfig); connManager.setMaxTotal(200); connManager.setDefaultMaxPerRoute(20); // Create httpClient httpClient = HttpClients.custom().disableRedirectHandling().setConnectionManager(connManager).build(); } catch (KeyManagementException e) { log.error("KeyManagementException", e); } catch (NoSuchAlgorithmException e) { log.error("NoSuchAlgorithmException", e); } catch (Exception e) { log.error("Exception", e); } } public static String doGet(String url) throws Exception { return doGet(url, null); } /** * GET Method request data */ public static String doGet(String url, Map<String, String> headerMap) throws Exception { HttpGet httpGet = new HttpGet(url); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SO_TIMEOUT).setConnectTimeout(TIMEOUT) .setConnectionRequestTimeout(REQUEST_TIMEOUT).build(); httpGet.setConfig(requestConfig); if (headerMap != null) { for (String key : headerMap.keySet()) { httpGet.setHeader(key, headerMap.get(key)); } } long responseLength = 0; // Response length String responseContent = null; // Response content String strRep = null; try { // Execute get request HttpResponse httpResponse = httpClient.execute(httpGet); // Get response message entity HttpEntity entity = httpResponse.getEntity(); if (entity != null) { responseLength = entity.getContentLength(); // Cannot call this method repeatedly, IO stream is closed. responseContent = EntityUtils.toString(entity, CHARSET); // Get status code of HTTP response int statusCode = httpResponse.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { strRep = responseContent; } // Consume response content EntityUtils.consume(entity); // Do not need the rest httpGet.abort(); } } finally { httpGet.releaseConnection(); } return strRep; } }
2. Do not use connection pool
public class HttpUtils2 { private final static Logger log = LoggerFactory.getLogger(HttpUtils2.class); private static final int REQUEST_TIMEOUT = 12 * 1000; // Set request timeout 12 seconds private static final int TIMEOUT = 12 * 1000; // Connection timeout private static final int SO_TIMEOUT = 12 * 1000; // Data transmission timeout private static final String CHARSET = "UTF8"; /** * GET Method request data */ public static String doGet(String url) { String strRep = null; HttpGet httpGet = new HttpGet(url); try { RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SO_TIMEOUT).setConnectTimeout(TIMEOUT) .setConnectionRequestTimeout(REQUEST_TIMEOUT).build(); httpGet.setConfig(requestConfig); HttpClient httpClient = HttpClients.createDefault(); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity entity = httpResponse.getEntity(); log.info("Response state: {}", httpResponse.getStatusLine()); // Cannot call this method repeatedly, IO stream is closed. String responseContent = EntityUtils.toString(entity, CHARSET); // Get status code of HTTP response int statusCode = httpResponse.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { strRep = responseContent; } } catch (Exception e) { log.error("get Request exception: {} get url: {}", e.getMessage(), url); } finally { httpGet.releaseConnection(); } return strRep; } }
3. Using fluent HC request
Fluent HC, a simple encapsulation of HttpClient, and its own connection pool, is more convenient to use
public class HttpUtils3 { private final static Logger log = LoggerFactory.getLogger(HttpUtils3.class); private static final int REQUEST_TIMEOUT = 12 * 1000; // Set request timeout 12 seconds private static final int SO_TIMEOUT = 12 * 1000; // Data transmission timeout private static final String CHARSET = "UTF8"; /** * GET Method request data */ public static String doGet(String url) { String strRep = null; HttpGet httpGet = new HttpGet(url); try { HttpEntity entity = Request.Get(url) .connectTimeout(REQUEST_TIMEOUT) .socketTimeout(SO_TIMEOUT) .execute().returnResponse().getEntity(); // Cannot call this method repeatedly, IO stream is closed. strRep = EntityUtils.toString(entity, CHARSET); } catch (Exception e) { log.error("get Request exception: {} get url: {}", e.getMessage(), url); } finally { httpGet.releaseConnection(); } return strRep; } }
4. Use test comparison
Use three methods to call the interface 10 times in succession
public class HttpTest { public static void main(String[] args) throws Exception { Stopwatch stopWatch = Stopwatch.createStarted(); for (int i = 0; i < 10; i++) { HttpUtils.doGet("http://www.baidu.com"); long stime = stopWatch.elapsed(TimeUnit.MILLISECONDS); System.out.println("HttpUtils Time consuming:" + stime); stopWatch.reset().start(); } System.out.println("------------------"); for (int i = 0; i < 10; i++) { HttpUtils2.doGet("http://www.baidu.com"); long stime = stopWatch.elapsed(TimeUnit.MILLISECONDS); System.out.println("HttpUtils2 Time consuming:" + stime); stopWatch.reset().start(); } System.out.println("------------------"); for (int i = 0; i < 10; i++) { HttpUtils3.doGet("http://www.baidu.com"); long stime = stopWatch.elapsed(TimeUnit.MILLISECONDS); System.out.println("HttpUtils3 Time consuming:" + stime); stopWatch.reset().start(); } } }
The output results are as follows:
HttpUtils time: 4480 HttpUtils time: 13 HttpUtils time: 16 HttpUtils time: 14 HttpUtils time: 13 HttpUtils time: 13 HttpUtils time: 13 HttpUtils time: 14 HttpUtils time: 15 HttpUtils time: 14 ------------------ HttpUtils2 time consumption: 48 HttpUtils2 time consumption: 25 HttpUtils2 time consumption: 28 HttpUtils2 time consumption: 25 HttpUtils2 time consumption: 28 HttpUtils2 time consumption: 33 HttpUtils2 time consumption: 37 HttpUtils2 time consumption: 30 HttpUtils2 time consumption: 26 HttpUtils2 time consumption: 32 ------------------ HttpUtils3 time consumption: 47 HttpUtils3 time consumption: 12 HttpUtils3 time consumption: 13 HttpUtils3 time consumption: 13 HttpUtils3 time consumption: 12 HttpUtils3 time consumption: 11 HttpUtils3 time consumption: 13 HttpUtils3 time consumption: 13 HttpUtils3 time consumption: 13 HttpUtils3 time consuming: 11The first request takes a long time to initialize the object.
It can be seen from the results that the performance of custom connection pool is similar to that of fluent HC, and it takes a long time to directly initiate httpClient requests, which is 2-3 times the time of connection pool.
Nine changes in hard rock 65 original articles published, 31 praised, 40000 visitors+ Private letter follow