美文网首页
httpclient封装

httpclient封装

作者: 定金喜 | 来源:发表于2023-01-20 17:17 被阅读0次

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

    相关文章

      网友评论

          本文标题:httpclient封装

          本文链接:https://www.haomeiwen.com/subject/uqtchdtx.html