1.为什么需要封装
httpclient原生的使用方式:
public static JSONObject getSingleDataSetDataPostInvoke(
String baseUrl, String token, Integer projectId, Integer datasetId,
String filePath, Integer offset, Integer limit) {
CloseableHttpClient httpClient = getDefaultHttpClient();
MessageFormat dataSetDataPostInvokeUrlForm = new MessageFormat(GET_SINGLE_DATASET_DATA_POST_INVOKE);
String[] args = new String[]{projectId.toString(), datasetId.toString()};
String dataSetDataPostInvokeUrl = dataSetDataPostInvokeUrlForm.format(args);
HttpPost httpPost = new HttpPost(baseUrl + dataSetDataPostInvokeUrl);
httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
httpPost.addHeader("token", token);
Map<String, Object> body = Maps.newHashMap();
body.put("filePath", filePath);
body.put("offset", offset);
body.put("limit", limit);
httpPost.setEntity(new StringEntity(Objects.requireNonNull(JSON.toJSONString(body)), Charsets.UTF_8));
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
JSONObject responseObj = JSON.parseObject(EntityUtils.toString(response.getEntity(), Charsets.UTF_8));
CheckUniverseResponse(responseObj);
response.close();
return responseObj;
} catch (IOException e) {
logger.error("获取Universe数据集数据后置调用失败, url:{}.", httpPost.getURI().toString(), e);
throw new AtlasException(UNIVERSE_FAIL_TO_GET_DATASET_DATA, e.getMessage());
}
}
缺点:硬编码设置header,params,body等,还需要解析返回值,代码的可维护性低。
钉钉和蚂蚁封装的httpclient
----DINGDING---
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dingtalk</artifactId>
<version>1.1.93</version>
</dependency>
---alipay-----
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.18.0.ALL</version>
</dependency>
支付宝源码部分:
public <T extends AlipayResponse> T execute(AlipayRequest<T> request) throws AlipayApiException {
return this.execute(request, (String)null);
}
public <T extends AlipayResponse> T execute(AlipayRequest<T> request, String accessToken) throws AlipayApiException {
return this.execute(request, accessToken, (String)null);
}
public <T extends AlipayResponse> T execute(AlipayRequest<T> request, String accessToken, String appAuthToken) throws AlipayApiException {
return this.execute(request, accessToken, appAuthToken, (String)null);
}
public <T extends AlipayResponse> T execute(AlipayRequest<T> request, String accessToken, String appAuthToken, String targetAppId) throws AlipayApiException {
if (!StringUtils.isEmpty(this.alipayRootCertSN)) {
throw new AlipayApiException("检测到证书相关参数已初始化,证书模式下请改为调用certificateExecute");
} else {
AlipayParser<T> parser = null;
if ("xml".equals(this.format)) {
parser = new ObjectXmlParser(request.getResponseClass());
} else {
parser = new ObjectJsonParser(request.getResponseClass());
}
return this._execute(request, (AlipayParser)parser, accessToken, appAuthToken, targetAppId);
}
}
public BatchAlipayResponse execute(BatchAlipayRequest request) throws AlipayApiException {
long beginTime = System.currentTimeMillis();
Map<String, Object> rt = this.doPost(request);
if (rt == null) {
return null;
} else {
Map<String, Long> costTimeMap = new HashMap();
if (rt.containsKey("prepareTime")) {
costTimeMap.put("prepareCostTime", (Long)((Long)rt.get("prepareTime")) - beginTime);
if (rt.containsKey("requestTime")) {
costTimeMap.put("requestCostTime", (Long)((Long)rt.get("requestTime")) - (Long)((Long)rt.get("prepareTime")));
}
}
AlipayParser<BatchAlipayResponse> parser = null;
if ("xml".equals(this.format)) {
parser = new ObjectXmlParser(request.getResponseClass());
} else {
parser = new ObjectJsonParser(request.getResponseClass());
}
BatchAlipayResponse batchAlipayResponse = null;
try {
ResponseEncryptItem responseItem = this.decryptResponse(request, rt, (AlipayParser)parser);
batchAlipayResponse = (BatchAlipayResponse)((AlipayParser)parser).parse(responseItem.getRealContent());
batchAlipayResponse.setBody(responseItem.getRealContent());
this.checkResponseSign(request, (AlipayParser)parser, responseItem.getRespContent(), batchAlipayResponse.isSuccess());
if (costTimeMap.containsKey("requestCostTime")) {
costTimeMap.put("postCostTime", System.currentTimeMillis() - (Long)((Long)rt.get("requestTime")));
}
List<AlipayParser<?>> parserList = new ArrayList();
List<AlipayRequestWrapper> requestList = request.getRequestList();
Iterator var11;
AlipayRequestWrapper aRequestList;
if ("xml".equals(this.format)) {
var11 = requestList.iterator();
while(var11.hasNext()) {
aRequestList = (AlipayRequestWrapper)var11.next();
parserList.add(new ObjectXmlParser(aRequestList.getAlipayRequest().getResponseClass()));
}
} else {
var11 = requestList.iterator();
while(var11.hasNext()) {
aRequestList = (AlipayRequestWrapper)var11.next();
parserList.add(new ObjectJsonParser(aRequestList.getAlipayRequest().getResponseClass()));
}
}
if (!batchAlipayResponse.isSuccess()) {
return batchAlipayResponse;
} else {
String[] responseArray = batchAlipayResponse.getResponseBody().split("#S#");
for(int index = 0; index < responseArray.length; ++index) {
AlipayResponse alipayResponse = ((AlipayParser)parserList.get(index)).parse(responseArray[index]);
alipayResponse.setBody(responseArray[index]);
batchAlipayResponse.addResponse(alipayResponse);
}
AlipayLogger.logBizDebug((String)rt.get("rsp"));
return batchAlipayResponse;
}
} catch (RuntimeException var14) {
AlipayLogger.logBizError((String)rt.get("rsp"), costTimeMap);
throw var14;
} catch (AlipayApiException var15) {
AlipayLogger.logBizError((String)rt.get("rsp"), costTimeMap);
throw new AlipayApiException(var15);
}
}
}
.......
使用:
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.open.public.template.message.industry.modify
AlipayOpenPublicTemplateMessageIndustryModifyRequest request = new AlipayOpenPublicTemplateMessageIndustryModifyRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数
//此次只是参数展示,未进行字符串转义,实际情况下请转义
request.setBizContent(" {" +
" \"primary_industry_name\":\"IT科技/IT软件与服务\"," +
" \"primary_industry_code\":\"10001/20102\"," +
" \"secondary_industry_code\":\"10001/20102\"," +
" \"secondary_industry_name\":\"IT科技/IT软件与服务\"" +
" }");
AlipayOpenPublicTemplateMessageIndustryModifyResponse response = alipayClient.execute(request);
//调用成功,则处理业务逻辑
if(response.isSuccess()){
//.....
}
钉钉源码部分:
public <T extends AliyunResponse> T _execute(AliyunRequest<T> request, AliyunParser<T> parser) throws ApiException {
if (this.needCheckRequest) {
try {
request.check();
} catch (ApiRuleException e) {
T localResponse = null;
try {
localResponse = request.getResponseClass().newInstance();
} catch (Exception xe) {
throw new ApiException(xe);
}
localResponse.setErrorCode(e.getErrCode());
localResponse.setMessage(e.getErrMsg());
return localResponse;
}
}
Map<String, Object> rt = doPost(request);
if (rt == null)
return null;
T tRsp = null;
if (this.needEnableParser) {
try {
tRsp = parser.parse((String) rt.get("rsp"));
tRsp.setBody((String) rt.get("rsp"));
} catch (RuntimeException e) {
AliyunLogger.logBizError((String) rt.get("rsp"));
throw e;
}
} else {
try {
tRsp = request.getResponseClass().newInstance();
tRsp.setBody((String) rt.get("rsp"));
} catch (Exception e) {
}
}
tRsp.setParams((TaobaoHashMap) rt.get("textParams"));
if (!tRsp.isSuccess()) {
AliyunLogger.logErrorScene(rt, tRsp, accessKeyId);
}
return tRsp;
}
public <T extends AliyunResponse> Map<String, Object> doPost(AliyunRequest<T> request) throws ApiException {
Map<String, Object> result = new HashMap<String, Object>();
RequestParametersHolder requestHolder = new RequestParametersHolder();
TaobaoHashMap appParams = new TaobaoHashMap(request.getTextParams());
requestHolder.setApplicationParams(appParams);
//
TaobaoHashMap protocalMustParams = new TaobaoHashMap();
try{
addProtocalMustParams(request, protocalMustParams);
}
catch (Exception e) {
throw new ApiException(e);
}
requestHolder.setProtocalMustParams(protocalMustParams);
TaobaoHashMap protocalOptParams = new TaobaoHashMap();
addProtocalOptParams(protocalOptParams);
requestHolder.setProtocalOptParams(protocalOptParams);
String url = null;
try {
//
protocalMustParams.put(AliyunConstants.SIGNATURE,
AliyunSignature.computeSignature(requestHolder.getAllParams(), accessKeySecret));
String query = paramsToQueryString(requestHolder.getAllParams());
url = (serverUrl.endsWith("/") ? serverUrl : (serverUrl + "/")) + "?" + query;
} catch (Exception e) {
throw new ApiException(e);
}
String rsp = null;
try {
//
if (request instanceof AliyunUploadRequest) {
AliyunUploadRequest<T> uRequest = (AliyunUploadRequest<T>) request;
Map<String, FileItem> fileParams = TaobaoUtils.cleanupMap(uRequest.getFileParams());
rsp =AliyunWebUtils.doPost(url, null, fileParams,Constants.CHARSET_UTF8, connectTimeout, readTimeout,request.getHeaderMap());
} else {
rsp = AliyunWebUtils.doPost(url, null,Constants.CHARSET_UTF8, connectTimeout, readTimeout,request.getHeaderMap());
}
} catch (IOException e) {
throw new ApiException(e);
}
result.put("rsp", rsp);
result.put("textParams", appParams);
result.put("protocalMustParams", protocalMustParams);
result.put("protocalOptParams", protocalOptParams);
result.put("url", url);
return result;
}
...
参考支付宝和钉钉,我们也可以对httpclient进行简单封装,满足我们业务需要的同时,使使用起来更简单,可维护性更好。
2.封装源码
package com.alibaba.fetchdata.common.http;
import com.alibaba.fastjson.JSON;
import com.alibaba.fetchdata.common.http.base.BaseHttpRequest;
import com.alibaba.fetchdata.common.http.base.BaseHttpResponse;
import com.alibaba.fetchdata.common.http.common.HttpTemplateException;
import com.alibaba.fetchdata.common.http.common.HttpTemplateUtils;
import com.alibaba.fetchdata.common.http.common.Method;
import com.alibaba.fetchdata.common.http.config.HttpTemplateConfig;
import com.alibaba.fetchdata.common.http.config.RouteConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.routing.HttpRoute;
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.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Slf4j
public class HttpTemplate {
private CloseableHttpClient httpClient;
private HttpTemplateHandler httpTemplateHandler;
private Map<String, RouteConfig> routes;
public HttpTemplate(HttpTemplateConfig httpTemplateConfig, HttpTemplateHandler httpTemplateHandler) {
if (httpTemplateConfig == null) {
this.httpClient = createHttpClient(new HttpTemplateConfig(null));
this.routes = Collections.emptyMap();
} else {
this.httpClient = createHttpClient(httpTemplateConfig);
this.routes = httpTemplateConfig.getRoutes();
}
if (httpTemplateHandler == null) {
this.httpTemplateHandler = new HttpTemplateHandler() {
};
} else {
this.httpTemplateHandler = httpTemplateHandler;
}
}
public <T extends BaseHttpResponse> T execute(BaseHttpRequest<T> baseHttpRequest) throws Exception {
HttpGet httpGet = null;
HttpPost httpPost = null;
BaseHttpResponse baseHttpResponse = null;
if (baseHttpRequest == null)
throw new IllegalArgumentException("request is null");
if (baseHttpRequest.getResponseClass() == null)
throw new IllegalArgumentException("HttpTemplate ResponseClass is null");
if (!this.httpTemplateHandler.onStart(baseHttpRequest))
return (T)HttpTemplateUtils.newResponse(baseHttpRequest, "HttpTemplate request deny");
if (!baseHttpRequest.check())
return (T) HttpTemplateUtils.newResponse(baseHttpRequest, "HttpTemplate request check fail");
RouteConfig routeConfig = this.routes.get(baseHttpRequest.getRoute());
if (routeConfig == null) {
routeConfig = new RouteConfig(baseHttpRequest.getIp())
.setScheme(baseHttpRequest.getScheme())
.setPort(baseHttpRequest.getPort())
.setConnectionRequestTimeout(5000)
.setConnectTimeout(10000)
.setSocketTimeout(30000)
.setMaxPerRoute(400);
}
if (baseHttpRequest.getMethod() == Method.POST) {
httpPost = buildHttpPost(baseHttpRequest, routeConfig);
} else if (baseHttpRequest.getMethod() == Method.UPLOAD) {
httpPost = buildHttpUpload(baseHttpRequest, routeConfig);
} else {
httpGet = buildHttpGet(baseHttpRequest, routeConfig);
}
try {
if (httpGet != null) {
baseHttpResponse = this.httpClient.execute(httpGet, response -> parseResponse(baseHttpRequest, response));
} else if (httpPost != null) {
baseHttpResponse = this.httpClient.execute(httpPost, response -> parseResponse(baseHttpRequest, response));
}
} catch (IOException e) {
this.httpTemplateHandler.onFinish(baseHttpRequest, (T)HttpTemplateUtils.newResponse(baseHttpRequest, "exception occur"), e);
throw e;
}
this.httpTemplateHandler.onFinish(baseHttpRequest, (T)baseHttpResponse, null);
return (T)baseHttpResponse;
}
private <T extends BaseHttpResponse> T parseResponse(BaseHttpRequest<T> baseHttpRequest, HttpResponse httpResponse) throws IOException {
HttpEntity httpEntity = httpResponse.getEntity();
String body = EntityUtils.toString(httpEntity, "utf-8");
try {
BaseHttpResponse baseHttpResponse = JSON.parseObject(body, baseHttpRequest.getResponseClass());
if (baseHttpResponse == null)
return (T)HttpTemplateUtils.newResponse(baseHttpRequest, null);
baseHttpResponse.addHttpInfo(httpResponse.getStatusLine(), httpResponse.getAllHeaders(), body);
return (T)baseHttpResponse;
} catch (Exception e) {
log.error("返回的body为:{}", body);
return (T)HttpTemplateUtils.newResponse(baseHttpRequest, body);
}
}
private HttpPost buildHttpPost(BaseHttpRequest<?> request, RouteConfig routeConfig) throws HttpTemplateException {
HttpPost httpPost = new HttpPost(getUri(request, routeConfig));
Map<String, Object> body = request.getBody();
if (null != body) {
StringEntity entity = new StringEntity(JSON.toJSONString(body), "UTF-8");
httpPost.setEntity(entity);
}
setRequestHeader(httpPost, request.getHeaders());
setTimeout(httpPost, routeConfig);
return httpPost;
}
private HttpPost buildHttpUpload(BaseHttpRequest<?> request, RouteConfig routeConfig) throws HttpTemplateException {
HttpPost httpPost = new HttpPost(getUri(request, routeConfig));
Map<String, File> fileItems = request.getFileItems();
Set<Map.Entry<String, File>> entries = fileItems.entrySet();
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entries.forEach(s -> entityBuilder.addBinaryBody(s.getKey(), s.getValue()));
httpPost.setEntity(entityBuilder.build());
setRequestHeader(httpPost, request.getHeaders());
setTimeout(httpPost, routeConfig);
return httpPost;
}
private HttpGet buildHttpGet(BaseHttpRequest<?> request, RouteConfig routeConfig) throws HttpTemplateException {
HttpGet httpGet = new HttpGet(getUri(request, routeConfig));
setRequestHeader(httpGet, request.getHeaders());
setTimeout(httpGet, routeConfig);
return httpGet;
}
private URI getUri(BaseHttpRequest<?> request, RouteConfig routeConfig) throws HttpTemplateException {
URIBuilder uriBuilder = new URIBuilder().setScheme(routeConfig.getScheme()).setHost(routeConfig.getHostname()).setPort(routeConfig.getPort()).setPath(request.getPath());
Map<String, String> queryParams = request.getQueryParams();
if (null != queryParams)
for (Map.Entry<String, String> entry : queryParams.entrySet())
uriBuilder.setParameter(entry.getKey(), entry.getValue());
try {
return uriBuilder.build();
} catch (URISyntaxException e) {
throw new HttpTemplateException("请求路径不合法", e);
}
}
private void setRequestHeader(HttpRequestBase httpRequestBase, Map<String, String> header) {
if (header != null)
for (Map.Entry<String, String> entry : header.entrySet())
httpRequestBase.setHeader(entry.getKey(), entry.getValue());
}
private void setTimeout(HttpRequestBase httpRequestBase, RouteConfig routeConfig) {
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(routeConfig.getConnectionRequestTimeout()).setConnectTimeout(routeConfig.getConnectTimeout()).setSocketTimeout(routeConfig.getSocketTimeout()).build();
httpRequestBase.setConfig(requestConfig);
}
private CloseableHttpClient createHttpClient(HttpTemplateConfig httpTemplateConfig) {
RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
Registry<ConnectionSocketFactory> registry = registryBuilder
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory()).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(httpTemplateConfig.getMaxTotal());
cm.setDefaultMaxPerRoute(httpTemplateConfig.getDefaultMaxPerRoute());
Map<String, RouteConfig> routes = httpTemplateConfig.getRoutes();
if (routes != null)
routes.forEach((name, routeConfig) -> {
HttpRoute route = HttpTemplateUtils.determineRoute(routeConfig.getHostname(), routeConfig.getPort(), routeConfig.getScheme());
cm.setMaxPerRoute(route, routeConfig.getMaxPerRoute());
});
return HttpClients.custom()
.setConnectionManager(cm)
.evictIdleConnections(30, TimeUnit.SECONDS)
.evictExpiredConnections()
.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
.build();
}
public CloseableHttpClient getClient() {
return this.httpClient;
}
}
package com.alibaba.fetchdata.common.http;
import com.alibaba.fetchdata.common.http.base.BaseHttpRequest;
import com.alibaba.fetchdata.common.http.base.BaseHttpResponse;
public interface HttpTemplateHandler {
default boolean onStart(BaseHttpRequest<?> baseHttpRequest) {
return true;
}
default <T extends BaseHttpResponse> void onFinish(BaseHttpRequest<T> baseHttpRequest, T baseHttpResponse, Exception e) {}
}
package com.alibaba.fetchdata.common.http.config;
import java.util.HashMap;
import java.util.Map;
public class HttpTemplateConfig {
private int maxTotal;
private int defaultMaxPerRoute;
private Map<String, RouteConfig> routes;
public HttpTemplateConfig(Map<String, RouteConfig> routes) {
if (routes == null) {
this.routes = new HashMap<>(0);
} else {
this.routes = routes;
}
this.maxTotal = 100;
this.defaultMaxPerRoute = 100;
}
public int getMaxTotal() {
return this.maxTotal;
}
public HttpTemplateConfig setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
return this;
}
public int getDefaultMaxPerRoute() {
return this.defaultMaxPerRoute;
}
public HttpTemplateConfig setDefaultMaxPerRoute(int defaultMaxPerRoute) {
this.defaultMaxPerRoute = defaultMaxPerRoute;
return this;
}
public Map<String, RouteConfig> getRoutes() {
return this.routes;
}
public HttpTemplateConfig setRoutes(Map<String, RouteConfig> routes) {
this.routes = routes;
return this;
}
}
package com.alibaba.fetchdata.common.http.config;
public class RouteConfig {
private String hostname;
private int port;
private String scheme;
private int maxPerRoute;
private int connectionRequestTimeout;
private int connectTimeout;
private int socketTimeout;
public RouteConfig(String hostname) {
this.hostname = hostname;
this.port = -1;
this.scheme = "https";
this.maxPerRoute = 100;
this.connectionRequestTimeout = 1000;
this.connectTimeout = 3000;
this.socketTimeout = 6000;
}
public RouteConfig(String hostname, int port, String scheme) {
this.hostname = hostname;
this.port = port;
this.scheme = scheme;
this.maxPerRoute = 100;
this.connectionRequestTimeout = 1000;
this.connectTimeout = 3000;
this.socketTimeout = 6000;
}
public String getScheme() {
return this.scheme;
}
public RouteConfig setScheme(String scheme) {
this.scheme = scheme;
return this;
}
public String getHostname() {
return this.hostname;
}
public RouteConfig setHostname(String hostname) {
this.hostname = hostname;
return this;
}
public int getPort() {
return this.port;
}
public RouteConfig setPort(int port) {
this.port = port;
return this;
}
public int getMaxPerRoute() {
return this.maxPerRoute;
}
public RouteConfig setMaxPerRoute(int maxPerRoute) {
this.maxPerRoute = maxPerRoute;
return this;
}
public int getConnectionRequestTimeout() {
return this.connectionRequestTimeout;
}
public RouteConfig setConnectionRequestTimeout(int connectionRequestTimeout) {
this.connectionRequestTimeout = connectionRequestTimeout;
return this;
}
public int getConnectTimeout() {
return this.connectTimeout;
}
public RouteConfig setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
}
public int getSocketTimeout() {
return this.socketTimeout;
}
public RouteConfig setSocketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
return this;
}
}
package com.alibaba.fetchdata.common.http.base;
import com.alibaba.fetchdata.common.http.common.Method;
import java.io.File;
import java.util.Map;
public abstract class BaseHttpRequest<T extends BaseHttpResponse> {
public abstract Map<String, String> getQueryParams();
public abstract Map<String, Object> getBody();
public abstract Map<String, File> getFileItems();
public abstract Map<String, String> getHeaders();
public abstract Map<String, String> getBizMap();
public abstract String getName();
public abstract String getRoute();
public abstract Method getMethod();
public abstract String getPath();
public abstract Class<T> getResponseClass();
public abstract boolean check();
public String getDomain(){
return null;
}
public String getIp() {
return null;
}
public Integer getPort() {
return null;
}
public String getScheme() {
return "https";
}
}
package com.alibaba.fetchdata.common.http.base;
import org.apache.http.Header;
import org.apache.http.StatusLine;
public abstract class BaseHttpResponse {
private StatusLine statusLine;
private Header[] headers;
private String body;
public abstract boolean success();
public abstract String code();
public StatusLine statusLine() {
return this.statusLine;
}
public Header[] headers() {
return this.headers;
}
public String body() {
return this.body;
}
public void addHttpInfo(StatusLine statusLine, Header[] headers, String body) {
this.statusLine = statusLine;
this.headers = headers;
this.body = body;
}
}
package com.alibaba.fetchdata.common.http.common;
public class Constants {
public static final String SECURE_SCHEME = "https";
public static final int DEFAULT_PORT = -1;
public static final int MAX_TOTAL = 100;
public static final int DEFAULT_MAX_PER_ROUTE = 100;
public static final int MAX_PER_ROUTE = 100;
public static final int CONNECTION_REQUEST_TIMEOUT = 1000;
public static final int CONNECTION_TIMEOUT = 3000;
public static final int SOCKET_TIMEOUT = 6000;
}
package com.alibaba.fetchdata.common.http.common;
public class HttpTemplateException extends Exception{
public HttpTemplateException() {}
public HttpTemplateException(String message) {
super(message);
}
public HttpTemplateException(String message, Throwable cause) {
super(message, cause);
}
public HttpTemplateException(Throwable cause) {
super(cause);
}
}
package com.alibaba.fetchdata.common.http.common;
import com.alibaba.fetchdata.common.http.base.BaseHttpRequest;
import com.alibaba.fetchdata.common.http.base.BaseHttpResponse;
import org.apache.http.HttpHost;
import org.apache.http.conn.routing.HttpRoute;
public class HttpTemplateUtils {
public static <T extends BaseHttpResponse> T newResponse(BaseHttpRequest<T> baseHttpRequest, String message) {
if (baseHttpRequest == null)
throw new IllegalArgumentException("Request is null");
if (baseHttpRequest.getResponseClass() == null)
throw new IllegalArgumentException("ResponseClass is null");
try {
BaseHttpResponse baseHttpResponse = baseHttpRequest.getResponseClass().newInstance();
baseHttpResponse.addHttpInfo(null, null, message);
return (T)baseHttpResponse;
} catch (Exception e) {
throw new IllegalArgumentException("ResponseClass can't be instantiated", e);
}
}
public static HttpRoute determineRoute(String hostname, int port, String scheme) {
int determinePort;
boolean secure = "https".equalsIgnoreCase(scheme);
if (port < 0) {
determinePort = secure ? 443 : 80;
} else {
determinePort = port;
}
HttpHost httpHost = new HttpHost(hostname, determinePort, scheme);
return new HttpRoute(httpHost, null, secure);
}
}
package com.alibaba.fetchdata.common.http.common;
public enum Method {
GET, POST, UPLOAD;
}
3.项目中使用
1.配置路由:
package com.alibaba.fetchdata.controller.config;
import com.google.common.collect.Maps;
import com.alibaba.fetchdata.common.http.HttpTemplate;
import com.alibaba.fetchdata.common.http.HttpTemplateHandler;
import com.alibaba.fetchdata.common.http.base.BaseHttpRequest;
import com.alibaba.fetchdata.common.http.base.BaseHttpResponse;
import com.alibaba.fetchdata.common.http.config.HttpTemplateConfig;
import com.alibaba.fetchdata.common.http.config.RouteConfig;
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @author dxc
**/
@Configuration
public class HttpConfig {
private Logger logger = LoggerFactory.getLogger(HttpConfig.class);
@Bean
public HttpTemplateConfig getHttpTemplateConfig() {
RouteConfig dingTalkRouteConfig = new RouteConfig("oapi.dingtalk.com")
.setConnectionRequestTimeout(5000)
.setConnectTimeout(3000)
.setSocketTimeout(3000)
.setMaxPerRoute(400);
Map<String, RouteConfig> routes = Maps.newHashMap();
routes.put("dingTalk", dingTalkRouteConfig);
return new HttpTemplateConfig(routes).setMaxTotal(500).setDefaultMaxPerRoute(40);
}
@Bean
public HttpTemplate httpTemplate() {
return new HttpTemplate(getHttpTemplateConfig(), new HttpTemplateHandler() {
@Override
public boolean onStart(BaseHttpRequest<?> baseHttpRequest) {
return true;
}
@Override
public <T extends BaseHttpResponse> void onFinish(BaseHttpRequest<T> baseHttpRequest, T baseHttpResponse, Exception e) {
}
});
}
}
2.request配置:
package com.alibaba.fetchdata.client.cloudpatrol;
import com.google.common.collect.Maps;
import com.alibaba.fetchdata.common.http.common.Method;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.Map;
@Data
public class DingtalkRequest extends BaseCloudPatrolRequest<DingtalkResponse> {
private String profile;
private String authorization;
@Override
public Map<String, String> getQueryParams() {
return null;
}
@Override
public Map<String, Object> getBody() {
Map<String, Object> body = Maps.newHashMap();
body.put("profile", profile);
return body;
}
@Override
public Map<String, File> getFileItems() {
return null;
}
@Override
public Map<String, String> getHeaders() {
Map<String, String> headers = Maps.newHashMap();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json");
headers.put("auth", authorization);
return headers;
}
@Override
public Map<String, String> getBizMap() {
return null;
}
@Override
public String getName() {
return null;
}
@Override
public Method getMethod() {
return Method.POST;
}
@Override
public String getPath() {
return "/api/report/getLastSuccessReport";
}
@Override
public Class<LastSuccessReportResponse> getResponseClass() {
return LastSuccessReportResponse.class;
}
@Override
public boolean check() {
return StringUtils.isNotBlank(profile) && StringUtils.isNotBlank(authorization);
}
@Override
public String getScheme() {
return "http";
}
}
package com.alibaba.fetchdata.client.cloudpatrol;
import com.alibaba.fetchdata.common.http.base.BaseHttpRequest;
public abstract class BaseDingtalkRequest<T extends BaseDingtalkResponse> extends BaseHttpRequest<T> {
@Override
public String getRoute() {
return "dingtalk";
}
}
3.response配置:
package com.alibaba.fetchdata.client.cloudpatrol;
public class DingtalkResponse extends BaseDingtalkResponse{
}
package com.alibaba.fetchdata.client.cloudpatrol;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fetchdata.common.http.base.BaseHttpResponse;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
@Data
public class BaseDingtalkResponse extends BaseHttpResponse {
@JSONField(name = "code")
private Integer code;
@JSONField(name = "msg")
private String msg;
@JSONField(name = "data")
private JSONObject data;
@Override
public boolean success() {
return code != null && code == 0 && (StringUtils.isBlank(msg) || ("success").equals(msg));
}
@Override
public String code() {
return null;
}
}
4.调用方式:
@Autowired
private HttpTemplate httpTemplate;
public static void main(String[] args) {
DingtalkRequest request = new DingtalkRequest();
request.setProfile(profile.getProfile());
request.setAuthorization("233444");
DingtalkResponse response = httpTemplate.execute(request);
if (response == null || !response.success()) {
String errorMsg = response == null ? null : response.getMsg();
throw new FetchDataException(ErrorCode.UN_KNOW.getCode(), errorMsg);
}
}