Table of Contents
3. Create HttpClient entity class association configuration
4. Create connection thread processing class
5. Create request return result class
6. Create specific request class
1.maven add dependency
pom.xml: here, we add the gson dependency to send the JSON data POST request later, and add the lombook to simplify the entity object (if not needed, we don't need to add it).
<!-- httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpasyncclient</artifactId> <version>4.1</version> </dependency> <!-- gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.2</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
2. Add profile information
Add some information about http configuration in application.yml
#http configuration service http: maxTotal: 100 #maximum connection defaultMaxPerRoute : 20 #Concurrency number connectTimeout: 1000 #Maximum time to create connection connectionRequestTimeout: 500 #Maximum time to get a connection from the connection pool socketTimeout: 10000 #Maximum time of data transmission staleConnectionCheckEnabled: true #Test whether the connection is available before submitting the request
3. Create HttpClient entity class association configuration
@Configuration public class HttpClient { @Value("${http.maxTotal}") private Integer maxTotal; @Value("${http.defaultMaxPerRoute}") private Integer defaultMaxPerRoute; @Value("${http.connectTimeout}") private Integer connectTimeout; @Value("${http.connectionRequestTimeout}") private Integer connectionRequestTimeout; @Value("${http.socketTimeout}") private Integer socketTimeout; @Value("${http.staleConnectionCheckEnabled}") private boolean staleConnectionCheckEnabled; /** * First, instantiate a connection pool manager, and set the maximum number of connections and concurrent connections. * @return */ @Bean(name = "httpClientConnectionManager") public PoolingHttpClientConnectionManager getHttpClientConnectionManager(){ PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager(); //maximum connection httpClientConnectionManager.setMaxTotal(maxTotal); //Concurrency number httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); return httpClientConnectionManager; } /** * Instantiate the connection pool and set the connection pool manager. * The connection pool manager instantiated above needs to be injected as a parameter. * @param httpClientConnectionManager * @return */ @Bean(name = "httpClientBuilder") public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager")PoolingHttpClientConnectionManager httpClientConnectionManager){ //The construction method in HttpClientBuilder is decorated with protected, so you can not directly use new to instantiate an HttpClientBuilder. You can use the static method create() provided by HttpClientBuilder to obtain the HttpClientBuilder object. HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClientBuilder.setConnectionManager(httpClientConnectionManager); return httpClientBuilder; } /** * Inject connection pool to get httpClient * @param httpClientBuilder * @return */ @Bean public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder){ return httpClientBuilder.build(); } /** * Builder Is an internal class of RequestConfig * Get a Builder object through the custom method of RequestConfig * Set up the connection information of builder * You can also set proxy, cookieSpec and other properties here. It can be set here if necessary * @return */ @Bean(name = "builder") public RequestConfig.Builder getBuilder(){ RequestConfig.Builder builder = RequestConfig.custom(); return builder.setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(connectionRequestTimeout) .setSocketTimeout(socketTimeout) .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled); } /** * Using builder to build a RequestConfig object * @param builder * @return */ @Bean public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder){ return builder.build(); } }
4. Create connection thread processing class
@Component public class IdleConnectionEvictor extends Thread { @Autowired private HttpClientConnectionManager connMgr; private volatile boolean shutdown; public IdleConnectionEvictor() { super(); super.start(); } @Override public void run() { try { while (!shutdown) { synchronized (this) { wait(5000); // Close failed connections connMgr.closeExpiredConnections(); } } } catch (InterruptedException ex) { // End } } //Shut down thread cleaning up invalid connections public void shutdown() { shutdown = true; synchronized (this) { notifyAll(); } } }
5. Create request return result class
@Data public class HttpResult { // Response code @NonNull private Integer code; // Response body @NonNull private String body; }
6. Create specific request class
Add a general solution that may encounter problems when requesting Https and redirection
@Component public class HttpAPIService { private static CloseableHttpClient httpClient; /** * Trust SSL certificate */ static { try { SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL) .loadTrustMaterial((x, y) -> true).build(); RequestConfig config = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(5000).build(); httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext) .setSSLHostnameVerifier((x, y) -> true).build(); } catch (Exception e) { e.printStackTrace(); } } @Autowired private RequestConfig config; /** * The get request without parameters returns body if the status code is 200 and null if it is not 200 * * @param url * @return * @throws Exception */ public String doGet(String url) throws Exception { // Declare http get request HttpGet httpGet = new HttpGet(url); // Mount configuration information httpGet.setConfig(config); // Allow redirection httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true); // Initiate request CloseableHttpResponse response = this.httpClient.execute(httpGet); // Judge whether the status code is 200 if (response.getStatusLine().getStatusCode() == 200) { // Returns the contents of the response body return EntityUtils.toString(response.getEntity(), "UTF-8"); } return null; } /** * For get request with parameters, if the status code is 200, it returns body; if it is not 200, it returns null. * * @param url * @return * @throws Exception */ public String doGet(String url, Map<String, Object> map) throws Exception { URIBuilder uriBuilder = new URIBuilder(url); if (map != null) { // Traversal map, splicing request parameters for (Map.Entry<String, Object> entry : map.entrySet()) { uriBuilder.setParameter(entry.getKey(), entry.getValue().toString()); } } // Call get request without parameters return this.doGet(uriBuilder.build().toString()); } /** * @description post request with parameters * @param url * @param map * @param headers * @return com.mark.httpclient.HttpResult * @author Mario * @date 2019/7/15 14:39 */ public HttpResult doPost(String url, Map<String, Object> map , Map<String,Object> headers) throws Exception { // Declare httpPost request HttpPost httpPost = new HttpPost(url); // Add configuration information httpPost.setConfig(config); // Determine whether the map is empty or not. If it is not empty, traverse and encapsulate the from form object. if (map != null) { List<NameValuePair> list = new ArrayList<NameValuePair>(); for (Map.Entry<String, Object> entry : map.entrySet()) { list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString())); } // Construct from form object UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8"); // Put the form in the post httpPost.setEntity(urlEncodedFormEntity); } // Set request header if (headers != null) { for (String key : headers.keySet()) { String value = headers.get(key).toString(); httpPost.addHeader(key,value); } } // Initiate request CloseableHttpResponse response = this.httpClient.execute(httpPost); return new HttpResult(response.getStatusLine().getStatusCode(), EntityUtils.toString( response.getEntity(), "UTF-8")); } /** * post request without parameters * * @param url * @return * @throws Exception */ public HttpResult doPost(String url) throws Exception { return this.doPost(url, null,null); } /** * @description post request sent in JSON with parameters * @param url * @param jsonString * @param headers * @return com.mark.httpclient.HttpResult * @author Mario * @date 2019/7/15 14:39 */ public static HttpResult doPostWithJson(String url, String jsonString, Map<String,Object> headers) throws Exception { // Declare httpPost request HttpPost httpPost = new HttpPost(url); // Set request header if (headers != null) { for (String key : headers.keySet()) { String value = headers.get(key).toString(); httpPost.addHeader(key, value); } } // Set to send as Json data StringEntity stringEntity = new StringEntity(jsonString, "utf-8"); stringEntity.setContentType("application/json"); httpPost.setEntity(stringEntity); // Initiate request CloseableHttpResponse response = httpClient.execute(httpPost); return new HttpResult(response.getStatusLine().getStatusCode(), EntityUtils.toString( response.getEntity(), "UTF-8")); } }