前言
为了支持多种HTTP客户端,可以使用接口和策略模式。我们可以创建一个HTTP客户端接口,并为Apache HttpClient和JDK 11 HttpClient分别实现这个接口。这样,可以根据需要切换不同的HTTP客户端实现。
接口定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package cn.idea360.assistant.dev.utils;
import java.io.IOException;
public interface HttpClientService {
String sendGet(String url) throws IOException;
String sendPost(String url, String json) throws IOException;
String sendPut(String url, String json) throws IOException;
String sendDelete(String url) throws IOException;
}
|
ApacheHttpClientService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| package cn.idea360.assistant.dev.utils;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.*; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import java.io.IOException;
public class ApacheHttpClientService implements HttpClientService {
private static final Logger logger = LoggerFactory.getLogger(ApacheHttpClientService.class);
private static final int MAX_TOTAL_CONNECTIONS = 300; private static final int MAX_PER_ROUTE = 100; private static final int CONNECTION_TIMEOUT = 5000; private static final int REQUEST_TIMEOUT = 5000; private static final int SOCKET_TIMEOUT = 5000;
private static final CloseableHttpClient httpClient;
static { PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setMaxTotal(MAX_TOTAL_CONNECTIONS); connManager.setDefaultMaxPerRoute(MAX_PER_ROUTE);
RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(CONNECTION_TIMEOUT) .setConnectionRequestTimeout(REQUEST_TIMEOUT) .setSocketTimeout(SOCKET_TIMEOUT) .build();
httpClient = HttpClients.custom() .setConnectionManager(connManager) .setDefaultRequestConfig(requestConfig) .build(); }
public ApacheHttpClientService() { }
@Override public String sendGet(String url) throws IOException { HttpGet request = new HttpGet(url); return sendRequest(request); }
@Override public String sendPost(String url, String json) throws IOException { HttpPost request = new HttpPost(url); setEntity(request, json); return sendRequest(request); }
@Override public String sendPut(String url, String json) throws IOException { HttpPut request = new HttpPut(url); setEntity(request, json); return sendRequest(request); }
@Override public String sendDelete(String url) throws IOException { HttpDelete request = new HttpDelete(url); return sendRequest(request); }
private static String sendRequest(HttpUriRequest request) throws IOException { try (CloseableHttpResponse response = httpClient.execute(request)) { int statusCode = response.getStatusLine().getStatusCode(); HttpEntity entity = response.getEntity(); String result = entity != null ? EntityUtils.toString(entity) : null;
if (statusCode >= HttpStatus.SC_OK && statusCode < HttpStatus.SC_MULTIPLE_CHOICES) { return result; } else { handleErrorResponse(request, statusCode); throw new IOException("请求失败, URL: " + request.getURI() + ", 状态码: " + statusCode); } } catch (IOException e) { logger.error("请求失败, URL: {}, 原因: {}", request.getURI(), ExceptionUtils.getStackTrace(e)); throw e; } }
private static void setEntity(HttpEntityEnclosingRequestBase request, String json) { request.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON)); }
private static void handleErrorResponse(HttpUriRequest request, int statusCode) throws IOException { logger.error("请求失败, URL: {}, 状态码: {}", request.getURI(), statusCode); }
}
|
JdkHttpClientService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| package cn.idea360.assistant.dev.utils;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration;
public class JdkHttpClientService implements HttpClientService {
private static final Logger logger = LoggerFactory.getLogger(JdkHttpClientService.class);
private static final int TIMEOUT = 5000;
private static final HttpClient httpClient;
static { httpClient = HttpClient.newBuilder() .connectTimeout(Duration.ofMillis(TIMEOUT)) .build(); }
@Override public String sendGet(String url) throws IOException { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .GET() .build(); return sendRequest(request); }
@Override public String sendPost(String url, String json) throws IOException { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .POST(HttpRequest.BodyPublishers.ofString(json)) .header("Content-Type", "application/json") .build(); return sendRequest(request); }
@Override public String sendPut(String url, String json) throws IOException { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .PUT(HttpRequest.BodyPublishers.ofString(json)) .header("Content-Type", "application/json") .build(); return sendRequest(request); }
@Override public String sendDelete(String url) throws IOException { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .DELETE() .build(); return sendRequest(request); }
private String sendRequest(HttpRequest request) throws IOException { try { HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); int statusCode = response.statusCode(); String result = response.body();
if (statusCode >= 200 && statusCode < 300) { return result; } else { handleErrorResponse(request, statusCode); throw new IOException("请求失败, URL: " + request.uri() + ", 状态码: " + statusCode); } } catch (InterruptedException e) { logger.error("请求被中断, URL: {}, 原因: {}", request.uri(), e.getMessage()); Thread.currentThread().interrupt(); throw new IOException("请求被中断, URL: " + request.uri(), e); } catch (IOException e) { logger.error("请求失败, URL: {}, 原因: {}", request.uri(), ExceptionUtils.getStackTrace(e)); throw e; } }
private void handleErrorResponse(HttpRequest request, int statusCode) { logger.error("请求失败, URL: {}, 状态码: {}", request.uri(), statusCode); } }
|
工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package cn.idea360.assistant.dev.utils;
public class HttpClientFactory { public static HttpClientService createHttpClientService(String clientType) { if ("apache".equalsIgnoreCase(clientType)) { return new ApacheHttpClientService(); } else if ("jdk".equalsIgnoreCase(clientType)) { return new JdkHttpClientService(); } else { throw new IllegalArgumentException("Unsupported client type: " + clientType); } } }
|