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

HttpClient的DnsResolver自定義DNS解析另一種選擇深入研究

 更新時間:2023年10月17日 09:35:11   作者:codecraft  
這篇文章主要為大家介紹了HttpClient的DnsResolver自定義DNS解析另一種選擇深入研究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下HttpClient的DnsResolver

DnsResolver

org/apache/http/conn/DnsResolver.java

/**
 * Users may implement this interface to override the normal DNS lookup offered
 * by the OS.
 *
 * @since 4.2
 */
public interface DnsResolver {

    /**
     * Returns the IP address for the specified host name, or null if the given
     * host is not recognized or the associated IP address cannot be used to
     * build an InetAddress instance.
     *
     * @see InetAddress
     *
     * @param host
     *            The host name to be resolved by this resolver.
     * @return The IP address associated to the given host name, or null if the
     *         host name is not known by the implementation class.
     */
    InetAddress[] resolve(String host) throws UnknownHostException;

}
DnsResolver定義了resolve方法,可用于替換OS提供的DNS lookup

InMemoryDnsResolver

org/apache/http/impl/conn/InMemoryDnsResolver.java

/**
 * In-memory {@link DnsResolver} implementation.
 *
 * @since 4.2
 */
public class InMemoryDnsResolver implements DnsResolver {
    /** Logger associated to this class. */
    private final Log log = LogFactory.getLog(InMemoryDnsResolver.class);
    /**
     * In-memory collection that will hold the associations between a host name
     * and an array of InetAddress instances.
     */
    private final Map<String, InetAddress[]> dnsMap;
    /**
     * Builds a DNS resolver that will resolve the host names against a
     * collection held in-memory.
     */
    public InMemoryDnsResolver() {
        dnsMap = new ConcurrentHashMap<String, InetAddress[]>();
    }
    /**
     * Associates the given array of IP addresses to the given host in this DNS overrider.
     * The IP addresses are assumed to be already resolved.
     *
     * @param host
     *            The host name to be associated with the given IP.
     * @param ips
     *            array of IP addresses to be resolved by this DNS overrider to the given
     *            host name.
     */
    public void add(final String host, final InetAddress... ips) {
        Args.notNull(host, "Host name");
        Args.notNull(ips, "Array of IP addresses");
        dnsMap.put(host, ips);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public InetAddress[] resolve(final String host) throws UnknownHostException {
        final InetAddress[] resolvedAddresses = dnsMap.get(host);
        if (log.isInfoEnabled()) {
            log.info("Resolving " + host + " to " + Arrays.deepToString(resolvedAddresses));
        }
        if(resolvedAddresses == null){
            throw new UnknownHostException(host + " cannot be resolved");
        }
        return resolvedAddresses;
    }
}
InMemoryDnsResolver實現(xiàn)了DnsResolver接口,它用一個ConcurrentHashMap來存放dns信息,提供add方法往map添加host及對應(yīng)的ip地址,然后其resolve就是從這個map來讀取對應(yīng)的ip地址信息

SystemDefaultDnsResolver

org/apache/http/impl/conn/SystemDefaultDnsResolver.java

/**
 * DNS resolver that uses the default OS implementation for resolving host names.
 *
 * @since 4.2
 */
public class SystemDefaultDnsResolver implements DnsResolver {

    public static final SystemDefaultDnsResolver INSTANCE = new SystemDefaultDnsResolver();

    @Override
    public InetAddress[] resolve(final String host) throws UnknownHostException {
        return InetAddress.getAllByName(host);
    }

}
SystemDefaultDnsResolver實現(xiàn)了DnsResolver,它用的就是jdk提供的InetAddress.getAllByName,默認(rèn)是走的OS的DNS,可以通過sun.net.spi.nameservice.provider.<n>去自定義

DefaultHttpClientConnectionOperator

org/apache/http/impl/conn/DefaultHttpClientConnectionOperator.java

@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
public class DefaultHttpClientConnectionOperator implements HttpClientConnectionOperator {
    static final String SOCKET_FACTORY_REGISTRY = "http.socket-factory-registry";
    private final Log log = LogFactory.getLog(getClass());
    private final Lookup<ConnectionSocketFactory> socketFactoryRegistry;
    private final SchemePortResolver schemePortResolver;
    private final DnsResolver dnsResolver;
    public DefaultHttpClientConnectionOperator(
            final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
            final SchemePortResolver schemePortResolver,
            final DnsResolver dnsResolver) {
        super();
        Args.notNull(socketFactoryRegistry, "Socket factory registry");
        this.socketFactoryRegistry = socketFactoryRegistry;
        this.schemePortResolver = schemePortResolver != null ? schemePortResolver :
            DefaultSchemePortResolver.INSTANCE;
        this.dnsResolver = dnsResolver != null ? dnsResolver :
            SystemDefaultDnsResolver.INSTANCE;
    }
    @Override
    public void connect(
            final ManagedHttpClientConnection conn,
            final HttpHost host,
            final InetSocketAddress localAddress,
            final int connectTimeout,
            final SocketConfig socketConfig,
            final HttpContext context) throws IOException {
        final Lookup<ConnectionSocketFactory> registry = getSocketFactoryRegistry(context);
        final ConnectionSocketFactory sf = registry.lookup(host.getSchemeName());
        if (sf == null) {
            throw new UnsupportedSchemeException(host.getSchemeName() +
                    " protocol is not supported");
        }
        final InetAddress[] addresses = host.getAddress() != null ?
                new InetAddress[] { host.getAddress() } : this.dnsResolver.resolve(host.getHostName());
        final int port = this.schemePortResolver.resolve(host);
        for (int i = 0; i < addresses.length; i++) {
            final InetAddress address = addresses[i];
            final boolean last = i == addresses.length - 1;
            Socket sock = sf.createSocket(context);
            sock.setSoTimeout(socketConfig.getSoTimeout());
            sock.setReuseAddress(socketConfig.isSoReuseAddress());
            sock.setTcpNoDelay(socketConfig.isTcpNoDelay());
            sock.setKeepAlive(socketConfig.isSoKeepAlive());
            if (socketConfig.getRcvBufSize() > 0) {
                sock.setReceiveBufferSize(socketConfig.getRcvBufSize());
            }
            if (socketConfig.getSndBufSize() > 0) {
                sock.setSendBufferSize(socketConfig.getSndBufSize());
            }
            final int linger = socketConfig.getSoLinger();
            if (linger >= 0) {
                sock.setSoLinger(true, linger);
            }
            conn.bind(sock);
            final InetSocketAddress remoteAddress = new InetSocketAddress(address, port);
            if (this.log.isDebugEnabled()) {
                this.log.debug("Connecting to " + remoteAddress);
            }
            try {
                sock = sf.connectSocket(
                        connectTimeout, sock, host, remoteAddress, localAddress, context);
                conn.bind(sock);
                if (this.log.isDebugEnabled()) {
                    this.log.debug("Connection established " + conn);
                }
                return;
            } catch (final SocketTimeoutException ex) {
                if (last) {
                    throw new ConnectTimeoutException(ex, host, addresses);
                }
            } catch (final ConnectException ex) {
                if (last) {
                    final String msg = ex.getMessage();
                    throw "Connection timed out".equals(msg)
                                    ? new ConnectTimeoutException(ex, host, addresses)
                                    : new HttpHostConnectException(ex, host, addresses);
                }
            } catch (final NoRouteToHostException ex) {
                if (last) {
                    throw ex;
                }
            }
            if (this.log.isDebugEnabled()) {
                this.log.debug("Connect to " + remoteAddress + " timed out. " +
                        "Connection will be retried using another IP address");
            }
        }
    }
    //......
}
DefaultHttpClientConnectionOperator的connect方法會通過dnsResolver.resolve解析host

小結(jié)

HttpClient提供了DnsResolver接口,可以用于自定義DNS解析,是除了使用sun.net.spi.nameservice.provider.<n>去自定義JDK全局dns解析外的另外一種方案。

以上就是HttpClient的DnsResolver自定義DNS解析另一種選擇深入研究的詳細(xì)內(nèi)容,更多關(guān)于HttpClient DnsResolver解析DNS的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot的啟動速度優(yōu)化

    SpringBoot的啟動速度優(yōu)化

    隨著我們項目的不斷迭代 Bean 的數(shù)量會大大增加,如果都在啟動時進(jìn)行初始化會非常耗時,本文主要介紹了SpringBoot的啟動速度優(yōu)化,感興趣的可以了解一下
    2023-09-09
  • IDEA中Git的配置及其使用過程

    IDEA中Git的配置及其使用過程

    本文介紹了如何在IntelliJ IDEA中配置和使用Git,包括配置Git路徑、克隆項目、更新代碼、提交和推送代碼、合并分支、管理分支以及將本地項目推送到GitHub
    2025-12-12
  • 通過JDK源碼角度分析Long類詳解

    通過JDK源碼角度分析Long類詳解

    這篇文章主要給大家介紹了關(guān)于通過JDK源碼角度分析Long類的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用long類具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Spring Cloud Alibaba Nacos Config加載配置詳解流程

    Spring Cloud Alibaba Nacos Config加載配置詳解流

    這篇文章主要介紹了Spring Cloud Alibaba Nacos Config配置中心實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-07-07
  • IDEA接入Deepseek的圖文教程

    IDEA接入Deepseek的圖文教程

    在本篇文章中,我們將詳細(xì)介紹如何在 JetBrains IDEA 中使用 Continue 插件接入 DeepSeek,讓你的 AI 編程助手更智能,提高開發(fā)效率,感興趣的小伙伴跟著小編一起來看看吧
    2025-03-03
  • springboot中如何替換class文件

    springboot中如何替換class文件

    這篇文章主要介紹了springboot中如何替換class文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java Web實現(xiàn)文件下載和亂碼處理方法

    Java Web實現(xiàn)文件下載和亂碼處理方法

    文件上傳和下載是web開發(fā)中常遇到的問題。今天小編給大家分享下Java Web實現(xiàn)文件下載和亂碼處理方法的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • Java一鍵獲取(CPU、內(nèi)存、硬盤、操作系統(tǒng))系統(tǒng)信息

    Java一鍵獲取(CPU、內(nèi)存、硬盤、操作系統(tǒng))系統(tǒng)信息

    這篇文章主要為大家詳細(xì)介紹了如何使用Java一鍵獲取CPU、內(nèi)存、硬盤、操作系統(tǒng)等系統(tǒng)信息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2026-03-03
  • SpringBoot利用AOP實現(xiàn)一個日志管理詳解

    SpringBoot利用AOP實現(xiàn)一個日志管理詳解

    目前有這么個問題,有兩個系統(tǒng)CSP和OMS,這倆系統(tǒng)共用的是同一套日志操作:Log;目前想?yún)^(qū)分下這倆系統(tǒng)的日志操作,那沒辦法了,只能重寫一份Log的日志操作。本文就將利用AOP實現(xiàn)一個日志管理,需要的可以參考一下
    2022-09-09
  • Spring Security6中@PostAuthorize注解的具體使用

    Spring Security6中@PostAuthorize注解的具體使用

    @PostAuthorize是Spring Security提供的方法級安全注解,用于在方法執(zhí)行后根據(jù)返回結(jié)果進(jìn)行權(quán)限校驗,本文就來詳細(xì)的介紹一下 @PostAuthorize注解的使用,感興趣的可以了解一下
    2025-10-10

最新評論

华宁县| 塔河县| 布尔津县| 贡觉县| 巴楚县| 文化| 扶沟县| 塔城市| 马边| 正蓝旗| 桐柏县| 华坪县| 蓝山县| 金阳县| 濮阳县| 科技| 江孜县| 贵阳市| 焦作市| 贵港市| 玉溪市| 沂源县| 遂平县| 滕州市| 关岭| 凤城市| 南岸区| 湘阴县| 东平县| 吴江市| 怀柔区| 浦县| 右玉县| 泌阳县| 澄城县| 沙洋县| 宜黄县| 河西区| 含山县| 和硕县| 壶关县|