Nacos封装通用HttpClient详解
一、Nacos下Http请求设计众多处理模块处理
包括更新、Prometheus监控等众多功能
Nacos对这块做了统一封装,扩展性也很好,有新旧版本和同步和异步版本。
二、具体封装模块
1、引入依赖如下.
<dependency> <groupId>com.alibaba.boot</groupId> <artifactId>nacos-discovery-spring-boot-starter</artifactId> <version>0.2.12</version> </dependency>
2、旧Http模块.
HttpAgent.
package com.alibaba.nacos.client.config.http; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.lifecycle.Closeable; import java.util.Map; /** * HttpAgent. * * @author Nacos */ public interface HttpAgent extends Closeable { /** * start to get nacos ip list. * * @throws NacosException on get ip list error. */ void start() throws NacosException; /** * invoke http get method. * * @param path http path * @param headers http headers * @param paramValues http paramValues http * @param encoding http encode * @param readTimeoutMs http timeout * @return HttpResult http response * @throws Exception If an input or output exception occurred */ HttpRestResult<String> httpGet(String path, Map<String, String> headers, Map<String, String> paramValues, String encoding, long readTimeoutMs) throws Exception; /** * invoke http post method. * * @param path http path * @param headers http headers * @param paramValues http paramValues http * @param encoding http encode * @param readTimeoutMs http timeout * @return HttpResult http response * @throws Exception If an input or output exception occurred */ HttpRestResult<String> httpPost(String path, Map<String, String> headers, Map<String, String> paramValues, String encoding, long readTimeoutMs) throws Exception;
ServerHttpAgent.[Server服务内部调用,后续版本要下线,比较重量级,不够灵活]
package com.alibaba.nacos.client.config.http; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.config.impl.ConfigHttpClientManager; import com.alibaba.nacos.client.config.impl.ServerListManager; import com.alibaba.nacos.client.utils.ContextPathUtil; import com.alibaba.nacos.client.utils.LogUtils; import com.alibaba.nacos.client.utils.ParamUtil; import com.alibaba.nacos.common.http.HttpClientConfig; import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.http.client.NacosRestTemplate; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.utils.ExceptionUtil; import org.slf4j.Logger; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; import java.util.Map; import java.util.Properties; /** * Server Agent. * * @author water.lyl */ public class ServerHttpAgent implements HttpAgent { private static final Logger LOGGER = LogUtils.logger(ServerHttpAgent.class); private static final NacosRestTemplate NACOS_RESTTEMPLATE = ConfigHttpClientManager.getInstance() .getNacosRestTemplate(); private String encode; private int maxRetry = 3; final ServerListManager serverListMgr; @Override public HttpRestResult<String> httpGet(String path, Map<String, String> headers, Map<String, String> paramValues, String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; String currentServerAddr = serverListMgr.getCurrentServerAddr(); int maxRetry = this.maxRetry; HttpClientConfig httpConfig = HttpClientConfig.builder() .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) .setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(100)).build(); do { try { Header newHeaders = Header.newInstance(); if (headers != null) { newHeaders.addAll(headers); } Query query = Query.newInstance().initParams(paramValues); HttpRestResult<String> result = NACOS_RESTTEMPLATE .get(getUrl(currentServerAddr, path), httpConfig, newHeaders, query, String.class); if (isFail(result)) { LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", serverListMgr.getCurrentServerAddr(), result.getCode()); } else { // Update the currently available server addr serverListMgr.updateCurrentServerAddr(currentServerAddr); return result; } } catch (ConnectException connectException) { LOGGER.error("[NACOS ConnectException httpGet] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), connectException.getMessage()); } catch (SocketTimeoutException socketTimeoutException) { LOGGER.error("[NACOS SocketTimeoutException httpGet] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), socketTimeoutException.getMessage()); } catch (Exception ex) { LOGGER.error("[NACOS Exception httpGet] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ex); throw ex; } if (serverListMgr.getIterator().hasNext()) { currentServerAddr = serverListMgr.getIterator().next(); } else { maxRetry--; if (maxRetry < 0) { throw new ConnectException( "[NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached"); } serverListMgr.refreshCurrentServerAddr(); } } while (System.currentTimeMillis() <= endTime); LOGGER.error("no available server"); throw new ConnectException("no available server"); } @Override public HttpRestResult<String> httpPost(String path, Map<String, String> headers, Map<String, String> paramValues, String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; String currentServerAddr = serverListMgr.getCurrentServerAddr(); int maxRetry = this.maxRetry; HttpClientConfig httpConfig = HttpClientConfig.builder() .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) .setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(3000)).build(); do { try { Header newHeaders = Header.newInstance(); if (headers != null) { newHeaders.addAll(headers); } HttpRestResult<String> result = NACOS_RESTTEMPLATE .postForm(getUrl(currentServerAddr, path), httpConfig, newHeaders, paramValues, String.class); if (isFail(result)) { LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", currentServerAddr, result.getCode()); } else { // Update the currently available server addr serverListMgr.updateCurrentServerAddr(currentServerAddr); return result; } } catch (ConnectException connectException) { LOGGER.error("[NACOS ConnectException httpPost] currentServerAddr: {}, err : {}", currentServerAddr, connectException.getMessage()); } catch (SocketTimeoutException socketTimeoutException) { LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {}, err : {}", currentServerAddr, socketTimeoutException.getMessage()); } catch (Exception ex) { LOGGER.error("[NACOS Exception httpPost] currentServerAddr: " + currentServerAddr, ex); throw ex; } if (serverListMgr.getIterator().hasNext()) { currentServerAddr = serverListMgr.getIterator().next(); } else { maxRetry--; if (maxRetry < 0) { throw new ConnectException( "[NACOS HTTP-POST] The maximum number of tolerable server reconnection errors has been reached"); } serverListMgr.refreshCurrentServerAddr(); } } while (System.currentTimeMillis() <= endTime); LOGGER.error("no available server, currentServerAddr : {}", currentServerAddr); throw new ConnectException("no available server, currentServerAddr : " + currentServerAddr); } @Override public HttpRestResult<String> httpDelete(String path, Map<String, String> headers, Map<String, String> paramValues, String encode, long readTimeoutMs) throws Exception { final long endTime = System.currentTimeMillis() + readTimeoutMs; String currentServerAddr = serverListMgr.getCurrentServerAddr(); int maxRetry = this.maxRetry; HttpClientConfig httpConfig = HttpClientConfig.builder() .setReadTimeOutMillis(Long.valueOf(readTimeoutMs).intValue()) .setConTimeOutMillis(ConfigHttpClientManager.getInstance().getConnectTimeoutOrDefault(100)).build(); do { try { Header newHeaders = Header.newInstance(); if (headers != null) { newHeaders.addAll(headers); } Query query = Query.newInstance().initParams(paramValues); HttpRestResult<String> result = NACOS_RESTTEMPLATE .delete(getUrl(currentServerAddr, path), httpConfig, newHeaders, query, String.class); if (isFail(result)) { LOGGER.error("[NACOS ConnectException] currentServerAddr: {}, httpCode: {}", serverListMgr.getCurrentServerAddr(), result.getCode()); } else { // Update the currently available server addr serverListMgr.updateCurrentServerAddr(currentServerAddr); return result; } } catch (ConnectException connectException) { LOGGER.error("[NACOS ConnectException httpDelete] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), ExceptionUtil.getStackTrace(connectException)); } catch (SocketTimeoutException stoe) { LOGGER.error("[NACOS SocketTimeoutException httpDelete] currentServerAddr:{}, err : {}", serverListMgr.getCurrentServerAddr(), ExceptionUtil.getStackTrace(stoe)); } catch (Exception ex) { LOGGER.error("[NACOS Exception httpDelete] currentServerAddr: " + serverListMgr.getCurrentServerAddr(), ex); throw ex; } if (serverListMgr.getIterator().hasNext()) { currentServerAddr = serverListMgr.getIterator().next(); } else { maxRetry--; if (maxRetry < 0) { throw new ConnectException( "[NACOS HTTP-DELETE] The maximum number of tolerable server reconnection errors has been reached"); } serverListMgr.refreshCurrentServerAddr(); } } while (System.currentTimeMillis() <= endTime); LOGGER.error("no available server"); throw new ConnectException("no available server"); } private String getUrl(String serverAddr, String relativePath) { return serverAddr + ContextPathUtil.normalizeContextPath(serverListMgr.getContentPath()) + relativePath; } private boolean isFail(HttpRestResult<String> result) { return result.getCode() == HttpURLConnection.HTTP_INTERNAL_ERROR || result.getCode() == HttpURLConnection.HTTP_BAD_GATEWAY || result.getCode() == HttpURLConnection.HTTP_UNAVAILABLE; } public static String getAppname() { return ParamUtil.getAppName(); } public ServerHttpAgent(ServerListManager mgr) { this.serverListMgr = mgr; } public ServerHttpAgent(ServerListManager mgr, Properties properties) { this.serverListMgr = mgr; } public ServerHttpAgent(Properties properties) throws NacosException { this.serverListMgr = new ServerListManager(properties); } @Override public void start() throws NacosException { serverListMgr.start(); } @Override public String getName() { return serverListMgr.getName(); } @Override public String getNamespace() { return serverListMgr.getNamespace(); } @Override public String getTenant() { return serverListMgr.getTenant(); } @Override public String getEncode() { return encode; } @Override public void shutdown() throws NacosException { String className = this.getClass().getName(); LOGGER.info("{} do shutdown begin", className); ConfigHttpClientManager.getInstance().shutdown(); LOGGER.info("{} do shutdown stop", className); } }
RestResult响应.
package com.alibaba.nacos.common.model; import java.io.Serializable; /** * Rest result. * * @author <a href="mailto:liaochuntao@live.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >liaochuntao</a> */ public class RestResult<T> implements Serializable { private static final long serialVersionUID = 6095433538316185017L; private int code; private String message; private T data; public RestResult() { } public RestResult(int code, String message, T data) { this.code = code; this.setMessage(message); this.data = data; } public RestResult(int code, T data) { this.code = code; this.data = data; } public RestResult(int code, String message) { this.code = code; this.setMessage(message); } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } public boolean ok() { return this.code == 0 || this.code == 200; } @Override public String toString() { return "RestResult{" + "code=" + code + ", message='" + message + '\'' + ", data=" + data + '}'; } public static <T> ResResultBuilder<T> builder() { return new ResResultBuilder<T>(); } public static final class ResResultBuilder<T> { private int code; private String errMsg; private T data; private ResResultBuilder() { } public ResResultBuilder<T> withCode(int code) { this.code = code; return this; } public ResResultBuilder<T> withMsg(String errMsg) { this.errMsg = errMsg; return this; } public ResResultBuilder<T> withData(T data) { this.data = data; return this; } /** * Build result. * * @return result */ public RestResult<T> build() { RestResult<T> restResult = new RestResult<T>(); restResult.setCode(code); restResult.setMessage(errMsg); restResult.setData(data); return restResult; } } }
HttpRestResult.
import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.model.RestResult; /** * Http RestResult. * * @author mai.jh */ public class HttpRestResult<T> extends RestResult<T> { private static final long serialVersionUID = 3766947816720175947L; private Header header; public HttpRestResult() { } public HttpRestResult(Header header, int code, T data, String message) { super(code, message, data); this.header = header; } public Header getHeader() { return header; } public void setHeader(Header header) { this.header = header; } }
RestResultUtils
package com.alibaba.nacos.common.model; import com.alibaba.nacos.common.model.core.IResultCode; /** * Rest result utils. * * @author <a href="mailto:liaochuntao@live.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >liaochuntao</a> */ public class RestResultUtils { public static <T> RestResult<T> success() { return RestResult.<T>builder().withCode(200).build(); } public static <T> RestResult<T> success(T data) { return RestResult.<T>builder().withCode(200).withData(data).build(); } public static <T> RestResult<T> success(String msg, T data) { return RestResult.<T>builder().withCode(200).withMsg(msg).withData(data).build(); } public static <T> RestResult<T> success(int code, T data) { return RestResult.<T>builder().withCode(code).withData(data).build(); } public static <T> RestResult<T> failed() { return RestResult.<T>builder().withCode(500).build(); } public static <T> RestResult<T> failed(String errMsg) { return RestResult.<T>builder().withCode(500).withMsg(errMsg).build(); } public static <T> RestResult<T> failed(int code, T data) { return RestResult.<T>builder().withCode(code).withData(data).build(); } public static <T> RestResult<T> failed(int code, T data, String errMsg) { return RestResult.<T>builder().withCode(code).withData(data).withMsg(errMsg).build(); } public static <T> RestResult<T> failedWithMsg(int code, String errMsg) { return RestResult.<T>builder().withCode(code).withMsg(errMsg).build(); } public static <T> RestResult<T> buildResult(IResultCode resultCode, T data) { return RestResult.<T>builder().withCode(resultCode.getCode()).withMsg(resultCode.getCodeMsg()).withData(data).build(); } }
MediaType
/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.nacos.common.http.param; import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.common.utils.StringUtils; /** * Http Media type. * * @author <a href="mailto:liaochuntao@live.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >liaochuntao</a> */ public final class MediaType { public static final String APPLICATION_ATOM_XML = "application/atom+xml"; public static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded;charset=UTF-8"; public static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; public static final String APPLICATION_SVG_XML = "application/svg+xml"; public static final String APPLICATION_XHTML_XML = "application/xhtml+xml"; public static final String APPLICATION_XML = "application/xml;charset=UTF-8"; public static final String APPLICATION_JSON = "application/json;charset=UTF-8"; public static final String MULTIPART_FORM_DATA = "multipart/form-data;charset=UTF-8"; public static final String TEXT_HTML = "text/html;charset=UTF-8"; public static final String TEXT_PLAIN = "text/plain;charset=UTF-8"; private MediaType(String type, String charset) { this.type = type; this.charset = charset; } /** * content type. */ private final String type; /** * content type charset. */ private final String charset; /** * Parse the given String contentType into a {@code MediaType} object. * * @param contentType mediaType * @return MediaType */ public static MediaType valueOf(String contentType) { if (StringUtils.isEmpty(contentType)) { throw new IllegalArgumentException("MediaType must not be empty"); } String[] values = contentType.split(";"); String charset = Constants.ENCODE; for (String value : values) { if (value.startsWith("charset=")) { charset = value.substring("charset=".length()); } } return new MediaType(values[0], charset); } /** * Use the given contentType and charset to assemble into a {@code MediaType} object. * * @param contentType contentType * @param charset charset * @return MediaType */ public static MediaType valueOf(String contentType, String charset) { if (StringUtils.isEmpty(contentType)) { throw new IllegalArgumentException("MediaType must not be empty"); } String[] values = contentType.split(";"); return new MediaType(values[0], StringUtils.isEmpty(charset) ? Constants.ENCODE : charset); } public String getType() { return type; } public String getCharset() { return charset; } @Override public String toString() { return type + ";charset=" + charset; } }
Header
/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.nacos.common.http.param; import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.common.constant.HttpHeaderConsts; import com.alibaba.nacos.common.utils.MapUtil; import com.alibaba.nacos.common.utils.StringUtils; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; /** * Http header. * * @author <a href="mailto:liaochuntao@live.com" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >liaochuntao</a> */ public class Header { public static final Header EMPTY = Header.newInstance(); private final Map<String, String> header; private final Map<String, List<String>> originalResponseHeader; private static final String DEFAULT_CHARSET = "UTF-8"; private static final String DEFAULT_ENCODING = "gzip"; private Header() { header = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); originalResponseHeader = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER); addParam(HttpHeaderConsts.CONTENT_TYPE, MediaType.APPLICATION_JSON); addParam(HttpHeaderConsts.ACCEPT_CHARSET, DEFAULT_CHARSET); //addParam(HttpHeaderConsts.ACCEPT_ENCODING, DEFAULT_ENCODING); } public static Header newInstance() { return new Header(); } /** * Add the key and value to the header. * * @param key the key * @param value the value * @return header */ public Header addParam(String key, String value) { if (StringUtils.isNotEmpty(key)) { header.put(key, value); } return this; } public Header setContentType(String contentType) { if (contentType == null) { contentType = MediaType.APPLICATION_JSON; } return addParam(HttpHeaderConsts.CONTENT_TYPE, contentType); } public Header build() { return this; } public String getValue(String key) { return header.get(key); } public Map<String, String> getHeader() { return header; } public Iterator<Map.Entry<String, String>> iterator() { return header.entrySet().iterator(); } /** * Transfer to KV part list. The odd index is key and the even index is value. * * @return KV string list */ public List<String> toList() { List<String> list = new ArrayList<String>(header.size() * 2); Iterator<Map.Entry<String, String>> iterator = iterator(); while (iterator.hasNext()) { Map.Entry<String, String> entry = iterator.next(); list.add(entry.getKey()); list.add(entry.getValue()); } return list; } /** * Add all KV list to header. The odd index is key and the even index is value. * * @param list KV list * @return header */ public Header addAll(List<String> list) { if ((list.size() & 1) != 0) { throw new IllegalArgumentException("list size must be a multiple of 2"); } for (int i = 0; i < list.size(); ) { String key = list.get(i++); if (StringUtils.isNotEmpty(key)) { header.put(key, list.get(i++)); } } return this; } /** * Add all parameters to header. * * @param params parameters */ public void addAll(Map<String, String> params) { if (MapUtil.isNotEmpty(params)) { for (Map.Entry<String, String> entry : params.entrySet()) { addParam(entry.getKey(), entry.getValue()); } } } /** * set original format response header. * * <p>Currently only corresponds to the response header of JDK. * * @param key original response header key * @param values original response header values */ public void addOriginalResponseHeader(String key, List<String> values) { if (StringUtils.isNotEmpty(key)) { this.originalResponseHeader.put(key, values); addParam(key, values.get(0)); } } /** * get original format response header. * * <p>Currently only corresponds to the response header of JDK. * * @return Map original response header */ public Map<String, List<String>> getOriginalResponseHeader() { return this.originalResponseHeader; } public String getCharset() { String acceptCharset = getValue(HttpHeaderConsts.ACCEPT_CHARSET); if (acceptCharset == null) { String contentType = getValue(HttpHeaderConsts.CONTENT_TYPE); acceptCharset = StringUtils.isNotBlank(contentType) ? analysisCharset(contentType) : Constants.ENCODE; } return acceptCharset; } private String analysisCharset(String contentType) { String[] values = contentType.split(";"); String charset = Constants.ENCODE; if (values.length == 0) { return charset; } for (String value : values) { if (value.startsWith("charset=")) { charset = value.substring("charset=".length()); } } return charset; } public void clear() { header.clear(); originalResponseHeader.clear(); } @Override public String toString() { return "Header{" + "headerToMap=" + header + '}'; } }
三、新模块,基于多种Http组件分装、可扩展性更好
具体模块查看
1、NacosRestTemplate[同步RestTemplate]
/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.nacos.common.http.client; import com.alibaba.nacos.common.http.HttpClientConfig; import com.alibaba.nacos.common.http.HttpRestResult; import com.alibaba.nacos.common.http.HttpUtils; import com.alibaba.nacos.common.http.client.handler.ResponseHandler; import com.alibaba.nacos.common.http.client.request.DefaultHttpClientRequest; import com.alibaba.nacos.common.http.client.request.HttpClientRequest; import com.alibaba.nacos.common.http.client.request.JdkHttpClientRequest; import com.alibaba.nacos.common.http.client.response.HttpClientResponse; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.MediaType; import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.model.RequestHttpEntity; import com.alibaba.nacos.common.utils.CollectionUtils; import com.alibaba.nacos.common.utils.HttpMethod; import org.slf4j.Logger; import java.lang.reflect.Type; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Nacos rest template Interface specifying a basic set of RESTful operations. * * @author mai.jh * @see HttpClientRequest * @see HttpClientResponse */ public class NacosRestTemplate extends AbstractNacosRestTemplate { private final HttpClientRequest requestClient; private final List<HttpClientRequestInterceptor> interceptors = new ArrayList<HttpClientRequestInterceptor>(); public NacosRestTemplate(Logger logger, HttpClientRequest requestClient) { super(logger); this.requestClient = requestClient; } /** * http get URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> get(String url, Header header, Query query, Type responseType) throws Exception { return execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType); } /** * http get URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * <p>{@code config} Specify the request config via {@link HttpClientConfig} * * @param url url * @param config http config * @param header headers * @param query http query param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> get(String url, HttpClientConfig config, Header header, Query query, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header, query); return execute(url, HttpMethod.GET, requestHttpEntity, responseType); } /** * get request, may be pulling a lot of data URL request params are expanded using the given query {@link Query}, * More request parameters can be set via body. * * <p>This method can only be used when HttpClientRequest is implemented by {@link DefaultHttpClientRequest}, note: * {@link JdkHttpClientRequest} Implementation does not support this method. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param body get with body * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> getLarge(String url, Header header, Query query, Object body, Type responseType) throws Exception { return execute(url, HttpMethod.GET_LARGE, new RequestHttpEntity(header, query, body), responseType); } /** * http delete URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> delete(String url, Header header, Query query, Type responseType) throws Exception { return execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType); } /** * http delete URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * <p>{@code config} Specify the request config via {@link HttpClientConfig} * * @param url url * @param config http config * @param header http header param * @param query http query param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> delete(String url, HttpClientConfig config, Header header, Query query, Type responseType) throws Exception { return execute(url, HttpMethod.DELETE, new RequestHttpEntity(config, header, query), responseType); } /** * http put Create a new resource by PUTting the given body to http request. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param body http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> put(String url, Header header, Query query, Object body, Type responseType) throws Exception { return execute(url, HttpMethod.PUT, new RequestHttpEntity(header, query, body), responseType); } /** * http put json Create a new resource by PUTting the given body to http request, http header contentType default * 'application/json;charset=UTF-8'. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param body http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> putJson(String url, Header header, Query query, String body, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), query, body); return execute(url, HttpMethod.PUT, requestHttpEntity, responseType); } /** * http put json Create a new resource by PUTting the given body to http request, http header contentType default * 'application/json;charset=UTF-8'. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param body http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> putJson(String url, Header header, String body, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), body); return execute(url, HttpMethod.PUT, requestHttpEntity, responseType); } /** * http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header * contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>URL request params are expanded using the given query {@code Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param bodyValues http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> putForm(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity( header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues); return execute(url, HttpMethod.PUT, requestHttpEntity, responseType); } /** * http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header * contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param bodyValues http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> putForm(String url, Header header, Map<String, String> bodyValues, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity( header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues); return execute(url, HttpMethod.PUT, requestHttpEntity, responseType); } /** * http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header * contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * <p>{@code config} Specify the request config via {@link HttpClientConfig} * * @param url url * @param config http config * @param header http header param * @param bodyValues http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> putForm(String url, HttpClientConfig config, Header header, Map<String, String> bodyValues, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues); return execute(url, HttpMethod.PUT, requestHttpEntity, responseType); } /** * http post Create a new resource by POSTing the given object to the http request. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param body http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> post(String url, Header header, Query query, Object body, Type responseType) throws Exception { return execute(url, HttpMethod.POST, new RequestHttpEntity(header, query, body), responseType); } /** * http post json Create a new resource by POSTing the given object to the http request, http header contentType * default 'application/json;charset=UTF-8'. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param body http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> postJson(String url, Header header, Query query, String body, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), query, body); return execute(url, HttpMethod.POST, requestHttpEntity, responseType); } /** * http post json Create a new resource by POSTing the given object to the http request, http header contentType * default 'application/json;charset=UTF-8'. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param body http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> postJson(String url, Header header, String body, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), body); return execute(url, HttpMethod.POST, requestHttpEntity, responseType); } /** * http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header * contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param query http query param * @param bodyValues http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> postForm(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity( header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues); return execute(url, HttpMethod.POST, requestHttpEntity, responseType); } /** * http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header * contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * @param url url * @param header http header param * @param bodyValues http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> postForm(String url, Header header, Map<String, String> bodyValues, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity( header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues); return execute(url, HttpMethod.POST, requestHttpEntity, responseType); } /** * http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header * contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type. * * <p>{@code config} Specify the request config via {@link HttpClientConfig} * * @param url url * @param config http config * @param header http header param * @param bodyValues http body param * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> postForm(String url, HttpClientConfig config, Header header, Map<String, String> bodyValues, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues); return execute(url, HttpMethod.POST, requestHttpEntity, responseType); } /** * Execute the HTTP method to the given URI template, writing the given request entity to the request, and returns * the response as {@link HttpRestResult}. * * @param url url * @param header http header param * @param query http query param * @param bodyValues http body param * @param httpMethod http method * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> exchangeForm(String url, Header header, Query query, Map<String, String> bodyValues, String httpMethod, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity( header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues); return execute(url, httpMethod, requestHttpEntity, responseType); } /** * Execute the HTTP method to the given URI template, writing the given request entity to the request, and returns * the response as {@link HttpRestResult}. * * @param url url * @param config HttpClientConfig * @param header http header param * @param query http query param * @param body http body param * @param httpMethod http method * @param responseType return type * @return {@link HttpRestResult} * @throws Exception ex */ public <T> HttpRestResult<T> exchange(String url, HttpClientConfig config, Header header, Query query, Object body, String httpMethod, Type responseType) throws Exception { RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header, query, body); return execute(url, httpMethod, requestHttpEntity, responseType); } /** * Set the request interceptors that this accessor should use. * * @param interceptors {@link HttpClientRequestInterceptor} */ public void setInterceptors(List<HttpClientRequestInterceptor> interceptors) { if (this.interceptors != interceptors) { this.interceptors.clear(); this.interceptors.addAll(interceptors); } } /** * Return the request interceptors that this accessor uses. * * <p>The returned {@link List} is active and may get appended to. */ public List<HttpClientRequestInterceptor> getInterceptors() { return interceptors; } @SuppressWarnings("unchecked") private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type responseType) throws Exception { URI uri = HttpUtils.buildUri(url, requestEntity.getQuery()); if (logger.isDebugEnabled()) { logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody()); } ResponseHandler<T> responseHandler = super.selectResponseHandler(responseType); HttpClientResponse response = null; try { response = this.requestClient().execute(uri, httpMethod, requestEntity); return responseHandler.handle(response); } finally { if (response != null) { response.close(); } } } private HttpClientRequest requestClient() { if (CollectionUtils.isNotEmpty(interceptors)) { if (logger.isDebugEnabled()) { logger.debug("Execute via interceptors :{}", interceptors); } return new InterceptingHttpClientRequest(requestClient, interceptors.iterator()); } return requestClient; } /** * close request client. */ public void close() throws Exception { requestClient.close(); } }
2、NacosAsyncRestTemplate【异步RestTemplate】
/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.nacos.common.http.client; import com.alibaba.nacos.common.http.Callback; import com.alibaba.nacos.common.http.HttpUtils; import com.alibaba.nacos.common.http.client.handler.ResponseHandler; import com.alibaba.nacos.common.http.client.request.AsyncHttpClientRequest; import com.alibaba.nacos.common.http.client.response.HttpClientResponse; import com.alibaba.nacos.common.http.param.Header; import com.alibaba.nacos.common.http.param.MediaType; import com.alibaba.nacos.common.http.param.Query; import com.alibaba.nacos.common.model.RequestHttpEntity; import com.alibaba.nacos.common.utils.HttpMethod; import org.slf4j.Logger; import java.lang.reflect.Type; import java.net.URI; import java.util.Map; /** * Nacos async rest template. * * @author mai.jh * @see AsyncHttpClientRequest * @see HttpClientResponse */ public class NacosAsyncRestTemplate extends AbstractNacosRestTemplate { private final AsyncHttpClientRequest clientRequest; public NacosAsyncRestTemplate(Logger logger, AsyncHttpClientRequest clientRequest) { super(logger); this.clientRequest = clientRequest; } /** * async http get URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param responseType return type * @param header http header param * @param query http query param * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void get(String url, Header header, Query query, Type responseType, Callback<T> callback) { execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType, callback); } /** * async get request, may be pulling a lot of data URL request params are expanded using the given query {@link * Query}, More request parameters can be set via body. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param query http query param * @param body get with body * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void getLarge(String url, Header header, Query query, Object body, Type responseType, Callback<T> callback) { execute(url, HttpMethod.GET_LARGE, new RequestHttpEntity(header, query, body), responseType, callback); } /** * async http delete URL request params are expanded using the given query {@link Query}, * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param query http query param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void delete(String url, Header header, Query query, Type responseType, Callback<T> callback) { execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType, callback); } /** * async http delete large request, when the parameter exceeds the URL limit, you can use this method to put the * parameter into the body pass. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param body body * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void delete(String url, Header header, String body, Type responseType, Callback<T> callback) { execute(url, HttpMethod.DELETE_LARGE, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), Query.EMPTY, body), responseType, callback); } /** * async http put Create a new resource by PUTting the given body to http request. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param query http query param * @param body http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void put(String url, Header header, Query query, Object body, Type responseType, Callback<T> callback) { execute(url, HttpMethod.PUT, new RequestHttpEntity(header, query, body), responseType, callback); } /** * async http put Json Create a new resource by PUTting the given body to http request, http header contentType * default 'application/json;charset=UTF-8'. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param query http query param * @param body http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void putJson(String url, Header header, Query query, String body, Type responseType, Callback<T> callback) { execute(url, HttpMethod.PUT, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), query, body), responseType, callback); } /** * async http put Json Create a new resource by PUTting the given body to http request, http header contentType * default 'application/json;charset=UTF-8'. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param body http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void putJson(String url, Header header, String body, Type responseType, Callback<T> callback) { execute(url, HttpMethod.PUT, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), body), responseType, callback); } /** * async http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http * header contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param query http query param * @param bodyValues http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void putForm(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType, Callback<T> callback) { execute(url, HttpMethod.PUT, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues), responseType, callback); } /** * async http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http * header contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param bodyValues http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void putForm(String url, Header header, Map<String, String> bodyValues, Type responseType, Callback<T> callback) { execute(url, HttpMethod.PUT, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues), responseType, callback); } /** * async http post Create a new resource by POSTing the given object to the http request. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param query http query param * @param body http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void post(String url, Header header, Query query, Object body, Type responseType, Callback<T> callback) { execute(url, HttpMethod.POST, new RequestHttpEntity(header, query, body), responseType, callback); } /** * async http post Json Create a new resource by POSTing the given object to the http request, http header * contentType default 'application/json;charset=UTF-8'. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param query http query param * @param body http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void postJson(String url, Header header, Query query, String body, Type responseType, Callback<T> callback) { execute(url, HttpMethod.POST, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), query, body), responseType, callback); } /** * async http post Json Create a new resource by POSTing the given object to the http request, http header * contentType default 'application/json;charset=UTF-8'. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param body http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void postJson(String url, Header header, String body, Type responseType, Callback<T> callback) { execute(url, HttpMethod.POST, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_JSON), body), responseType, callback); } /** * async http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http * header contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>URL request params are expanded using the given query {@link Query}. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param query http query param * @param bodyValues http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void postForm(String url, Header header, Query query, Map<String, String> bodyValues, Type responseType, Callback<T> callback) { execute(url, HttpMethod.POST, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), query, bodyValues), responseType, callback); } /** * async http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http * header contentType default 'application/x-www-form-urlencoded;charset=utf-8'. * * <p>{@code responseType} can be an RestResult or RestResult data {@code T} type. * * <p>{@code callback} Result callback execution, * if you need response headers, you can convert the received RestResult to HttpRestResult. * * @param url url * @param header http header param * @param bodyValues http body param * @param responseType return type * @param callback callback {@link Callback#onReceive(com.alibaba.nacos.common.model.RestResult)} */ public <T> void postForm(String url, Header header, Map<String, String> bodyValues, Type responseType, Callback<T> callback) { execute(url, HttpMethod.POST, new RequestHttpEntity(header.setContentType(MediaType.APPLICATION_FORM_URLENCODED), bodyValues), responseType, callback); } @SuppressWarnings("unchecked") private <T> void execute(String url, String httpMethod, RequestHttpEntity requestEntity, Type type, Callback<T> callback) { try { URI uri = HttpUtils.buildUri(url, requestEntity.getQuery()); if (logger.isDebugEnabled()) { logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody()); } ResponseHandler<T> responseHandler = super.selectResponseHandler(type); clientRequest.execute(uri, httpMethod, requestEntity, responseHandler, callback); } catch (Exception e) { // When an exception occurs, use Callback to pass it instead of throw it directly. callback.onError(e); } } /** * close request client. */ public void close() throws Exception { clientRequest.close(); } }
3、HttpClientFactory
package com.alibaba.nacos.common.http; import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate; import com.alibaba.nacos.common.http.client.NacosRestTemplate; /** * http Client Factory. * * @author mai.jh */ public interface HttpClientFactory { /** * create new nacost rest. * * @return NacosRestTemplate */ NacosRestTemplate createNacosRestTemplate(); /** * create new nacos async rest. * * @return NacosAsyncRestTemplate */ NacosAsyncRestTemplate createNacosAsyncRestTemplate(); }
4、AbstractHttpClientFactory
/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.nacos.common.http; import org.slf4j.Logger; /** * default http client factory. * * @author mai.jh */ public class DefaultHttpClientFactory extends AbstractHttpClientFactory { private static final int TIMEOUT = Integer.getInteger("nacos.http.timeout", 5000); private final Logger logger; public DefaultHttpClientFactory(Logger logger) { this.logger = logger; } @Override protected HttpClientConfig buildHttpClientConfig() { return HttpClientConfig.builder().setConTimeOutMillis(TIMEOUT).setReadTimeOutMillis(TIMEOUT >> 1).build(); } @Override protected Logger assignLogger() { return logger; } }
HttpClientConfig【连接池参数】
/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.nacos.common.http; import com.alibaba.nacos.common.utils.ThreadUtils; import java.util.concurrent.TimeUnit; /** * http client config build. * * @author mai.jh */ public class HttpClientConfig { /** * connect time out. */ private final int conTimeOutMillis; /** * read time out. */ private final int readTimeOutMillis; /** * connTimeToLive. */ private final long connTimeToLive; /** * connTimeToLiveTimeUnit. */ private final TimeUnit connTimeToLiveTimeUnit; /** * connectionRequestTimeout. */ private final int connectionRequestTimeout; /** * max redirect. */ private final int maxRedirects; /** * max connect total. */ private final int maxConnTotal; /** * Assigns maximum connection per route value. */ private final int maxConnPerRoute; /** * is HTTP compression enabled. */ private final boolean contentCompressionEnabled; /** * io thread count. */ private final int ioThreadCount; /** * user agent. */ private final String userAgent; public HttpClientConfig(int conTimeOutMillis, int readTimeOutMillis, long connTimeToLive, TimeUnit timeUnit, int connectionRequestTimeout, int maxRedirects, int maxConnTotal, int maxConnPerRoute, boolean contentCompressionEnabled, int ioThreadCount, String userAgent) { this.conTimeOutMillis = conTimeOutMillis; this.readTimeOutMillis = readTimeOutMillis; this.connTimeToLive = connTimeToLive; this.connTimeToLiveTimeUnit = timeUnit; this.connectionRequestTimeout = connectionRequestTimeout; this.maxRedirects = maxRedirects; this.maxConnTotal = maxConnTotal; this.maxConnPerRoute = maxConnPerRoute; this.contentCompressionEnabled = contentCompressionEnabled; this.ioThreadCount = ioThreadCount; this.userAgent = userAgent; } public int getConTimeOutMillis() { return conTimeOutMillis; } public int getReadTimeOutMillis() { return readTimeOutMillis; } public long getConnTimeToLive() { return connTimeToLive; } public TimeUnit getConnTimeToLiveTimeUnit() { return connTimeToLiveTimeUnit; } public int getConnectionRequestTimeout() { return connectionRequestTimeout; } public int getMaxRedirects() { return maxRedirects; } public int getMaxConnTotal() { return maxConnTotal; } public int getMaxConnPerRoute() { return maxConnPerRoute; } public boolean getContentCompressionEnabled() { return contentCompressionEnabled; } public int getIoThreadCount() { return ioThreadCount; } public String getUserAgent() { return userAgent; } public static HttpClientConfigBuilder builder() { return new HttpClientConfigBuilder(); } public static final class HttpClientConfigBuilder { private int conTimeOutMillis = -1; private int readTimeOutMillis = -1; private long connTimeToLive = -1; private TimeUnit connTimeToLiveTimeUnit = TimeUnit.MILLISECONDS; private int connectionRequestTimeout = 5000; private int maxRedirects = 50; private int maxConnTotal = 0; private int maxConnPerRoute = 0; private boolean contentCompressionEnabled = true; private int ioThreadCount = ThreadUtils.getSuitableThreadCount(1); private String userAgent; public HttpClientConfigBuilder setConTimeOutMillis(int conTimeOutMillis) { this.conTimeOutMillis = conTimeOutMillis; return this; } public HttpClientConfigBuilder setReadTimeOutMillis(int readTimeOutMillis) { this.readTimeOutMillis = readTimeOutMillis; return this; } public HttpClientConfigBuilder setConnectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit) { this.connTimeToLive = connTimeToLive; this.connTimeToLiveTimeUnit = connTimeToLiveTimeUnit; return this; } public HttpClientConfigBuilder setConnectionRequestTimeout(int connectionRequestTimeout) { this.connectionRequestTimeout = connectionRequestTimeout; return this; } public HttpClientConfigBuilder setMaxRedirects(int maxRedirects) { this.maxRedirects = maxRedirects; return this; } public HttpClientConfigBuilder setMaxConnTotal(int maxConnTotal) { this.maxConnTotal = maxConnTotal; return this; } public HttpClientConfigBuilder setMaxConnPerRoute(int maxConnPerRoute) { this.maxConnPerRoute = maxConnPerRoute; return this; } public HttpClientConfigBuilder setContentCompressionEnabled(boolean contentCompressionEnabled) { this.contentCompressionEnabled = contentCompressionEnabled; return this; } public HttpClientConfigBuilder setIoThreadCount(int ioThreadCount) { this.ioThreadCount = ioThreadCount; return this; } public HttpClientConfigBuilder setUserAgent(String userAgent) { this.userAgent = userAgent; return this; } /** * build http client config. * * @return HttpClientConfig */ public HttpClientConfig build() { return new HttpClientConfig(conTimeOutMillis, readTimeOutMillis, connTimeToLive, connTimeToLiveTimeUnit, connectionRequestTimeout, maxRedirects, maxConnTotal, maxConnPerRoute, contentCompressionEnabled, ioThreadCount, userAgent); } } }
开启SSL
HttpClient整体封装比较完善,对项目中使用也比较有参考.
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
最新评论