最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Nacos封裝通用HttpClient詳解

 更新時(shí)間:2024年01月30日 09:33:09   作者:大道之簡(jiǎn)  
這篇文章主要介紹了Nacos封裝通用HttpClient用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、Nacos下Http請(qǐng)求設(shè)計(jì)眾多處理模塊處理

包括更新、Prometheus監(jiān)控等眾多功能

Nacos對(duì)這塊做了統(tǒng)一封裝,擴(kuò)展性也很好,有新舊版本和同步和異步版本。

二、具體封裝模塊

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服務(wù)內(nèi)部調(diào)用,后續(xù)版本要下線,比較重量級(jí),不夠靈活]

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響應(yīng).

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組件分裝、可擴(kuò)展性更好

具體模塊查看

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【連接池參數(shù)】

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

開(kāi)啟SSL 

HttpClient整體封裝比較完善,對(duì)項(xiàng)目中使用也比較有參考. 

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot基于Disruptor實(shí)現(xiàn)高效的消息隊(duì)列?

    SpringBoot基于Disruptor實(shí)現(xiàn)高效的消息隊(duì)列?

    Disruptor是一個(gè)開(kāi)源的Java框架,它被設(shè)計(jì)用于在生產(chǎn)者-消費(fèi)者問(wèn)題上獲得盡量高的吞吐量和盡量低的延遲,本文主要介紹了SpringBoot基于Disruptor實(shí)現(xiàn)高效的消息隊(duì)列?,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • 解決IDEA使用maven創(chuàng)建Web項(xiàng)目,出現(xiàn)500錯(cuò)誤的問(wèn)題

    解決IDEA使用maven創(chuàng)建Web項(xiàng)目,出現(xiàn)500錯(cuò)誤的問(wèn)題

    本文主要介紹了在使用Maven創(chuàng)建項(xiàng)目并導(dǎo)入依賴寫(xiě)完測(cè)試代碼后運(yùn)行出現(xiàn)500錯(cuò)誤的解決步驟,這種問(wèn)題的根本原因是Tomcat啟動(dòng)后缺少某些支持的jar包,導(dǎo)致運(yùn)行出錯(cuò),解決方法是在項(xiàng)目結(jié)構(gòu)中找到Artifacts,點(diǎn)擊要編輯的項(xiàng)目
    2024-10-10
  • Jackson反序列化@JsonFormat 不生效的解決方案

    Jackson反序列化@JsonFormat 不生效的解決方案

    這篇文章主要介紹了Jackson反序列化@JsonFormat 不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 利用Java巧妙解決Excel公式迭代計(jì)算

    利用Java巧妙解決Excel公式迭代計(jì)算

    迭代計(jì)算其實(shí)是在?Excel?中,一種公式的循環(huán)引用,那么如何利用Java語(yǔ)言巧妙解決Excel公式迭代計(jì)算的問(wèn)題呢,下面小編就來(lái)和大家詳細(xì)講講吧
    2023-10-10
  • Java設(shè)計(jì)模式之備忘錄模式實(shí)現(xiàn)對(duì)象狀態(tài)的保存和恢復(fù)

    Java設(shè)計(jì)模式之備忘錄模式實(shí)現(xiàn)對(duì)象狀態(tài)的保存和恢復(fù)

    本文介紹Java設(shè)計(jì)模式之備忘錄模式,該模式可以實(shí)現(xiàn)對(duì)象狀態(tài)的保存和恢復(fù)。通過(guò)詳細(xì)講解備忘錄模式的原理、實(shí)現(xiàn)方法和應(yīng)用場(chǎng)景,幫助讀者深入理解該設(shè)計(jì)模式,并提供示例代碼和技巧,便于讀者實(shí)際應(yīng)用
    2023-04-04
  • java后端進(jìn)行跨域的幾種方式小結(jié)

    java后端進(jìn)行跨域的幾種方式小結(jié)

    本文主要介紹了java后端進(jìn)行跨域的幾種方式小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 使用SpringMVC 重寫(xiě)、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù)

    使用SpringMVC 重寫(xiě)、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù)

    這篇文章主要介紹了使用SpringMVC 重寫(xiě)、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中增強(qiáng)for循環(huán)代碼示例

    Java中增強(qiáng)for循環(huán)代碼示例

    這篇文章主要給大家介紹了Java中增強(qiáng)for循環(huán)的相關(guān)資料,for/in循環(huán)就是JDK5.0中所謂的增強(qiáng)For循環(huán),它能對(duì)數(shù)組和集合進(jìn)行遍歷,使用它會(huì)使用你的代碼短小而精煉的多,需要的朋友可以參考下
    2023-10-10
  • JWT令牌的工作原理詳解

    JWT令牌的工作原理詳解

    這篇文章主要介紹了JWT令牌的工作原理詳解,在認(rèn)證的時(shí)候,當(dāng)用戶用他們的的憑證成功登錄以后,一個(gè)JSON?Web?Token將會(huì)被返回,此后,用戶名和密碼就不再是用戶的憑證,而token是用戶用來(lái)訪問(wèn)資源的新憑證了,需要的朋友可以參考下
    2023-08-08
  • RocketMQ實(shí)現(xiàn)消息分發(fā)的步驟

    RocketMQ實(shí)現(xiàn)消息分發(fā)的步驟

    RocketMQ 實(shí)現(xiàn)消息分發(fā)的核心機(jī)制是通過(guò) Topic、Queue 和 Consumer Group 的配合實(shí)現(xiàn)的,下面給大家介紹RocketMQ實(shí)現(xiàn)消息分發(fā)的步驟,感興趣的朋友一起看看吧
    2024-03-03

最新評(píng)論

黄平县| 桐城市| 东山县| 西丰县| 上犹县| 金川县| 阿克苏市| 博爱县| 沙洋县| 将乐县| 濉溪县| 岗巴县| 施甸县| 巴南区| 河南省| 周口市| 潮州市| 齐齐哈尔市| 辽宁省| 凉城县| 高陵县| 烟台市| 静乐县| 屯昌县| 麻城市| 固安县| 黔西县| 巢湖市| 台江县| 苍山县| 绥江县| 偏关县| 扶沟县| 宣武区| 太康县| 临潭县| 建宁县| 田东县| 逊克县| 苍溪县| 尼勒克县|